Bibletime – a bible study tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cswordsetupdialog.cpp 31KB

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