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.

cindexitem.cpp 36KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  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. //BibleTime includes
  10. #include "cindexitem.h"
  11. #include "cmainindex.h"
  12. #include "backend/creferencemanager.h"
  13. #include "backend/cswordmoduleinfo.h"
  14. #include "backend/cswordkey.h"
  15. #include "backend/cswordversekey.h"
  16. #include "backend/clanguagemgr.h"
  17. #include "frontend/searchdialog/csearchdialog.h"
  18. #include "frontend/cexportmanager.h"
  19. #include "frontend/cbtconfig.h"
  20. #include "frontend/cinputdialog.h"
  21. #include "frontend/cexportmanager.h"
  22. #include "frontend/cdragdropmgr.h"
  23. #include "frontend/cprinter.h"
  24. #include "util/cresmgr.h"
  25. #include "util/scoped_resource.h"
  26. #include "util/ctoolclass.h"
  27. #include <string.h>
  28. //TQt includes
  29. #include <tqdragobject.h>
  30. #include <tqstringlist.h>
  31. #include <tqfile.h>
  32. #include <tqstring.h>
  33. #include <tqtextstream.h>
  34. //KDE includes
  35. #include <tdeconfig.h>
  36. #include <klocale.h>
  37. #include <tdefiledialog.h>
  38. #include <kiconloader.h>
  39. #include <kstandarddirs.h>
  40. #define CURRENT_SYNTAX_VERSION 1
  41. using namespace Printing;
  42. using std::string;
  43. CItemBase::CItemBase(CMainIndex* mainIndex, const Type type)
  44. : TDEListViewItem(mainIndex),
  45. m_type(type),
  46. m_sortingEnabled(true) {}
  47. CItemBase::CItemBase(CItemBase* parentItem, const Type type)
  48. : TDEListViewItem(parentItem),
  49. m_type(type),
  50. m_sortingEnabled(true) {}
  51. CItemBase::~CItemBase() {}
  52. const TQString CItemBase::toolTip() {
  53. return TQString();
  54. }
  55. /** Returns the used main index. */
  56. CMainIndex* CItemBase::listView() const {
  57. return dynamic_cast<CMainIndex*>( TQListViewItem::listView() );
  58. }
  59. void CItemBase::init() {
  60. update();
  61. }
  62. void CItemBase::update() {}
  63. const CItemBase::Type& CItemBase::type() const {
  64. return m_type;
  65. };
  66. void CItemBase::moveAfter( CItemBase* const item ) {
  67. if (!item)
  68. return;
  69. if ( parent() == item->parent() ) { //same parent means level
  70. moveItem(item); //both items are on the same level, so we can use moveItem
  71. }
  72. }
  73. /** Returns true if the given action should be enabled in the popup menu. */
  74. const bool CItemBase::enableAction( const MenuAction /*action*/ ) {
  75. return false; //this base class has no valif actions
  76. }
  77. /** No descriptions */
  78. const bool CItemBase::isMovable() {
  79. return false;
  80. }
  81. const bool CItemBase::allowAutoOpen( const TQMimeSource* ) const {
  82. return false;
  83. };
  84. /** This function engables or disables sorting depending on the parameter. */
  85. void CItemBase::setSortingEnabled( const bool& enableSort ) {
  86. m_sortingEnabled = enableSort;
  87. }
  88. /** Returns true whether the sorting is enabled or not. */
  89. const bool CItemBase::isSortingEnabled() {
  90. return m_sortingEnabled;
  91. }
  92. /** Reimplementation which takes care of the our sortingEnabled setting. */
  93. void CItemBase::sortChildItems( int col, bool asc ) {
  94. if (!isSortingEnabled()) {
  95. return;
  96. }
  97. else {
  98. TDEListViewItem::sortChildItems( col, asc );
  99. }
  100. }
  101. /** Reimplementation which takes care of the our sortingEnabled setting. */
  102. void CItemBase::sort() {
  103. if (!isSortingEnabled()) {
  104. return;
  105. }
  106. else {
  107. TDEListViewItem::sort();
  108. }
  109. }
  110. /* ---------------------------------------------- */
  111. /* ---------- new class: CModuleItem ------------ */
  112. /* ---------------------------------------------- */
  113. CModuleItem::CModuleItem(CTreeFolder* parentItem, CSwordModuleInfo* module) : CItemBase(parentItem), m_module(module) {}
  114. CModuleItem::~CModuleItem() {}
  115. /** No descriptions */
  116. void CModuleItem::update() {
  117. if (m_module) {
  118. setPixmap(0, CToolClass::getIconForModule(m_module));
  119. setText(0,m_module->name() );
  120. }
  121. }
  122. void CModuleItem::init() {
  123. setDragEnabled(false);
  124. setDropEnabled(true);
  125. update();
  126. }
  127. /** Reimplementation to handle text drops on a module. In this case open the searchdialog. In the case of a referebnce open the module at the given position. */
  128. bool CModuleItem::acceptDrop( const TQMimeSource* src ) const {
  129. if (CDragDropMgr::canDecode(src)) {
  130. if (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark) {
  131. CDragDropMgr::Item item = CDragDropMgr::decode(src).first();
  132. CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
  133. if (m && (module()->type() == m->type())) { //it makes only sense
  134. return true;
  135. }
  136. //but we also allow drops from bibles on commentaries and the other way from commentaries
  137. else if (m && (module()->type() == CSwordModuleInfo::Bible) && (m->type() == CSwordModuleInfo::Commentary)) {
  138. return true;
  139. }
  140. else if (m && (module()->type() == CSwordModuleInfo::Commentary) && (m->type() == CSwordModuleInfo::Bible)) {
  141. return true;
  142. }
  143. }
  144. else if(CDragDropMgr::dndType(src) == CDragDropMgr::Item::Text) { //text drop on a module
  145. return true;
  146. };
  147. }
  148. return false; //default return value
  149. }
  150. /** No descriptions */
  151. void CModuleItem::dropped( TQDropEvent* e, TQListViewItem* /*after*/) {
  152. /* Something was dropped on a module item
  153. *
  154. * 1. If the drop type is plain text open the searchdialog for this text and start the search
  155. * 2. If the type is Bookmark, open the module at the specified position
  156. *
  157. * We support only the first drop item, more is not useful
  158. */
  159. if (acceptDrop(e)) {
  160. CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
  161. CDragDropMgr::Item item = dndItems.first();
  162. if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Text) { //open the searchdialog
  163. // tqWarning("Text dropped!");
  164. if ( module() ) {
  165. ListCSwordModuleInfo modules;
  166. modules.append(module());
  167. Search::CSearchDialog::openDialog(modules, item.text());
  168. }
  169. }
  170. else if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Bookmark) { //open the module
  171. CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
  172. if (m) { //it makes only sense to create a new window for a module with the same type
  173. if ((module()->type() == m->type()) ||
  174. ((module()->type() == CSwordModuleInfo::Bible || module()->type() == CSwordModuleInfo::Commentary)
  175. && (m->type() == CSwordModuleInfo::Bible || m->type() == CSwordModuleInfo::Commentary))) { //same base type of module
  176. ListCSwordModuleInfo modules;
  177. modules.append(module());
  178. listView()->emitModulesChosen(modules, item.bookmarkKey());
  179. };
  180. }
  181. }
  182. };
  183. }
  184. /** Reimplementation. */
  185. const TQString CModuleItem::toolTip() {
  186. return CToolClass::moduleToolTip(module());
  187. }
  188. /** Returns the used module. */
  189. CSwordModuleInfo* const CModuleItem::module() const {
  190. return m_module;
  191. }
  192. /** Reimplementation from CItemBase. */
  193. const bool CModuleItem::enableAction( const MenuAction action ) {
  194. if (action == EditModule) {
  195. if (!module())
  196. return false;
  197. return module()->isWritable();
  198. }
  199. if (action == SearchInModules || action == AboutModule)
  200. return true;
  201. if (module()->isEncrypted() && action == UnlockModule)
  202. return true;
  203. return false;
  204. }
  205. /* ----------------------------------------------*/
  206. /* ---------- new class: CBookmarkItem ------------*/
  207. /* ----------------------------------------------*/
  208. CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, CSwordModuleInfo* module, const TQString& key, const TQString& description)
  209. : CItemBase(parentItem),
  210. m_description(description),
  211. m_moduleName(module ? module->name() : TQString()) {
  212. if ((module && (module->type() == CSwordModuleInfo::Bible) || (module->type() == CSwordModuleInfo::Commentary)) ) {
  213. CSwordVerseKey vk(0);
  214. vk = key;
  215. vk.setLocale("en");
  216. m_key = vk.key(); //the m_key member is always the english key!
  217. }
  218. else {
  219. m_key = key;
  220. };
  221. m_startupXML = TQDomElement(); //empty XML code
  222. }
  223. CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, TQDomElement& xml )
  224. : CItemBase(parentItem),
  225. m_key(TQString()),
  226. m_description(TQString()),
  227. m_moduleName(TQString()) {
  228. m_startupXML = xml;
  229. }
  230. CBookmarkItem::~CBookmarkItem() {}
  231. /** No descriptions */
  232. void CBookmarkItem::update() {
  233. setMultiLinesEnabled(true);
  234. setPixmap(0,SmallIcon(CResMgr::mainIndex::bookmark::icon,16));
  235. const TQString title = TQString::fromLatin1("%1 (%2)")
  236. .arg(key())
  237. .arg(module() ? module()->name() : i18n("unknown"));
  238. setText(0, title);
  239. }
  240. void CBookmarkItem::init() {
  241. if (!m_startupXML.isNull()) { //we have some XML code to parse
  242. loadFromXML(m_startupXML);
  243. }
  244. update();
  245. setDropEnabled(false);
  246. setDragEnabled(false);
  247. // if (!module())
  248. // setSelectable(false);
  249. }
  250. /** Reimplementation. */
  251. const TQString CBookmarkItem::toolTip() {
  252. if (!module()) {
  253. return TQString();
  254. }
  255. CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults();
  256. filterOptions.footnotes = false;
  257. filterOptions.scriptureReferences = false;
  258. CPointers::backend()->setFilterOptions(filterOptions);
  259. TQString ret;
  260. util::scoped_ptr<CSwordKey> k( CSwordKey::createInstance(module()) );
  261. k->key(this->key());
  262. const CLanguageMgr::Language* lang = module()->language();
  263. CBTConfig::FontSettingsPair fontPair = CBTConfig::get
  264. (lang);
  265. Q_ASSERT(k.get());
  266. if (fontPair.first) { //use a special font
  267. tqWarning("using a font, %s", TQString(fontPair.second.family()).latin1());
  268. ret = TQString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr><font face=\"%4\" size=\"4\">%5</font>")
  269. .arg(key())
  270. .arg(module()->name())
  271. .arg(description())
  272. .arg(fontPair.second.family())
  273. .arg(k->renderedText());
  274. }
  275. else {
  276. ret = TQString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr>%4")
  277. .arg(key())
  278. .arg(module()->name())
  279. .arg(description())
  280. .arg(k->renderedText());
  281. }
  282. return ret;
  283. }
  284. /** Returns the used module. */
  285. CSwordModuleInfo* const CBookmarkItem::module() {
  286. CSwordModuleInfo* const m = CPointers::backend()->findModuleByName(m_moduleName);
  287. Q_ASSERT(m);
  288. return m;
  289. }
  290. /** Returns the used key. */
  291. const TQString CBookmarkItem::key() {
  292. const TQString englishKeyName = englishKey();
  293. if (!module()) {
  294. return englishKeyName;
  295. }
  296. TQString returnKeyName = englishKeyName;
  297. if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) {
  298. CSwordVerseKey vk(0);
  299. vk = englishKeyName;
  300. vk.setLocale(CPointers::backend()->booknameLanguage().latin1() );
  301. returnKeyName = vk.key(); //the returned key is always in the currently set bookname language
  302. }
  303. return returnKeyName;
  304. }
  305. /** Returns the used description. */
  306. const TQString& CBookmarkItem::description() {
  307. return m_description;
  308. }
  309. /** No descriptions */
  310. const bool CBookmarkItem::isMovable() {
  311. return true;
  312. }
  313. /** Reimplementation to handle the menu entries of the main index. */
  314. const bool CBookmarkItem::enableAction(const MenuAction action) {
  315. if (action == ChangeBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries)
  316. return true;
  317. return false;
  318. }
  319. /** Changes this bookmark. */
  320. void CBookmarkItem::rename() {
  321. bool ok = false;
  322. const TQString newDescription = CInputDialog::getText(i18n("Change description ..."), i18n("Enter a new description for the chosen bookmark."), description(), &ok, listView(), true);
  323. if (ok) {
  324. m_description = newDescription;
  325. update();
  326. }
  327. }
  328. /** Reimplementation of CItemBase::saveToXML. */
  329. TQDomElement CBookmarkItem::saveToXML( TQDomDocument& doc ) {
  330. TQDomElement elem = doc.createElement("Bookmark");
  331. elem.setAttribute("key", englishKey());
  332. elem.setAttribute("description", description());
  333. elem.setAttribute("modulename", m_moduleName);
  334. elem.setAttribute("moduledescription", module() ? module()->config(CSwordModuleInfo::Description) : TQString());
  335. return elem;
  336. }
  337. void CBookmarkItem::loadFromXML( TQDomElement& element ) {
  338. if (element.isNull())
  339. return;
  340. //find the right module
  341. if (element.hasAttribute("modulename")) {
  342. //we use the name in all cases, even if the module isn't installed anymore
  343. m_moduleName = element.attribute("modulename");
  344. }
  345. if (element.hasAttribute("key")) {
  346. m_key = element.attribute("key");
  347. }
  348. if (element.hasAttribute("description")) {
  349. m_description = element.attribute("description");
  350. }
  351. }
  352. /** Returns the english key. */
  353. const TQString& CBookmarkItem::englishKey() const {
  354. return m_key;
  355. }
  356. /** Reimplementation. Returns false everytime because a bookmarks has not possible drops. */
  357. bool CBookmarkItem::acceptDrop(const TQMimeSource* /*src*/) const {
  358. return false;
  359. }
  360. /****************************************/
  361. /***** class: CItemFolder *************/
  362. /****************************************/
  363. CFolderBase::CFolderBase(CMainIndex* mainIndex, const Type type) : CItemBase(mainIndex, type) {}
  364. CFolderBase::CFolderBase(CFolderBase* parentItem, const Type type) : CItemBase(parentItem, type) {}
  365. CFolderBase::CFolderBase(CFolderBase* parentFolder, const TQString& caption) : CItemBase(parentFolder) {
  366. setText(0, caption);
  367. }
  368. CFolderBase::~CFolderBase() {}
  369. const bool CFolderBase::isFolder() {
  370. return true;
  371. }
  372. void CFolderBase::update() {
  373. CItemBase::update();
  374. if (isOpen() && childCount())
  375. setPixmap(0, SmallIcon(CResMgr::mainIndex::openedFolder::icon, 16));
  376. else
  377. setPixmap(0, SmallIcon(CResMgr::mainIndex::closedFolder::icon, 16));
  378. }
  379. void CFolderBase::init() {
  380. CItemBase::init();
  381. setDropEnabled(false);
  382. setDragEnabled(false);
  383. }
  384. /** No descriptions */
  385. void CFolderBase::setOpen( bool open ) {
  386. TDEListViewItem::setOpen(open);
  387. update();
  388. }
  389. /** The function which renames this folder. */
  390. void CFolderBase::rename() {
  391. startRename(0);
  392. }
  393. /** Creates a new sub folder of this folder. */
  394. void CFolderBase::newSubFolder() {
  395. if (dynamic_cast<CBookmarkFolder*>(this) || dynamic_cast<Bookmarks::SubFolder*>(this) ) {
  396. Bookmarks::SubFolder* f = new Bookmarks::SubFolder(this, i18n("New folder"));
  397. f->init();
  398. listView()->setCurrentItem(f);
  399. listView()->ensureItemVisible(f);
  400. f->rename();
  401. }
  402. }
  403. /** Reimplementation. Returns true if the drop is accepted. */
  404. const bool CFolderBase::allowAutoOpen( const TQMimeSource* ) const {
  405. return true;
  406. }
  407. /** Reimplementation. Returns false because folders have no use for drops (except for the bookmark folders) */
  408. bool CFolderBase::acceptDrop(const TQMimeSource*) const {
  409. return false;
  410. }
  411. TQPtrList<TQListViewItem> CFolderBase::getChildList() {
  412. TQPtrList<TQListViewItem> childs;
  413. if (!childCount()) //no childs available
  414. return childs;
  415. TQListViewItem* i = firstChild();
  416. while (i && (i->parent() == this)) {
  417. CItemBase* item = dynamic_cast<CItemBase*>(i);
  418. if (item) { //we found a valid item
  419. childs.append(item);
  420. CFolderBase* folder = dynamic_cast<CFolderBase*>(i);
  421. if (folder) {
  422. TQPtrList<TQListViewItem> subChilds = folder->getChildList();
  423. for (TQListViewItem* ci = subChilds.first(); ci; ci = subChilds.next()) {
  424. childs.append(ci);
  425. }
  426. }
  427. }
  428. do {
  429. i = i->nextSibling();
  430. }
  431. while (i && (i->parent() != this));
  432. }
  433. return childs;
  434. }
  435. /****************************************/
  436. /***** class: CTreeFolder *************/
  437. /****************************************/
  438. CTreeFolder::CTreeFolder(CMainIndex* mainIndex, const Type type, const TQString& language) : CFolderBase(mainIndex, type) {
  439. m_language = language;
  440. }
  441. CTreeFolder::CTreeFolder(CFolderBase* item, const Type type, const TQString& language) : CFolderBase(item, type) {
  442. m_language = language;
  443. }
  444. CTreeFolder::~CTreeFolder() {}
  445. void CTreeFolder::addGroup(const Type type, const TQString language) {
  446. CTreeFolder* i = 0;
  447. if (type == BookmarkFolder) {
  448. i = new CBookmarkFolder(this);
  449. }
  450. else if (type == OldBookmarkFolder) {
  451. i = new Bookmarks::OldBookmarksFolder(this);
  452. }
  453. else {
  454. i = new CTreeFolder(this, type, language);
  455. }
  456. i->init();
  457. if (!i->childCount())
  458. delete i;
  459. }
  460. void CTreeFolder::addModule(CSwordModuleInfo* const module) {
  461. CModuleItem* i = new CModuleItem(this, module);
  462. i->init();
  463. }
  464. void CTreeFolder::addBookmark(CSwordModuleInfo* module, const TQString& key, const TQString& description) {
  465. CBookmarkItem* i = new CBookmarkItem(this, module, key, description);
  466. i->init();
  467. }
  468. void CTreeFolder::update() {
  469. CFolderBase::update();
  470. }
  471. void CTreeFolder::init() {
  472. if (language() == "*") {
  473. switch (type()) {
  474. case BibleModuleFolder:
  475. setText(0,i18n("Bibles"));
  476. break;
  477. case CommentaryModuleFolder:
  478. setText(0,i18n("Commentaries"));
  479. break;
  480. case LexiconModuleFolder:
  481. setText(0,i18n("Lexicons"));
  482. break;
  483. case BookModuleFolder:
  484. setText(0,i18n("Books"));
  485. break;
  486. case DevotionalModuleFolder:
  487. setText(0,i18n("Daily devotionals"));
  488. break;
  489. case GlossaryModuleFolder:
  490. setText(0,i18n("Glossaries"));
  491. break;
  492. case BookmarkFolder:
  493. setText(0,i18n("Bookmarks"));
  494. break;
  495. case OldBookmarkFolder:
  496. setText(0,i18n("Old bookmarks"));
  497. break;
  498. default:
  499. setText(0, i18n("Unknown"));
  500. break;
  501. };
  502. }
  503. else {
  504. const CLanguageMgr::Language* const lang = CPointers::languageMgr()->languageForAbbrev( language() );
  505. setText(0, !language().isEmpty() ? ( lang->isValid() ? lang->translatedName() : language()) : i18n("Unknown language"));
  506. }
  507. initTree();
  508. update();
  509. }
  510. void CTreeFolder::initTree() {
  511. // tqWarning("CTreeMgr::initTree");
  512. if (type() == Unknown)
  513. return;
  514. CSwordModuleInfo::ModuleType moduleType = CSwordModuleInfo::Unknown;
  515. if (type() == BibleModuleFolder)
  516. moduleType = CSwordModuleInfo::Bible;
  517. else if (type() == CommentaryModuleFolder)
  518. moduleType = CSwordModuleInfo::Commentary;
  519. else if (type() == LexiconModuleFolder || type() == GlossaryModuleFolder || type() == DevotionalModuleFolder)
  520. moduleType = CSwordModuleInfo::Lexicon;
  521. else if (type() == BookModuleFolder)
  522. moduleType = CSwordModuleInfo::GenericBook;
  523. //get all modules by using the given type
  524. ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
  525. ListCSwordModuleInfo usedModules;
  526. ListCSwordModuleInfo::iterator end_it = allModules.end();
  527. for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
  528. // for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
  529. if ((*it)->type() == moduleType) { //found a module, check if the type is correct (devotional etc.)
  530. if (type() == GlossaryModuleFolder && !(*it)->category() == CSwordModuleInfo::Glossary) { //not a gglossary
  531. continue;
  532. }
  533. if (type() == DevotionalModuleFolder && ((*it)->category() != CSwordModuleInfo::DailyDevotional)) {//not a devotional
  534. continue;
  535. }
  536. if (type() == LexiconModuleFolder && ( ((*it)->category() == CSwordModuleInfo::DailyDevotional) || ((*it)->category() == CSwordModuleInfo::Glossary) )) {
  537. //while looking for lexicons glossaries and devotionals shouldn't be used
  538. continue;
  539. }
  540. if (language() == TQString::fromLatin1("*") || (language() != TQString::fromLatin1("*") && TQString::fromLatin1((*it)->module()->Lang()) == language()) )//right type and language!
  541. usedModules.append(*it);
  542. }
  543. }
  544. //we have now all modules we want to have
  545. if (language() == TQString::fromLatin1("*")) { //create subfolders for each language
  546. TQStringList usedLangs;
  547. // for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
  548. /*ListCSwordModuleInfo::iterator*/
  549. end_it = usedModules.end();
  550. for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
  551. TQString lang = TQString::fromLatin1((*it)->module()->Lang());
  552. // if (lang.isEmpty())
  553. // lang = ");
  554. if (!usedLangs.contains(lang)) {
  555. usedLangs.append(lang);
  556. }
  557. }
  558. //ToDo:: Optimize the loop with const itrs
  559. TQStringList::iterator lang_it;
  560. for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
  561. addGroup(/**lang_it,*/ type(), *lang_it);
  562. }
  563. }
  564. else if (usedModules.count() > 0) { //create subitems with the given type and language
  565. /*ListCSwordModuleInfo::iterator*/ end_it = usedModules.end();
  566. for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
  567. // for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
  568. addModule(*it);
  569. }
  570. }
  571. sortChildItems(0,true);
  572. }
  573. const TQString& CTreeFolder::language() const {
  574. return m_language;
  575. };
  576. /* --------------------------------------------------*/
  577. /* ---------- new class: CBookmarkFolder::SubFolder--*/
  578. /* --------------------------------------------------*/
  579. namespace Bookmarks {
  580. /* --------------------------------------------------------------------------*/
  581. /* ---------- new class: CBookmarkFolder::OldBookmarkImport -----------------*/
  582. /* --------------------------------------------------------------------------*/
  583. const TQString OldBookmarkImport::oldBookmarksXML( const TQString& configFileName ) {
  584. TQString fileName = (configFileName.isEmpty()) ? "bt-groupmanager" : configFileName;
  585. TDEConfig* config = new KSimpleConfig( fileName );
  586. TDEConfigGroupSaver groupSaver(config, configFileName.isEmpty() ? "Groupmanager" : "Bookmarks");
  587. TQDomDocument doc("DOC");
  588. doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
  589. TQDomElement content = doc.createElement("SwordBookmarks");
  590. content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
  591. doc.appendChild(content);
  592. //first create the bookmark groups in the XML document, then add the bookmarks to each parent
  593. TQMap<int, TQDomElement> parentMap; //maps parent ids to dom elements
  594. TQStringList groupList = config->readListEntry("Groups");
  595. TQValueList<int> parentList = config->readIntListEntry("Group parents");
  596. TQStringList::Iterator it_groups = groupList.begin();
  597. TQValueList<int>::Iterator it_parents = parentList.begin();
  598. int parentIDCounter = 0;
  599. while ( (it_groups != groupList.end()) && (it_parents != parentList.end()) ) {
  600. TQDomElement parentElement = (*it_parents == -1) ? content : parentMap[*it_parents];
  601. if (parentElement.isNull()) {
  602. tqWarning("EMPTY PARENT FOUND!");
  603. parentElement = content;
  604. };
  605. TQDomElement elem = doc.createElement("Folder");
  606. elem.setAttribute("caption", (*it_groups));
  607. parentMap.insert(parentIDCounter, elem);
  608. parentElement.appendChild( elem );
  609. ++it_parents;
  610. ++it_groups;
  611. ++parentIDCounter;
  612. }
  613. //groups are now read in, create now the bookmarks
  614. parentList = config->readIntListEntry("Bookmark parents");
  615. TQStringList bookmarkList = config->readListEntry("Bookmarks");
  616. TQStringList bookmarkModulesList = config->readListEntry("Bookmark modules");
  617. TQStringList bookmarkDescriptionsList = config->readListEntry("Bookmark descriptions");
  618. it_parents = parentList.begin();
  619. TQStringList::Iterator it_bookmarks = bookmarkList.begin();
  620. TQStringList::Iterator it_modules = bookmarkModulesList.begin();
  621. TQStringList::Iterator it_descriptions = bookmarkDescriptionsList.begin();
  622. while ( it_bookmarks != bookmarkList.end()
  623. && it_parents != parentList.end()
  624. && it_modules != bookmarkModulesList.end()
  625. ) {
  626. TQDomElement parentElement = ((*it_parents) == -1) ? content : parentMap[(*it_parents)];
  627. if (parentElement.isNull()) {
  628. tqWarning("EMPTY PARENT FOUND!");
  629. parentElement = content;
  630. };
  631. TQDomElement elem = doc.createElement("Bookmark");
  632. elem.setAttribute("key", *it_bookmarks);
  633. elem.setAttribute("description", *it_descriptions);
  634. elem.setAttribute("modulename", *it_modules);
  635. CSwordModuleInfo* m = CPointers::backend()->findModuleByName( *it_modules );
  636. elem.setAttribute("moduledescription", m ? m->config(CSwordModuleInfo::Description) : TQString());
  637. parentElement.appendChild( elem );
  638. ++it_parents;
  639. ++it_modules;
  640. ++it_descriptions;
  641. ++it_bookmarks;
  642. };
  643. return doc.toString();
  644. };
  645. /********************
  646. * New class: OldBookmarkFolder
  647. *********************/
  648. OldBookmarksFolder::OldBookmarksFolder(CTreeFolder* folder) : CBookmarkFolder(folder, OldBookmarkFolder) {}
  649. OldBookmarksFolder::~OldBookmarksFolder() {}
  650. /** Reimplementation to handle special bookmark tree. */
  651. void OldBookmarksFolder::initTree() {
  652. // Import the bookmarks of the previous BibleTime versions
  653. if (!CBTConfig::get
  654. ( CBTConfig::readOldBookmarks )) { //if we havn't yet loaded the old bookmarks
  655. loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML() );
  656. }
  657. }
  658. TQDomElement OldBookmarksFolder::saveToXML( TQDomDocument& doc ) {
  659. TQDomElement elem = doc.createElement("Folder");
  660. elem.setAttribute("caption", text(0));
  661. // Append the XML nodes of all child items
  662. CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
  663. while( i ) {
  664. if (i->parent() == this) {
  665. TQDomElement newElem = i->saveToXML( doc );
  666. if (!newElem.isNull()) {
  667. elem.appendChild( newElem ); //append to this folder
  668. }
  669. }
  670. i = dynamic_cast<CItemBase*>( i->nextSibling() );
  671. }
  672. // Save to config, that we imported the old bookmarks and that we have them on disk
  673. CBTConfig::set
  674. ( CBTConfig::readOldBookmarks, true );
  675. return elem;
  676. }
  677. void OldBookmarksFolder::loadFromXML( TQDomElement& /*element*/ ) {
  678. //this function is empty because the folder imports the old 1.2 bookmarks from the bt-groupmanager config file
  679. }
  680. // New class SubFolder
  681. SubFolder::SubFolder(CFolderBase* parentItem, const TQString& caption) : CBookmarkFolder(parentItem, BookmarkFolder) {
  682. m_startupXML = TQDomElement();
  683. setText( 0, caption );
  684. }
  685. SubFolder::SubFolder(CFolderBase* parentItem, TQDomElement& xml ) : CBookmarkFolder(parentItem, BookmarkFolder) {
  686. m_startupXML = xml;
  687. }
  688. SubFolder::~SubFolder() {}
  689. void SubFolder::init() {
  690. CFolderBase::init();
  691. if (!m_startupXML.isNull())
  692. loadFromXML(m_startupXML);
  693. setDropEnabled(true);
  694. setRenameEnabled(0,true);
  695. }
  696. /** Reimplementation from CItemBase. */
  697. const bool SubFolder::enableAction(const MenuAction action) {
  698. if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks )
  699. return true;
  700. if (action == ExportBookmarks || action == ImportBookmarks )
  701. return true; //not yet implemented
  702. if ((action == PrintBookmarks) && childCount()){
  703. CPrinter::KeyTree tree;
  704. CPrinter::KeyTreeItem::Settings settings;
  705. TQPtrList<TQListViewItem> items = getChildList();
  706. //create a tree of keytreeitems using the bookmark hierarchy.
  707. for (items.first(); items.current(); items.next()) {
  708. CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(items.current());
  709. if (i) {
  710. tree.append( new CPrinter::KeyTreeItem( i->key(), i->module(), settings ) );
  711. }
  712. }
  713. return tree.collectModules().count() > 0;
  714. }
  715. return false;
  716. }
  717. /** Returns the XML code which represents the content of this folder. */
  718. TQDomElement SubFolder::saveToXML( TQDomDocument& doc ) {
  719. /**
  720. * Save all subitems (bookmarks and folders) to the XML file.
  721. * We get the XML code for the items by calling their own saveToXML implementations.
  722. */
  723. TQDomElement elem = doc.createElement("Folder");
  724. elem.setAttribute("caption", text(0));
  725. //append the XML nodes of all child items
  726. CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
  727. while( i ) {
  728. if (i->parent() == this) {
  729. TQDomElement newElem = i->saveToXML( doc );
  730. if (!newElem.isNull()) {
  731. elem.appendChild( newElem ); //append to this folder
  732. }
  733. }
  734. i = dynamic_cast<CItemBase*>( i->nextSibling() );
  735. }
  736. return elem;
  737. }
  738. /** Loads the content of this folder from the XML code passed as argument to this function. */
  739. void SubFolder::loadFromXML( TQDomElement& elem ) {
  740. //get the caption and restore all child items!
  741. if (elem.hasAttribute("caption"))
  742. setText(0, elem.attribute("caption"));
  743. //restore all child items
  744. TQDomElement child = elem.firstChild().toElement();
  745. CItemBase* oldItem = 0;
  746. while ( !child.isNull() && child.parentNode() == elem ) {
  747. CItemBase* i = 0;
  748. if (child.tagName() == "Folder") {
  749. i = new Bookmarks::SubFolder(this, child);
  750. }
  751. else if (child.tagName() == "Bookmark") {
  752. i = new CBookmarkItem(this, child);
  753. }
  754. i->init();
  755. if (oldItem)
  756. i->moveAfter(oldItem);
  757. oldItem = i;
  758. child = child.nextSibling().toElement();
  759. }
  760. }
  761. };
  762. /* --------------------------------------------------*/
  763. /* ---------- new class: CBookmarkFolder ------------*/
  764. /* --------------------------------------------------*/
  765. CBookmarkFolder::CBookmarkFolder(CMainIndex* mainIndex, const Type type) : CTreeFolder(mainIndex, type, "*") {
  766. setSortingEnabled(false);
  767. }
  768. CBookmarkFolder::CBookmarkFolder(CFolderBase* parentItem, const Type type) : CTreeFolder(parentItem, type, "*") {
  769. setSortingEnabled(false);
  770. }
  771. CBookmarkFolder::~CBookmarkFolder() {}
  772. void CBookmarkFolder::initTree() {
  773. addGroup(OldBookmarkFolder, "*");
  774. TDEStandardDirs stdDirs;
  775. const TQString path = stdDirs.saveLocation("data", "bibletime/");
  776. if (!path.isEmpty()) {
  777. loadBookmarks(path + "bookmarks.xml");
  778. }
  779. }
  780. /** Reimplementation. */
  781. const bool CBookmarkFolder::enableAction(const MenuAction action) {
  782. if ((action == NewFolder) || (action == ImportBookmarks))
  783. return true;
  784. if ((action == ExportBookmarks) && childCount())
  785. return true;
  786. if ((action == PrintBookmarks) && childCount())
  787. return true;
  788. return false;
  789. }
  790. void CBookmarkFolder::exportBookmarks() {
  791. TQString fileName = KFileDialog::getSaveFileName(TQString(), i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Export bookmarks"));
  792. if (!fileName.isEmpty()) {
  793. saveBookmarks( fileName, false ); //false means we don't want to overwrite the file without asking the user
  794. };
  795. }
  796. void CBookmarkFolder::importBookmarks() {
  797. TQString fileName = KFileDialog::getOpenFileName(TQString(), i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Import bookmarks"));
  798. if (!fileName.isEmpty()) {
  799. //we have to decide if we should load an old bookmark file from 1.2 or earlier or the new XML format of > 1.3
  800. if ( !loadBookmarks(fileName) ) { //if this failed try to load it as old bookmark file
  801. loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML( fileName ) );
  802. };
  803. };
  804. }
  805. bool CBookmarkFolder::acceptDrop(const TQMimeSource * src) const {
  806. // tqWarning("bool CBookmarkFolder::acceptDrop(const TQMimeSource * src): return%ii", (CDragDropMgr::canDecode(src) && (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark)));
  807. return CDragDropMgr::canDecode(src)
  808. && (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark);
  809. }
  810. void CBookmarkFolder::dropped(TQDropEvent *e, TQListViewItem* after) {
  811. if (acceptDrop(e)) {
  812. CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
  813. CDragDropMgr::ItemList::Iterator it;
  814. CItemBase* previousItem = dynamic_cast<CItemBase*>(after);
  815. for( it = dndItems.begin(); it != dndItems.end(); ++it) {
  816. CSwordModuleInfo* module = CPointers::backend()->findModuleByName(
  817. (*it).bookmarkModule()
  818. );
  819. CBookmarkItem* i = new CBookmarkItem(
  820. this,
  821. module,
  822. (*it).bookmarkKey(),
  823. (*it).bookmarkDescription()
  824. );
  825. if (previousItem) {
  826. i->moveAfter( previousItem );
  827. }
  828. i->init();
  829. previousItem = i;
  830. };
  831. };
  832. }
  833. /** Saves the bookmarks in a file. */
  834. const bool CBookmarkFolder::saveBookmarks( const TQString& filename, const bool& forceOverwrite ) {
  835. TQDomDocument doc("DOC");
  836. doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
  837. TQDomElement content = doc.createElement("SwordBookmarks");
  838. content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
  839. doc.appendChild(content);
  840. //append the XML nodes of all child items
  841. CItemBase* i = dynamic_cast<CItemBase*>( firstChild() );
  842. while( i ) {
  843. if (i->parent() == this) { //only one level under this folder
  844. TQDomElement newElem = i->saveToXML( doc ); // the cild creates it's own XML code
  845. if (!newElem.isNull()) {
  846. content.appendChild( newElem ); //append to this folder
  847. }
  848. }
  849. i = dynamic_cast<CItemBase*>( i->nextSibling() );
  850. }
  851. return CToolClass::savePlainFile(filename, doc.toString(), forceOverwrite, TQTextStream::UnicodeUTF8);
  852. }
  853. const bool CBookmarkFolder::loadBookmarksFromXML( const TQString& xml ) {
  854. TQDomDocument doc;
  855. doc.setContent(xml);
  856. TQDomElement document = doc.documentElement();
  857. if( document.tagName() != "SwordBookmarks" ) {
  858. tqWarning("Not a BibleTime Bookmark XML file");
  859. return false;
  860. }
  861. CItemBase* oldItem = 0;
  862. //restore all child items
  863. TQDomElement child = document.firstChild().toElement();
  864. while ( !child.isNull() && child.parentNode() == document) {
  865. CItemBase* i = 0;
  866. if (child.tagName() == "Folder") {
  867. i = new Bookmarks::SubFolder(this, child);
  868. }
  869. else if (child.tagName() == "Bookmark") {
  870. i = new CBookmarkItem(this, child);
  871. }
  872. if (!i) {
  873. break;
  874. }
  875. i->init();
  876. if (oldItem) {
  877. i->moveAfter(oldItem);
  878. }
  879. oldItem = i;
  880. if (!child.nextSibling().isNull()) {
  881. child = child.nextSibling().toElement();
  882. }
  883. else {
  884. break;
  885. }
  886. }
  887. return true;
  888. }
  889. /** Loads bookmarks from a file. */
  890. const bool CBookmarkFolder::loadBookmarks( const TQString& filename ) {
  891. TQFile file(filename);
  892. if (!file.exists())
  893. return false;
  894. TQString xml;
  895. if (file.open(IO_ReadOnly)) {
  896. TQTextStream t;
  897. t.setEncoding(TQTextStream::UnicodeUTF8); //set encoding before file is used for input!
  898. t.setDevice(TQT_TQIODEVICE(&file));
  899. xml = t.read();
  900. file.close();
  901. }
  902. return loadBookmarksFromXML( xml );
  903. }
  904. /* NEW CLASS */
  905. CGlossaryFolder::CGlossaryFolder(CMainIndex* mainIndex, const Type type, const TQString& fromLanguage, const TQString& toLanguage)
  906. : CTreeFolder(mainIndex, type, fromLanguage) {
  907. m_fromLanguage = fromLanguage;
  908. m_toLanguage = toLanguage;
  909. }
  910. CGlossaryFolder::CGlossaryFolder(CFolderBase* item, const Type type, const TQString& fromLanguage, const TQString& toLanguage)
  911. : CTreeFolder(item, type, fromLanguage) {
  912. m_fromLanguage = fromLanguage;
  913. m_toLanguage = toLanguage;
  914. }
  915. CGlossaryFolder::~CGlossaryFolder() {}
  916. void CGlossaryFolder::initTree() {
  917. if (type() == Unknown)
  918. return;
  919. //get all modules by using the lexicon type
  920. ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
  921. ListCSwordModuleInfo usedModules;
  922. // for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
  923. ListCSwordModuleInfo::iterator end_it = allModules.end();
  924. for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
  925. if ((*it)->type() == CSwordModuleInfo::Lexicon) { //found a module, check if the type is correct (devotional etc.)
  926. if ((type() == GlossaryModuleFolder) && ((*it)->category() != CSwordModuleInfo::Glossary)) { //not a glossary
  927. continue;
  928. }
  929. //found a glossary
  930. //ToDo: this is ugly code
  931. if (language() == TQString::fromLatin1("*")
  932. || (language() != TQString::fromLatin1("*")
  933. && (*it)->config(CSwordModuleInfo::GlossaryFrom) == fromLanguage()
  934. && (*it)->config(CSwordModuleInfo::GlossaryTo) == toLanguage()
  935. )
  936. ) { //right type and language!
  937. usedModules.append(*it);
  938. }
  939. }
  940. }
  941. //we have now all modules we want to have
  942. if (language() == TQString::fromLatin1("*")) { //create subfolders for each language
  943. typedef std::pair<TQString, TQString> LanguagePair;
  944. typedef TQValueList<LanguagePair> LanguagePairList;
  945. LanguagePairList usedLangs;
  946. // for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
  947. ListCSwordModuleInfo::iterator end_it = usedModules.end();
  948. for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
  949. LanguagePair langPair(
  950. (*it)->config(CSwordModuleInfo::GlossaryFrom),
  951. (*it)->config(CSwordModuleInfo::GlossaryTo)
  952. );
  953. if (!usedLangs.contains(langPair)) {
  954. usedLangs.append(langPair);
  955. }
  956. }
  957. LanguagePairList::iterator lang_it;
  958. for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
  959. addGroup(type(), (*lang_it).first, (*lang_it).second);
  960. }
  961. }
  962. else if (usedModules.count() > 0) { //create subitems with the given type and languages
  963. // for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
  964. ListCSwordModuleInfo::iterator end_it = usedModules.end();
  965. for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
  966. addModule(*it);
  967. }
  968. }
  969. sortChildItems(0,true);
  970. }
  971. void CGlossaryFolder::init() {
  972. if (language() == "*") {
  973. setText(0,i18n("Glossaries"));
  974. }
  975. else {
  976. const CLanguageMgr::Language* const fromLang = CPointers::languageMgr()->languageForAbbrev( m_fromLanguage );
  977. const CLanguageMgr::Language* const toLang = CPointers::languageMgr()->languageForAbbrev( m_toLanguage );
  978. TQString fromLangString = fromLang->translatedName();
  979. TQString toLangString = toLang->translatedName();
  980. if (fromLangString.isEmpty()) { //use abbrev!
  981. fromLangString = m_fromLanguage;
  982. };
  983. if (toLangString.isEmpty()) { //use abbrev!
  984. toLangString = m_toLanguage;
  985. };
  986. setText(0, fromLangString + " - " + toLangString );
  987. }
  988. initTree();
  989. update();
  990. }
  991. /** Returns the language this glossary folder maps from. */
  992. const TQString& CGlossaryFolder::fromLanguage() const {
  993. return m_fromLanguage;
  994. }
  995. /** Returns the language this glossary folder maps to. */
  996. const TQString& CGlossaryFolder::toLanguage() const {
  997. return m_toLanguage;
  998. }
  999. void CGlossaryFolder::addGroup(const Type type, const TQString& fromLanguage, const TQString& toLanguage) {
  1000. CTreeFolder* i = new CGlossaryFolder(this, type, fromLanguage, toLanguage);
  1001. i->init();
  1002. if (!i->childCount()) {
  1003. delete i;
  1004. }
  1005. }