~ubuntu-branches/ubuntu/jaunty/bibletime/jaunty

« back to all changes in this revision

Viewing changes to bibletime/frontend/cswordsetupdialog.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ralph Janke
  • Date: 2008-05-10 15:18:16 UTC
  • mfrom: (1.1.6 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080510151816-bqp8y1to705zd0fm
Tags: 1.6.5.1-1
* New upstream version (Closes: #441161, #271502)
* fixes for new autotools and gcc 4.3 (Closes: #407291)
* added poxml to Build-Depends
* No DFSG necessary anymore since biblestudy howto has 
  now Commons Licence 
* Added libclucene-dev to dev-depends (Closes: #436677)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********
 
2
*
 
3
* This file is part of BibleTime's source code, http://www.bibletime.info/.
 
4
*
 
5
* Copyright 1999-2006 by the BibleTime developers.
 
6
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
 
7
*
 
8
**********/
 
9
 
 
10
 
 
11
 
 
12
#include "cswordsetupdialog.h"
 
13
#include "cswordsetupmodulelistview.h"
 
14
#include "cswordsetupinstallsourcesdialog.h"
 
15
 
 
16
#include "backend/cswordbackend.h"
 
17
#include "backend/cswordmoduleinfo.h"
 
18
// #include "btinstallmgr.h"
 
19
 
 
20
#include "cmanageindiceswidget.h"
 
21
 
 
22
#include "util/cresmgr.h"
 
23
#include "util/ctoolclass.h"
 
24
#include "util/scoped_resource.h"
 
25
 
 
26
//QT includes
 
27
#include <qdir.h>
 
28
#include <qlayout.h>
 
29
#include <qlabel.h>
 
30
#include <qcombobox.h>
 
31
#include <qwidgetstack.h>
 
32
#include <qfileinfo.h>
 
33
#include <qpushbutton.h>
 
34
#include <qlineedit.h>
 
35
#include <qdict.h>
 
36
 
 
37
//KDE includes
 
38
#include <kapplication.h>
 
39
#include <kconfig.h>
 
40
#include <kdirselectdialog.h>
 
41
#include <keditlistbox.h>
 
42
#include <klocale.h>
 
43
#include <kstandarddirs.h>
 
44
#include <kiconloader.h>
 
45
#include <kmessagebox.h>
 
46
#include <kprogress.h>
 
47
#include <kurl.h>
 
48
 
 
49
//Sword includes
 
50
#include <installmgr.h>
 
51
#include <swmodule.h>
 
52
#include <swversion.h>
 
53
 
 
54
using namespace sword;
 
55
 
 
56
namespace BookshelfManager {
 
57
 
 
58
        CSwordSetupDialog::CSwordSetupDialog(QWidget *parent, const char *name )
 
59
: KDialogBase(IconList, i18n("Bookshelf Manager"), Ok, Ok, parent, name, true, true, QString::null, QString::null, QString::null),
 
60
        m_removeModuleListView(0),
 
61
        m_installModuleListPage(0),
 
62
        m_installModuleListView(0),
 
63
        m_progressDialog(0),
 
64
        m_refreshedRemoteSources(false) {
 
65
                setIconListAllVisible(true);
 
66
                m_swordSetupChanged = false;
 
67
 
 
68
                initSwordConfig();
 
69
                initInstall();
 
70
                initRemove();
 
71
                initManageIndices();
 
72
        }
 
73
 
 
74
        void CSwordSetupDialog::initSwordConfig() {
 
75
                QFrame* page = m_swordConfigPage = addPage(i18n("Bookshelf path(s)"), QString::null, SmallIcon("bt_swordconfig",32));
 
76
                page->setMinimumSize(500,400);
 
77
 
 
78
                QGridLayout* layout = new QGridLayout(page, 6, 4);
 
79
                layout->setMargin(5);
 
80
 
 
81
                layout->setSpacing(10);
 
82
                layout->setColStretch(0,1);
 
83
                layout->setRowStretch(5,1);
 
84
 
 
85
                QLabel* mainLabel = CToolClass::explanationLabel(page,
 
86
                                                        i18n("Configure bookshelf path(s)"),
 
87
                                                        i18n("You can store your bookshelfs in one or more directories, which you can specify here.")
 
88
                                                                                                                );
 
89
                layout->addMultiCellWidget(mainLabel, 0, 0, 0, 3);
 
90
 
 
91
 
 
92
                QString swordConfPath = BTInstallMgr::Tool::LocalConfig::swordConfigFilename();
 
93
                QLabel* confPathLabel = new QLabel(i18n("Your bookshelf configuration file is <b>%1</b>").arg(swordConfPath), page);
 
94
                layout->addMultiCellWidget(confPathLabel, 1,1,0,3);
 
95
 
 
96
                m_swordPathListBox = new QListView(page);
 
97
                //   m_swordPathListBox->setFullWidth(true);
 
98
                m_swordPathListBox->addColumn(i18n("Path to bookshelf"));
 
99
                connect(m_swordPathListBox, SIGNAL(selectionChanged()), this, SLOT(slot_swordPathSelected()));
 
100
                layout->addMultiCellWidget(m_swordPathListBox, 2,5,0,1);
 
101
 
 
102
                m_swordEditPathButton = new QPushButton(i18n("Edit Entry"), page);
 
103
                m_swordEditPathButton->setIconSet(SmallIcon("edit", 16));
 
104
                connect(m_swordEditPathButton, SIGNAL(clicked()), this, SLOT(slot_swordEditClicked()));
 
105
                layout->addWidget(m_swordEditPathButton, 2, 3);
 
106
 
 
107
                m_swordAddPathButton = new QPushButton(i18n("Add Entry"), page);
 
108
                m_swordAddPathButton->setIconSet(SmallIcon("edit_add", 16));
 
109
                connect(m_swordAddPathButton, SIGNAL(clicked()), this, SLOT(slot_swordAddClicked()));
 
110
                layout->addWidget(m_swordAddPathButton, 3,3);
 
111
 
 
112
                m_swordRemovePathButton = new QPushButton(i18n("Remove Entry"), page);
 
113
                m_swordRemovePathButton->setIconSet(SmallIcon("editdelete", 16));
 
114
                connect(m_swordRemovePathButton, SIGNAL(clicked()), this, SLOT(slot_swordRemoveClicked()));
 
115
                layout->addWidget(m_swordRemovePathButton, 4,3);
 
116
 
 
117
                setupSwordPathListBox();
 
118
        }
 
119
 
 
120
        void CSwordSetupDialog::initInstall() {
 
121
                m_installPage = addPage(i18n("Install/Update works"), QString::null, SmallIcon("bt_bible",32));
 
122
 
 
123
                QVBoxLayout* vboxlayout = new QVBoxLayout(m_installPage);
 
124
                QHBoxLayout* hboxlayout = new QHBoxLayout();
 
125
                hboxlayout->setAutoAdd( true );
 
126
 
 
127
                vboxlayout->addLayout(hboxlayout);
 
128
 
 
129
                m_installWidgetStack = new QWidgetStack(m_installPage);
 
130
                hboxlayout->addWidget(m_installWidgetStack);
 
131
 
 
132
                m_installSourcePage = new QWidget(0);
 
133
                m_installWidgetStack->addWidget(m_installSourcePage);
 
134
 
 
135
                //  m_installSourcePage->setMinimumSize(500,400);
 
136
 
 
137
                QGridLayout* layout = new QGridLayout(m_installSourcePage, 7, 3);
 
138
                layout->setMargin(5);
 
139
                layout->setSpacing(10);
 
140
                layout->setRowStretch(6,5);
 
141
                layout->setColStretch(0,5);
 
142
 
 
143
                QLabel* installLabel = CToolClass::explanationLabel(m_installSourcePage,
 
144
                                                           i18n("Install/update works - Step 1"),
 
145
                                                           i18n("Please choose a (local or remote) library and a bookshelf path to install the work(s) to. \
 
146
After that step click on the connect button.<br/>\
 
147
<b>WARNING: If you live in a persecuted country and do not wish to risk detection you should NOT use \
 
148
the module remote installation feature!</b>")
 
149
                                                                                                                   );
 
150
                layout->addMultiCellWidget(installLabel, 0,0,0,2);
 
151
 
 
152
                QLabel* sourceHeadingLabel = new QLabel(QString("<b>%1</b>").arg(i18n("Select library")), m_installSourcePage);
 
153
                layout->addMultiCellWidget(sourceHeadingLabel, 1,1,0,1);
 
154
 
 
155
                m_sourceCombo = new QComboBox(m_installSourcePage);
 
156
                layout->addWidget(m_sourceCombo, 2, 0);
 
157
 
 
158
                QPushButton* deleteSourceButton = new QPushButton(i18n("Delete library"), m_installSourcePage);
 
159
                deleteSourceButton->setIconSet(SmallIcon("remove", 16));
 
160
                connect(deleteSourceButton, SIGNAL(clicked()), SLOT(slot_installDeleteSource()));
 
161
                layout->addWidget(deleteSourceButton, 2, 1, Qt::AlignLeft);
 
162
 
 
163
                QPushButton* addSourceButton = new QPushButton(i18n("Add library"), m_installSourcePage);
 
164
                addSourceButton->setIconSet(SmallIcon("folder_new", 16));
 
165
                connect(addSourceButton, SIGNAL(clicked()), SLOT(slot_installAddSource()));
 
166
                layout->addWidget(addSourceButton, 2, 2, Qt::AlignLeft);
 
167
 
 
168
                m_sourceLabel = new QLabel(m_installSourcePage);
 
169
                layout->addMultiCellWidget(m_sourceLabel, 3,3,0,1);
 
170
 
 
171
                QLabel* targetHeadingLabel = new QLabel(QString("<b>%1</b>").arg(i18n("Select bookshelf path")), m_installSourcePage);
 
172
                layout->addMultiCellWidget(targetHeadingLabel, 4,4,0,1);
 
173
 
 
174
                m_targetCombo = new QComboBox(m_installSourcePage);
 
175
                layout->addWidget(m_targetCombo, 5, 0);
 
176
 
 
177
                m_targetLabel = new QLabel(m_installSourcePage);
 
178
                layout->addMultiCellWidget(m_targetLabel, 6,6,0,0,Qt::AlignTop);
 
179
 
 
180
                //part beloew main layout with the back/next buttons
 
181
                QHBoxLayout* myHBox = new QHBoxLayout();
 
182
                vboxlayout->addLayout(myHBox);
 
183
 
 
184
                m_installBackButton = new QPushButton(i18n("Back"), m_installPage);
 
185
                m_installBackButton->setIconSet(SmallIcon("back",16));
 
186
                myHBox->addWidget(m_installBackButton);
 
187
 
 
188
                myHBox->addSpacing(10);
 
189
                myHBox->addStretch(5);
 
190
 
 
191
                m_installContinueButton = new QPushButton(i18n("Connect to library"), m_installPage);
 
192
                m_installContinueButton->setIconSet(SmallIcon("forward",16));
 
193
                connect(m_installContinueButton, SIGNAL(clicked()), this, SLOT(slot_connectToSource()));
 
194
                myHBox->addWidget(m_installContinueButton);
 
195
 
 
196
                m_installBackButton->setEnabled(false);
 
197
 
 
198
                connect(m_sourceCombo, SIGNAL( highlighted(const QString&) ), SLOT( slot_sourceSelected( const QString&) ));
 
199
                connect(m_targetCombo, SIGNAL( highlighted(const QString&) ), SLOT( slot_targetSelected( const QString&) ));
 
200
                populateInstallCombos();
 
201
 
 
202
                slot_sourceSelected( m_sourceCombo->currentText() );
 
203
        }
 
204
 
 
205
        void CSwordSetupDialog::initRemove() {
 
206
                QFrame* page = m_removePage = addPage(i18n("Remove works"), QString::null, SmallIcon("edittrash",32));
 
207
 
 
208
                page->setMinimumSize(500,400);
 
209
 
 
210
                QGridLayout* layout = new QGridLayout(page, 4, 4);
 
211
                layout->setMargin(5);
 
212
 
 
213
                layout->setSpacing(10);
 
214
                layout->setColStretch(1,1);
 
215
                layout->setRowStretch(2,1);
 
216
 
 
217
                QLabel* mainLabel= CToolClass::explanationLabel(page,
 
218
                                                   i18n("Remove installed work(s)"),
 
219
                                                   i18n("This dialog lets you remove installed works from your system. Choose the modules and then click on the remove button.")
 
220
                                                                                                           );
 
221
                layout->addMultiCellWidget(mainLabel, 0, 0, 0, 3);
 
222
 
 
223
                QLabel* headingLabel = new QLabel(QString("<b>%1</b>").arg(i18n("Select works to be uninstalled")), page);
 
224
                layout->addMultiCellWidget(headingLabel, 1, 1, 0, 3);
 
225
 
 
226
                m_removeModuleListView = new CSwordSetupModuleListView(page, false);
 
227
                layout->addMultiCellWidget( m_removeModuleListView, 2,2,0,3);
 
228
 
 
229
                m_removeRemoveButton = new QPushButton(i18n("Remove selected work(s)"), page);
 
230
                m_removeRemoveButton->setIconSet( SmallIcon("edittrash", 16) );
 
231
                layout->addWidget(m_removeRemoveButton, 3, 3, Qt::AlignRight);
 
232
 
 
233
                connect(m_removeRemoveButton, SIGNAL(clicked()),
 
234
                                this, SLOT(slot_doRemoveModules()));
 
235
 
 
236
                populateRemoveModuleListView();
 
237
        }
 
238
 
 
239
        void CSwordSetupDialog::initManageIndices()
 
240
        {
 
241
                QFrame* page = m_manageIndiciesPage = addPage(i18n("Manage search indicies"),
 
242
                        QString::null, SmallIcon("filefind",32));
 
243
 
 
244
                page->setMinimumSize(500,400);
 
245
                QVBoxLayout* box = new QVBoxLayout(page, 4, 4);
 
246
                CManageIndicesWidget* mi = new CManageIndicesWidget(page);
 
247
                box->addWidget(mi);
 
248
        }
 
249
 
 
250
        void CSwordSetupDialog::slotOk() {
 
251
                writeSwordConfig();
 
252
                KDialogBase::slotOk();
 
253
                emit signalSwordSetupChanged( );
 
254
        }
 
255
 
 
256
        void CSwordSetupDialog::writeSwordConfig() {
 
257
                if (m_swordSetupChanged && m_swordPathListBox->childCount()) {
 
258
                        QStringList targets;
 
259
                        QListViewItemIterator it( m_swordPathListBox );
 
260
                        while ( it.current() ) {
 
261
                                QListViewItem *item = it.current();
 
262
                                if (!item->text(0).isEmpty()) {
 
263
                                        targets << item->text(0);
 
264
                                }
 
265
                                ++it;
 
266
                        }
 
267
 
 
268
                        BTInstallMgr::Tool::LocalConfig::setTargetList(targets); //creates new Sword config
 
269
                }
 
270
        }
 
271
 
 
272
        const bool CSwordSetupDialog::showPart( CSwordSetupDialog::Parts ID ) {
 
273
                bool ret = false;
 
274
                switch (ID) {
 
275
                        case CSwordSetupDialog::Sword:
 
276
                        showPage( pageIndex(m_swordConfigPage) );
 
277
                        break;
 
278
                        case CSwordSetupDialog::Install:
 
279
                        showPage( pageIndex(m_installPage) );
 
280
                        break;
 
281
                        case CSwordSetupDialog::Remove:
 
282
                        showPage( pageIndex(m_removePage) );
 
283
                        break;
 
284
                        default:
 
285
                        break;
 
286
                }
 
287
                return ret;
 
288
        }
 
289
 
 
290
 
 
291
        void CSwordSetupDialog::populateInstallCombos() {
 
292
                m_sourceCombo->clear();
 
293
 
 
294
                BTInstallMgr::Tool::RemoteConfig::initConfig();
 
295
 
 
296
                QStringList list;
 
297
                {
 
298
                        BTInstallMgr mgr;
 
299
                        list = BTInstallMgr::Tool::RemoteConfig::sourceList(&mgr);
 
300
                }
 
301
                if (!list.count()) { //add Crosswire entry
 
302
                        InstallSource is("FTP");   //default return value
 
303
                        is.caption = "Crosswire";
 
304
                        is.source = "ftp.crosswire.org";
 
305
                        is.directory = "/pub/sword/raw";
 
306
                        BTInstallMgr::Tool::RemoteConfig::addSource(&is);
 
307
 
 
308
                        BTInstallMgr mgr; //make sure we're uptodate
 
309
                        list = BTInstallMgr::Tool::RemoteConfig::sourceList(&mgr);
 
310
 
 
311
                        Q_ASSERT( list.count() > 0 );
 
312
                }
 
313
 
 
314
                BTInstallMgr mgr;
 
315
                for (QStringList::iterator it = list.begin(); it != list.end(); ++it) {
 
316
                        sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&mgr, *it);
 
317
 
 
318
                        if (BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is)) {
 
319
                                m_sourceCombo->insertItem( i18n("[Remote]") + " " + *it ); //remote source
 
320
                        }
 
321
                        else { // local source
 
322
                                QFileInfo fi( is.directory.c_str() );
 
323
                                if (fi.isDir() && fi.isReadable()) {
 
324
                                        m_sourceCombo->insertItem( i18n("[Local]") + " " + *it );
 
325
                                }
 
326
                        }
 
327
                }
 
328
 
 
329
                //Fill in the targets in the targets combobox
 
330
                //list = (m_targetCombo->count()) ? m_swordPathListBox : BTInstallMgr::Tool::LocalConfig::targetList();
 
331
                if (m_targetCombo->count()) { //we already read in the list once, we have to use the Sword paths list items now because this list is newer
 
332
                        list.clear();
 
333
                        QListViewItemIterator it2( m_swordPathListBox );
 
334
                        while (it2.current()) {
 
335
                                list << it2.current()->text(0);
 
336
 
 
337
                                ++it2;
 
338
                        }
 
339
                }
 
340
                else {
 
341
                        list = BTInstallMgr::Tool::LocalConfig::targetList();
 
342
                }
 
343
 
 
344
                m_targetCombo->clear();
 
345
                for (QStringList::iterator it = list.begin(); it != list.end(); ++it) {
 
346
                        QFileInfo fi(*it);
 
347
                        if (fi.isDir() && fi.isWritable()) {
 
348
                                m_targetCombo->insertItem( *it );
 
349
                        }
 
350
                }
 
351
 
 
352
                //init widget states
 
353
                m_targetCombo->setEnabled( (m_targetCombo->count() > 0) );
 
354
                m_installContinueButton->setEnabled(
 
355
                        (m_sourceCombo->count() > 0) && (m_targetCombo->count() > 0)
 
356
                );
 
357
 
 
358
                slot_sourceSelected( m_sourceCombo->currentText() );
 
359
        }
 
360
 
 
361
 
 
362
        void CSwordSetupDialog::slot_sourceSelected(const QString &sourceName) {
 
363
                //remove status parta
 
364
                QString source = sourceName;
 
365
 
 
366
                QString rep = i18n("[Local]") + " ";
 
367
                int i = source.find(rep);
 
368
                if (i>=0) {
 
369
                        source.remove(i, rep.length());
 
370
                }
 
371
                rep = i18n("[Remote]") + " ";
 
372
                i = source.find(rep);
 
373
                if (i>=0) {
 
374
                        source.remove(i, rep.length());
 
375
                }
 
376
 
 
377
                BTInstallMgr mgr;
 
378
                QString url;
 
379
                sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&mgr, source) ;
 
380
 
 
381
                if (BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is)) {
 
382
                        url = QString("ftp://%1%2").arg(is.source.c_str()).arg(is.directory.c_str());
 
383
                }
 
384
                else {
 
385
                        url = QString("%1").arg(is.directory.c_str());
 
386
                }
 
387
                m_sourceLabel->setText( url );
 
388
 
 
389
                m_refreshedRemoteSources = false;
 
390
        }
 
391
 
 
392
 
 
393
        void CSwordSetupDialog::slot_targetSelected(const QString &targetName) {
 
394
                m_targetLabel->setText( m_targetMap[targetName] );
 
395
                target = m_targetMap[targetName];
 
396
        }
 
397
 
 
398
 
 
399
        void CSwordSetupDialog::slot_doRemoveModules() {
 
400
 
 
401
                QStringList moduleList =  m_removeModuleListView->selectedModules();
 
402
 
 
403
                if ( moduleList.empty() ) {
 
404
                        return; //no message, just do nothing
 
405
                }
 
406
 
 
407
                const QString message = i18n("You selected the following work(s): %1.\n\n"
 
408
                                                                         "Do you really want to remove them from your system?").arg(moduleList.join(", "));
 
409
 
 
410
                if ((KMessageBox::warningYesNo(0, message, i18n("Warning")) == KMessageBox::Yes)) {  //Yes was pressed.
 
411
                        sword::InstallMgr installMgr;
 
412
                        QDict<sword::SWMgr> mgrDict; //maps config paths to SWMgr objects
 
413
 
 
414
                        for ( QStringList::Iterator it = moduleList.begin(); it != moduleList.end(); ++it ) {
 
415
                                if (CSwordModuleInfo* m = backend()->findModuleByName(*it)) { //module found?
 
416
                                        QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + "/";
 
417
                                        QString dataPath = m->config(CSwordModuleInfo::DataPath);
 
418
 
 
419
                                        if (dataPath.left(2) == "./") {
 
420
                                                dataPath = dataPath.mid(2);
 
421
                                        }
 
422
 
 
423
                                        if (prefixPath.contains(dataPath)) { //remove module part to get the prefix path
 
424
                                                prefixPath = prefixPath.remove( prefixPath.find(dataPath), dataPath.length() );
 
425
                                        }
 
426
                                        else { //fall back to default Sword config path
 
427
                                                prefixPath = QString::fromLatin1(backend()->prefixPath);
 
428
                                        }
 
429
 
 
430
                                        sword::SWMgr* mgr = mgrDict[ prefixPath ];
 
431
                                        if (!mgr) { //create new mgr if it's not yet available
 
432
                                                mgrDict.insert(prefixPath, new sword::SWMgr(prefixPath.local8Bit()));
 
433
                                                mgr = mgrDict[ prefixPath ];
 
434
                                        }
 
435
 
 
436
                                        installMgr.removeModule(mgr, m->name().latin1());
 
437
                                }
 
438
                        }
 
439
 
 
440
                        CPointers::backend()->reloadModules();
 
441
                        populateRemoveModuleListView(); //rebuild the tree
 
442
                        populateInstallModuleListView( currentInstallSource() ); //rebuild the tree
 
443
 
 
444
                        //delete all mgrs
 
445
                        mgrDict.setAutoDelete(true);
 
446
                        mgrDict.clear();
 
447
                }
 
448
        }
 
449
 
 
450
        void CSwordSetupDialog::populateRemoveModuleListView() {
 
451
                CSwordBackend myBackend;
 
452
                KApplication::kApplication()->processEvents();
 
453
                myBackend.initModules();
 
454
 
 
455
                m_removeModuleListView->clear();
 
456
 
 
457
                ListCSwordModuleInfo list = myBackend.moduleList();
 
458
                int mod = 0;
 
459
                sword::SWConfig moduleConfig("");
 
460
 
 
461
                mod = 1;
 
462
                ListCSwordModuleInfo::iterator end_it = list.end();
 
463
 
 
464
                for (ListCSwordModuleInfo::iterator it(list.begin()); it != end_it; ++it, ++mod) {
 
465
                        m_removeModuleListView->addModule(
 
466
                                (*it),
 
467
                                (*it)->config(CSwordModuleInfo::ModuleVersion)
 
468
                        );
 
469
                }
 
470
 
 
471
                m_removeModuleListView->finish();
 
472
        }
 
473
 
 
474
        const bool CSwordSetupDialog::refreshRemoteModuleCache( const QString& sourceName ) {
 
475
                if (m_refreshedRemoteSources) { //the module info is up-to-date
 
476
                        return true;
 
477
                }
 
478
 
 
479
                BTInstallMgr iMgr;
 
480
                m_currentInstallMgr = &iMgr; //for the progress dialog
 
481
                sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&iMgr, sourceName);
 
482
                bool success = false;
 
483
 
 
484
                m_progressDialog = new KProgressDialog(this, 0, i18n("Download"), QString::null, true);
 
485
                m_progressDialog->progressBar()->setTotalSteps(100);
 
486
                m_progressDialog->setLabel( i18n("Downloading library information...") );
 
487
                m_progressDialog->setMinimumDuration(0); //show immediately
 
488
                m_progressDialog->setAutoClose(false);
 
489
                m_progressDialog->show();
 
490
                KApplication::kApplication()->processEvents();
 
491
 
 
492
                connect(
 
493
                        m_progressDialog, SIGNAL(cancelClicked()),
 
494
                        SLOT(slot_moduleRefreshProgressCancelClicked())
 
495
                );
 
496
                connect(
 
497
                        &iMgr, SIGNAL(completed(const int, const int)),
 
498
                        SLOT(slot_moduleRefreshCompleted(const int, const int))
 
499
                );
 
500
 
 
501
 
 
502
                if (BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is)) {
 
503
                        //   int errorCode = 0;
 
504
                        if (!m_refreshedRemoteSources) {
 
505
                                if (!iMgr.refreshRemoteSource( &is ) ) { //make sure the sources were updates sucessfully
 
506
                                        m_refreshedRemoteSources = true;
 
507
                                        success = true;
 
508
                                }
 
509
                                else { //an error occurres, the KIO library should display an error message
 
510
                                        qWarning("InstallMgr: refreshRemoteSources returned an error.");
 
511
                                        m_refreshedRemoteSources = false;
 
512
                                        success = false;
 
513
                                }
 
514
                        }
 
515
                }
 
516
 
 
517
                m_progressDialog->close();
 
518
                delete m_progressDialog;
 
519
                m_progressDialog = 0;
 
520
 
 
521
                return success;
 
522
        }
 
523
 
 
524
        bool CSwordSetupDialog::populateInstallModuleListView( const QString& sourceName ) {
 
525
                KApplication::kApplication()->processEvents();
 
526
                Q_ASSERT(m_installModuleListView);
 
527
                if (!m_installModuleListView) { // this may be an update after removing modules
 
528
                        return false;
 
529
                }
 
530
 
 
531
                m_installModuleListView->clear();
 
532
 
 
533
                BTInstallMgr iMgr;
 
534
                sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&iMgr, sourceName);
 
535
 
 
536
                if (BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is)
 
537
                                && !refreshRemoteModuleCache(sourceName)) {
 
538
                        //   qWarning("finish");
 
539
                        m_installModuleListView->finish();
 
540
                        return false;
 
541
                }
 
542
 
 
543
                //kind of a hack to provide a pointer to mgr next line
 
544
                //   qWarning("createing remote_backend");
 
545
                util::scoped_ptr<CSwordBackend> remote_backend( BTInstallMgr::Tool::backend(&is) );
 
546
                //  qWarning("config path1 is %s", remote_backend->configPath);
 
547
                //  qWarning("config path2 is %s", BTInstallMgr::Tool::backend(&is)->configPath ); //mem leak
 
548
                //   qWarning("after creating remote_backend");
 
549
                Q_ASSERT(remote_backend);
 
550
                Q_ASSERT( BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is) );
 
551
                if (!remote_backend) {
 
552
                        m_installModuleListView->finish();
 
553
                        return false;
 
554
                }
 
555
 
 
556
                CSwordBackend* local_backend = CPointers::backend();
 
557
                Q_ASSERT(local_backend);
 
558
                //  qWarning("local backend has path %s", local_backend->);
 
559
                KApplication::kApplication()->processEvents();
 
560
                //local_backend.initModules();
 
561
 
 
562
                //  qWarning("config path3 is %s", remote_backend->configPath);
 
563
                ListCSwordModuleInfo mods = remote_backend->moduleList();
 
564
                Q_ASSERT(mods.count() > 0);
 
565
 
 
566
                ListCSwordModuleInfo::iterator end_it = mods.end();
 
567
                for (ListCSwordModuleInfo::iterator it(mods.begin()); it != end_it; ++it) {
 
568
                        //   qWarning("adding module %s (%s)", (*it)->name().latin1(), (*it)->config(CSwordModuleInfo::AbsoluteDataPath).latin1());
 
569
                        bool isUpdate = false;
 
570
 
 
571
                        CSwordModuleInfo* const installedModule = local_backend->findModuleByName((*it)->name());
 
572
                        if (installedModule) {
 
573
                                //    qWarning("module is already installed in %s", installedModule->config(CSwordModuleInfo::AbsoluteDataPath).latin1());
 
574
                        }
 
575
                        //     Q_ASSERT(installedModule);
 
576
 
 
577
                        if (installedModule) { //module already installed?
 
578
                                //check whether it's an uodated module or just the same
 
579
                                const SWVersion installedVersion(
 
580
                                        installedModule->config(CSwordModuleInfo::ModuleVersion).latin1()
 
581
                                );
 
582
 
 
583
                                const SWVersion newVersion(
 
584
                                        (*it)->config(CSwordModuleInfo::ModuleVersion).latin1()
 
585
                                );
 
586
 
 
587
                                isUpdate = (newVersion > installedVersion);
 
588
                                if (!isUpdate) {
 
589
                                        //     qWarning("    mod %s is not an update", (*it)->name().latin1());
 
590
                                        continue;
 
591
                                }
 
592
                        }
 
593
 
 
594
                        //   Q_ASSERT(installedModule);
 
595
                        m_installModuleListView->addModule(
 
596
                                (*it),
 
597
                                installedModule
 
598
                                ? installedModule->config(CSwordModuleInfo::ModuleVersion)
 
599
                                : QString::null
 
600
                        );
 
601
                }
 
602
                m_installModuleListView->finish();
 
603
                return true;
 
604
        }
 
605
 
 
606
        void CSwordSetupDialog::slot_connectToSource() {
 
607
                if (!m_installModuleListPage) { //the widgets are not yet created
 
608
                        m_installModuleListPage = new QWidget(0);
 
609
 
 
610
                        QGridLayout* layout = new QGridLayout(m_installModuleListPage, 7, 2);
 
611
                        layout->setMargin(5);
 
612
                        layout->setSpacing(10);
 
613
 
 
614
                        QLabel* installLabel = CToolClass::explanationLabel(m_installModuleListPage,
 
615
                                                                   i18n("Install/update works - Step 2"),
 
616
                                                                   i18n("Please choose the works which should be installed and/or updated and click the install button.")
 
617
                                                                                                                           );
 
618
                        layout->addMultiCellWidget(installLabel, 0,0,0,1);
 
619
                        layout->setRowStretch(0,0);
 
620
 
 
621
                        m_installWidgetStack->addWidget(m_installModuleListPage);
 
622
                        m_installModuleListPage->setMinimumSize(500,400);
 
623
 
 
624
                        //insert a list box which contains all available remote modules
 
625
                        BTInstallMgr iMgr;
 
626
                        sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&iMgr, currentInstallSource());
 
627
 
 
628
                        m_installModuleListView = new CSwordSetupModuleListView(m_installModuleListPage, true, &is);
 
629
                        layout->addMultiCellWidget( m_installModuleListView, 1,6,0,1);
 
630
                        layout->setColStretch(0,5);
 
631
                        layout->setRowStretch(1,5);
 
632
 
 
633
                        connect(m_installModuleListView, SIGNAL(selectedModulesChanged()), SLOT(slot_installModulesChanged()));
 
634
                }
 
635
 
 
636
                if (populateInstallModuleListView( currentInstallSource() ) ){
 
637
 
 
638
                        //code valid for already existing and newly created widgets
 
639
                        disconnect( m_installContinueButton, SIGNAL(clicked()), this, SLOT(slot_connectToSource()));
 
640
                        connect( m_installContinueButton, SIGNAL(clicked()), this, SLOT(slot_installModules()));
 
641
        
 
642
                        m_installContinueButton->setText(i18n("Install works"));
 
643
                        m_installContinueButton->setEnabled(false);
 
644
        
 
645
                        m_installWidgetStack->raiseWidget(m_installModuleListPage);
 
646
        
 
647
                        connect( m_installBackButton, SIGNAL(clicked()), this, SLOT(slot_showInstallSourcePage()));
 
648
                        m_installBackButton->setEnabled(true);
 
649
                }
 
650
        }
 
651
 
 
652
        void CSwordSetupDialog::slot_installAddSource() {
 
653
 
 
654
                sword::InstallSource newSource = CSwordSetupInstallSourcesDialog::getSource();
 
655
 
 
656
                if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add
 
657
                        BTInstallMgr::Tool::RemoteConfig::addSource( &newSource );
 
658
                }
 
659
 
 
660
                populateInstallCombos(); //make sure the items are updated
 
661
        }
 
662
 
 
663
        void CSwordSetupDialog::slot_installDeleteSource() {
 
664
 
 
665
                BTInstallMgr iMgr;
 
666
                sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source( &iMgr, currentInstallSource() );
 
667
                BTInstallMgr::Tool::RemoteConfig::removeSource( &iMgr, &is );
 
668
 
 
669
                populateInstallCombos();
 
670
        }
 
671
 
 
672
        void CSwordSetupDialog::slot_installModulesChanged() {
 
673
                // This function enabled the Install modules button if modules are chosen
 
674
                // If an item was clicked to be not chosen look if there are other selected items
 
675
                // If the item was clicked to be chosen enable the button without looking at the other items
 
676
 
 
677
                const int moduleCount = m_installModuleListView->selectedModules().count();
 
678
                m_installContinueButton->setEnabled(moduleCount > 0);
 
679
        }
 
680
 
 
681
        void CSwordSetupDialog::slot_installModules() {
 
682
                qWarning("CSwordSetupDialog::slot_installModules()");
 
683
                //   m_installContinueButton->setEnabled(false);
 
684
                //   m_installBackButton->setEnabled(false);
 
685
 
 
686
                //first get all chosen modules
 
687
                QStringList moduleList = m_installModuleListView->selectedModules();
 
688
                Q_ASSERT(moduleList.count() != 0);
 
689
                if (moduleList.count() == 0) { // no modules selected
 
690
                        return;
 
691
                }
 
692
 
 
693
                const QString message = i18n("You selected the following works: %1.\n\n\
 
694
 Do you really want to install them on your system?").arg(moduleList.join(", "));
 
695
 
 
696
                if ((KMessageBox::warningYesNo(0, message, i18n("Warning")) == KMessageBox::Yes)) {  //Yes was pressed.
 
697
                        BTInstallMgr iMgr;
 
698
                        m_currentInstallMgr = &iMgr;
 
699
                        sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source(&iMgr, currentInstallSource());
 
700
 
 
701
                        qWarning("installing from %s/%s", is.source.c_str(), is.directory.c_str());
 
702
                        QString target = m_targetCombo->currentText();
 
703
 
 
704
                        //make sure target/mods.d and target/modules exist
 
705
                        QDir dir(target.latin1());
 
706
                        if (!dir.exists()) {
 
707
                                dir.mkdir(target, true);
 
708
                        }
 
709
                        if (!dir.exists("modules")) {
 
710
                                dir.mkdir("modules");
 
711
                        }
 
712
                        if (!dir.exists("mods.d")) {
 
713
                                dir.mkdir("mods.d");
 
714
                        }
 
715
 
 
716
                        sword::SWMgr lMgr( target.latin1() );
 
717
 
 
718
                        //module are removed in this section of code
 
719
                        m_installedModuleCount = 0;
 
720
                        m_progressDialog = new KProgressDialog(this, 0, i18n("Download of work(s)"), QString::null, true);
 
721
                        m_progressDialog->progressBar()->setTotalSteps(100 * moduleList.count());
 
722
                        m_progressDialog->setMinimumDuration(0); //show immediately
 
723
                        m_progressDialog->setAutoClose(false);
 
724
                        m_progressDialog->show();
 
725
                        KApplication::kApplication()->processEvents();
 
726
 
 
727
                        connect(
 
728
                                m_progressDialog, SIGNAL(cancelClicked()),
 
729
                                SLOT(slot_installProgressCancelClicked())
 
730
                        );
 
731
                        connect(
 
732
                                &iMgr, SIGNAL(completed(const int, const int)),
 
733
                                SLOT(installCompleted(const int, const int))
 
734
                        );
 
735
 
 
736
                        for ( QStringList::Iterator it = moduleList.begin(); (it != moduleList.end()) && !m_progressDialog->wasCancelled(); ++it, ++m_installedModuleCount ) {
 
737
 
 
738
                                qWarning("installing %s", (*it).latin1());
 
739
                                m_installingModule = *it;
 
740
 
 
741
                                //check whether it's an update. If yes, remove existing module first
 
742
                                CSwordModuleInfo* m = backend()->findModuleByName(*it);
 
743
                                Q_ASSERT(!m);
 
744
                                if (m) { //module found?
 
745
                                        QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + "/";
 
746
                                        QString dataPath = m->config(CSwordModuleInfo::DataPath);
 
747
                                        if (dataPath.left(2) == "./") {
 
748
                                                dataPath = dataPath.mid(2);
 
749
                                        }
 
750
 
 
751
                                        if (prefixPath.contains(dataPath)) {
 
752
                                                prefixPath.remove( prefixPath.find(dataPath), dataPath.length() ); //complicated to work with Qt 3.0
 
753
                                                //prefixPath = prefixPath.replace(dataPath, ""); //old code working with Qt 3.2
 
754
                                        }
 
755
                                        else {
 
756
                                                prefixPath = QString::fromLatin1(backend()->prefixPath);
 
757
                                        }
 
758
 
 
759
                                        sword::SWMgr mgr(prefixPath.latin1());
 
760
                                        iMgr.removeModule(&mgr, m->name().latin1());
 
761
                                }
 
762
 
 
763
                                if (!m_progressDialog->wasCancelled()
 
764
                                                && BTInstallMgr::Tool::RemoteConfig::isRemoteSource(&is)) {
 
765
                                        //        qWarning("calling install");
 
766
                                        int status = iMgr.installModule(&lMgr, 0, (*it).latin1(), &is);
 
767
                                        //         qWarning("status: %d", status);
 
768
                                        Q_ASSERT(status != -1);
 
769
                                }
 
770
                                else if (!m_progressDialog->wasCancelled()) { //local source
 
771
                                        iMgr.installModule(&lMgr, is.directory.c_str(), (*it).latin1());
 
772
                                }
 
773
                        }
 
774
 
 
775
                        m_progressDialog->close();
 
776
                        delete m_progressDialog;
 
777
                        m_progressDialog = 0;
 
778
 
 
779
                        //reload our backend because modules may have changed
 
780
                        backend()->reloadModules();
 
781
                        populateInstallModuleListView( currentInstallSource() ); //rebuild the tree
 
782
                        populateRemoveModuleListView();
 
783
                }
 
784
 
 
785
                m_currentInstallMgr = 0;
 
786
                m_installBackButton->setEnabled(true);
 
787
                slot_installModulesChanged();
 
788
        }
 
789
 
 
790
        void CSwordSetupDialog::installCompleted( const int total, const int /* file */) {
 
791
                if (m_progressDialog) {
 
792
                        m_progressDialog->progressBar()->setProgress(total+100*m_installedModuleCount);
 
793
                        m_progressDialog->setLabel( i18n("[%1]: %2% complete").arg(m_installingModule).arg(total) );
 
794
                }
 
795
                KApplication::kApplication()->processEvents();
 
796
        }
 
797
 
 
798
        void CSwordSetupDialog::slot_showInstallSourcePage() {
 
799
                connect( m_installContinueButton, SIGNAL(clicked()), this, SLOT(slot_connectToSource()));
 
800
                disconnect( m_installContinueButton, SIGNAL(clicked()), this, SLOT(slot_installModules()));
 
801
                m_installBackButton->setEnabled(false);
 
802
 
 
803
                m_installContinueButton->setText(i18n("Connect to library"));
 
804
                m_installContinueButton->setEnabled(true);
 
805
 
 
806
                m_installWidgetStack->raiseWidget(m_installSourcePage);
 
807
        }
 
808
 
 
809
        void CSwordSetupDialog::slot_swordEditClicked() {
 
810
                if (QListViewItem* i = m_swordPathListBox->currentItem()) {
 
811
                        KURL url = KDirSelectDialog::selectDirectory(i->text(0), true);
 
812
                        if (url.isValid()) {
 
813
                                const QFileInfo fi( url.path() );
 
814
                                if (!fi.exists() || !fi.isWritable()) {
 
815
                                        const int result = KMessageBox::warningYesNo(this, i18n("This directory is not writable, so works \
 
816
   can not be installed here using BibleTime. \
 
817
   Do you want to use this directory instead of the previous value?"));
 
818
                                        if (result == KMessageBox::No) {
 
819
                                                return;
 
820
                                        }
 
821
                                }
 
822
                                i->setText(0, url.path());
 
823
                                m_swordSetupChanged = true;
 
824
                                writeSwordConfig(); //to make sure other parts work with the new setting
 
825
                                populateInstallCombos(); //update target list bof on install page
 
826
                                populateRemoveModuleListView();
 
827
                        }
 
828
                }
 
829
        }
 
830
 
 
831
        void CSwordSetupDialog::slot_swordAddClicked() {
 
832
                KURL url = KDirSelectDialog::selectDirectory(QString::null, true);
 
833
                if (url.isValid()) {
 
834
                        const QFileInfo fi( url.path() );
 
835
                        if (!fi.exists() || !fi.isWritable()) {
 
836
                                const int result = KMessageBox::warningYesNo(this, i18n("This directory is not writable, \
 
837
   so works can not be installed here using BibleTime. \
 
838
   Do you want to add it to the list of module directories?"));
 
839
                                if (result == KMessageBox::No) {
 
840
                                        return;
 
841
                                }
 
842
                        }
 
843
                        (void)new QListViewItem(m_swordPathListBox, url.path());
 
844
                        m_swordSetupChanged = true;
 
845
                        writeSwordConfig(); //to make sure other parts work with the new setting
 
846
                        populateInstallCombos();     //update target list bof on install page
 
847
                        populateRemoveModuleListView();
 
848
                }
 
849
        }
 
850
 
 
851
        void CSwordSetupDialog::slot_swordRemoveClicked() {
 
852
                QListViewItem* i = m_swordPathListBox->currentItem();
 
853
                if (i) {
 
854
                        delete i;
 
855
 
 
856
                        m_swordSetupChanged = true;
 
857
                        writeSwordConfig(); //to make sure other parts work with the new setting
 
858
                        populateInstallCombos(); //update target list bof on install page
 
859
                        populateRemoveModuleListView();
 
860
                }
 
861
        }
 
862
 
 
863
        void CSwordSetupDialog::setupSwordPathListBox() {
 
864
                QStringList targets = BTInstallMgr::Tool::LocalConfig::targetList();
 
865
                m_swordPathListBox->clear();
 
866
 
 
867
                for (QStringList::iterator it = targets.begin(); it != targets.end(); ++it)  {
 
868
                        if ((*it).isEmpty()) {
 
869
                                continue;
 
870
                        }
 
871
                        new QListViewItem(m_swordPathListBox, *it);
 
872
                }
 
873
                m_swordPathListBox->setCurrentItem( m_swordPathListBox->firstChild() );
 
874
        }
 
875
 
 
876
        void CSwordSetupDialog::slot_swordPathSelected() {
 
877
                m_swordEditPathButton->setEnabled( m_swordPathListBox->currentItem() );
 
878
        }
 
879
 
 
880
        const QString CSwordSetupDialog::currentInstallSource() {
 
881
                QString source = m_sourceCombo->currentText();
 
882
                QString rep = i18n("[Local]") + " ";
 
883
                int i = source.find(rep);
 
884
                if (i>=0) {
 
885
                        source.remove(i, rep.length());
 
886
                }
 
887
                rep = i18n("[Remote]") + " ";
 
888
                i = source.find(rep);
 
889
                if (i>=0) {
 
890
                        source.remove(i, rep.length());
 
891
                }
 
892
                return source;
 
893
        }
 
894
 
 
895
        void CSwordSetupDialog::slot_installProgressCancelClicked() {
 
896
                //cancel possible active module installation
 
897
                Q_ASSERT(m_currentInstallMgr);
 
898
                if (m_currentInstallMgr) {
 
899
                        m_currentInstallMgr->terminate();
 
900
                }
 
901
        }
 
902
 
 
903
        void CSwordSetupDialog::slot_moduleRefreshProgressCancelClicked() {
 
904
                Q_ASSERT(m_currentInstallMgr);
 
905
                if (m_currentInstallMgr) {
 
906
                        m_currentInstallMgr->terminate();
 
907
                }
 
908
                KApplication::kApplication()->processEvents();
 
909
        }
 
910
 
 
911
        void CSwordSetupDialog::slot_moduleRefreshCompleted(const int /*total*/, const int current) {
 
912
                if (m_progressDialog) {
 
913
                        m_progressDialog->progressBar()->setProgress(current);
 
914
                }
 
915
                KApplication::kApplication()->processEvents();
 
916
        }
 
917
 
 
918
} // NAMESPACE