3
* This file is part of BibleTime's source code, http://www.bibletime.info/.
5
* Copyright 1999-2006 by the BibleTime developers.
6
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
13
#include "cindexitem.h"
14
#include "cmainindex.h"
16
#include "backend/creferencemanager.h"
17
#include "backend/cswordmoduleinfo.h"
18
#include "backend/cswordkey.h"
19
#include "backend/cswordversekey.h"
20
#include "backend/clanguagemgr.h"
22
#include "frontend/searchdialog/csearchdialog.h"
23
#include "frontend/cexportmanager.h"
24
#include "frontend/cbtconfig.h"
25
#include "frontend/cinputdialog.h"
26
#include "frontend/cexportmanager.h"
27
#include "frontend/cdragdropmgr.h"
28
#include "frontend/cprinter.h"
30
#include "util/cresmgr.h"
31
#include "util/scoped_resource.h"
32
#include "util/ctoolclass.h"
37
#include <qdragobject.h>
38
#include <qstringlist.h>
41
#include <qtextstream.h>
46
#include <kfiledialog.h>
47
#include <kiconloader.h>
48
#include <kstandarddirs.h>
50
#define CURRENT_SYNTAX_VERSION 1
52
using namespace Printing;
55
CItemBase::CItemBase(CMainIndex* mainIndex, const Type type)
56
: KListViewItem(mainIndex),
58
m_sortingEnabled(true) {}
60
CItemBase::CItemBase(CItemBase* parentItem, const Type type)
61
: KListViewItem(parentItem),
63
m_sortingEnabled(true) {}
65
CItemBase::~CItemBase() {}
67
const QString CItemBase::toolTip() {
71
/** Returns the used main index. */
72
CMainIndex* CItemBase::listView() const {
73
return dynamic_cast<CMainIndex*>( QListViewItem::listView() );
76
void CItemBase::init() {
80
void CItemBase::update() {}
82
const CItemBase::Type& CItemBase::type() const {
86
void CItemBase::moveAfter( CItemBase* const item ) {
90
if ( parent() == item->parent() ) { //same parent means level
91
moveItem(item); //both items are on the same level, so we can use moveItem
95
/** Returns true if the given action should be enabled in the popup menu. */
96
const bool CItemBase::enableAction( const MenuAction /*action*/ ) {
97
return false; //this base class has no valif actions
100
/** No descriptions */
101
const bool CItemBase::isMovable() {
105
const bool CItemBase::allowAutoOpen( const QMimeSource* ) const {
109
/** This function engables or disables sorting depending on the parameter. */
110
void CItemBase::setSortingEnabled( const bool& enableSort ) {
111
m_sortingEnabled = enableSort;
114
/** Returns true whether the sorting is enabled or not. */
115
const bool CItemBase::isSortingEnabled() {
116
return m_sortingEnabled;
119
/** Reimplementation which takes care of the our sortingEnabled setting. */
120
void CItemBase::sortChildItems( int col, bool asc ) {
121
if (!isSortingEnabled()) {
125
KListViewItem::sortChildItems( col, asc );
129
/** Reimplementation which takes care of the our sortingEnabled setting. */
130
void CItemBase::sort() {
131
if (!isSortingEnabled()) {
135
KListViewItem::sort();
139
/* ---------------------------------------------- */
140
/* ---------- new class: CModuleItem ------------ */
141
/* ---------------------------------------------- */
143
CModuleItem::CModuleItem(CTreeFolder* parentItem, CSwordModuleInfo* module) : CItemBase(parentItem), m_module(module) {}
145
CModuleItem::~CModuleItem() {}
147
/** No descriptions */
148
void CModuleItem::update() {
150
setPixmap(0, CToolClass::getIconForModule(m_module));
151
setText(0,m_module->name() );
155
void CModuleItem::init() {
156
setDragEnabled(false);
157
setDropEnabled(true);
163
/** 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. */
164
bool CModuleItem::acceptDrop( const QMimeSource* src ) const {
165
if (CDragDropMgr::canDecode(src)) {
166
if (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark) {
167
CDragDropMgr::Item item = CDragDropMgr::decode(src).first();
168
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
169
if (m && (module()->type() == m->type())) { //it makes only sense
172
//but we also allow drops from bibles on commentaries and the other way from commentaries
173
else if (m && (module()->type() == CSwordModuleInfo::Bible) && (m->type() == CSwordModuleInfo::Commentary)) {
176
else if (m && (module()->type() == CSwordModuleInfo::Commentary) && (m->type() == CSwordModuleInfo::Bible)) {
180
else if(CDragDropMgr::dndType(src) == CDragDropMgr::Item::Text) { //text drop on a module
184
return false; //default return value
187
/** No descriptions */
188
void CModuleItem::dropped( QDropEvent* e, QListViewItem* /*after*/) {
189
/* Something was dropped on a module item
191
* 1. If the drop type is plain text open the searchdialog for this text and start the search
192
* 2. If the type is Bookmark, open the module at the specified position
194
* We support only the first drop item, more is not useful
198
CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
199
CDragDropMgr::Item item = dndItems.first();
200
if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Text) { //open the searchdialog
201
// qWarning("Text dropped!");
203
ListCSwordModuleInfo modules;
204
modules.append(module());
206
Search::CSearchDialog::openDialog(modules, item.text());
209
else if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Bookmark) { //open the module
210
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
211
if (m) { //it makes only sense to create a new window for a module with the same type
212
if ((module()->type() == m->type()) ||
213
((module()->type() == CSwordModuleInfo::Bible || module()->type() == CSwordModuleInfo::Commentary)
214
&& (m->type() == CSwordModuleInfo::Bible || m->type() == CSwordModuleInfo::Commentary))) { //same base type of module
215
ListCSwordModuleInfo modules;
216
modules.append(module());
218
listView()->emitModulesChosen(modules, item.bookmarkKey());
226
/** Reimplementation. */
227
const QString CModuleItem::toolTip() {
228
return CToolClass::moduleToolTip(module());
231
/** Returns the used module. */
232
CSwordModuleInfo* const CModuleItem::module() const {
236
/** Reimplementation from CItemBase. */
237
const bool CModuleItem::enableAction( const MenuAction action ) {
238
if (action == EditModule) {
241
return module()->isWritable();
244
if (action == SearchInModules || action == AboutModule)
246
if (module()->isEncrypted() && action == UnlockModule)
251
/* ----------------------------------------------*/
252
/* ---------- new class: CBookmarkItem ------------*/
253
/* ----------------------------------------------*/
255
CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, CSwordModuleInfo* module, const QString& key, const QString& description)
256
: CItemBase(parentItem),
257
m_description(description),
258
m_moduleName(module ? module->name() : QString::null) {
259
if ((module && (module->type() == CSwordModuleInfo::Bible) || (module->type() == CSwordModuleInfo::Commentary)) ) {
260
CSwordVerseKey vk(0);
263
m_key = vk.key(); //the m_key member is always the english key!
269
m_startupXML = QDomElement(); //empty XML code
272
CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, QDomElement& xml )
273
: CItemBase(parentItem),
274
m_key(QString::null),
275
m_description(QString::null),
276
m_moduleName(QString::null) {
280
CBookmarkItem::~CBookmarkItem() {}
282
/** No descriptions */
283
void CBookmarkItem::update() {
284
setMultiLinesEnabled(true);
285
setPixmap(0,SmallIcon(CResMgr::mainIndex::bookmark::icon,16));
287
const QString title = QString::fromLatin1("%1 (%2)")
289
.arg(module() ? module()->name() : i18n("unknown"));
293
void CBookmarkItem::init() {
294
if (!m_startupXML.isNull()) { //we have some XML code to parse
295
loadFromXML(m_startupXML);
299
setDropEnabled(false);
300
setDragEnabled(false);
303
// setSelectable(false);
306
/** Reimplementation. */
307
const QString CBookmarkItem::toolTip() {
309
return QString::null;
312
CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults();
313
filterOptions.footnotes = false;
314
filterOptions.scriptureReferences = false;
315
CPointers::backend()->setFilterOptions(filterOptions);
318
util::scoped_ptr<CSwordKey> k( CSwordKey::createInstance(module()) );
321
const CLanguageMgr::Language* lang = module()->language();
322
CBTConfig::FontSettingsPair fontPair = CBTConfig::get
326
if (fontPair.first) { //use a special font
327
qWarning("using a font, %s", fontPair.second.family().latin1());
328
ret = QString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr><font face=\"%4\" size=\"4\">%5</font>")
330
.arg(module()->name())
332
.arg(fontPair.second.family())
333
.arg(k->renderedText());
336
ret = QString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr>%4")
338
.arg(module()->name())
340
.arg(k->renderedText());
346
/** Returns the used module. */
347
CSwordModuleInfo* const CBookmarkItem::module() {
348
CSwordModuleInfo* const m = CPointers::backend()->findModuleByName(m_moduleName);
353
/** Returns the used key. */
354
const QString CBookmarkItem::key() {
355
const QString englishKeyName = englishKey();
357
return englishKeyName;
360
QString returnKeyName = englishKeyName;
361
if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) {
362
CSwordVerseKey vk(0);
364
vk.setLocale(CPointers::backend()->booknameLanguage().latin1() );
366
returnKeyName = vk.key(); //the returned key is always in the currently set bookname language
369
return returnKeyName;
372
/** Returns the used description. */
373
const QString& CBookmarkItem::description() {
374
return m_description;
377
/** No descriptions */
378
const bool CBookmarkItem::isMovable() {
382
/** Reimplementation to handle the menu entries of the main index. */
383
const bool CBookmarkItem::enableAction(const MenuAction action) {
384
if (action == ChangeBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries)
390
/** Changes this bookmark. */
391
void CBookmarkItem::rename() {
393
const QString newDescription = CInputDialog::getText(i18n("Change description ..."), i18n("Enter a new description for the chosen bookmark."), description(), &ok, listView(), true);
396
m_description = newDescription;
401
/** Reimplementation of CItemBase::saveToXML. */
402
QDomElement CBookmarkItem::saveToXML( QDomDocument& doc ) {
403
QDomElement elem = doc.createElement("Bookmark");
405
elem.setAttribute("key", englishKey());
406
elem.setAttribute("description", description());
407
elem.setAttribute("modulename", m_moduleName);
408
elem.setAttribute("moduledescription", module() ? module()->config(CSwordModuleInfo::Description) : QString::null);
413
void CBookmarkItem::loadFromXML( QDomElement& element ) {
414
if (element.isNull())
417
//find the right module
418
if (element.hasAttribute("modulename")) {
419
//we use the name in all cases, even if the module isn't installed anymore
420
m_moduleName = element.attribute("modulename");
423
if (element.hasAttribute("key")) {
424
m_key = element.attribute("key");
427
if (element.hasAttribute("description")) {
428
m_description = element.attribute("description");
432
/** Returns the english key. */
433
const QString& CBookmarkItem::englishKey() const {
437
/** Reimplementation. Returns false everytime because a bookmarks has not possible drops. */
438
bool CBookmarkItem::acceptDrop(const QMimeSource* /*src*/) const {
442
/****************************************/
443
/***** class: CItemFolder *************/
444
/****************************************/
446
CFolderBase::CFolderBase(CMainIndex* mainIndex, const Type type) : CItemBase(mainIndex, type) {}
448
CFolderBase::CFolderBase(CFolderBase* parentItem, const Type type) : CItemBase(parentItem, type) {}
450
CFolderBase::CFolderBase(CFolderBase* parentFolder, const QString& caption) : CItemBase(parentFolder) {
454
CFolderBase::~CFolderBase() {}
456
const bool CFolderBase::isFolder() {
460
void CFolderBase::update() {
462
if (isOpen() && childCount())
463
setPixmap(0, SmallIcon(CResMgr::mainIndex::openedFolder::icon, 16));
465
setPixmap(0, SmallIcon(CResMgr::mainIndex::closedFolder::icon, 16));
468
void CFolderBase::init() {
470
setDropEnabled(false);
471
setDragEnabled(false);
474
/** No descriptions */
475
void CFolderBase::setOpen( bool open ) {
476
KListViewItem::setOpen(open);
480
/** The function which renames this folder. */
481
void CFolderBase::rename() {
485
/** Creates a new sub folder of this folder. */
486
void CFolderBase::newSubFolder() {
487
if (dynamic_cast<CBookmarkFolder*>(this) || dynamic_cast<Bookmarks::SubFolder*>(this) ) {
488
Bookmarks::SubFolder* f = new Bookmarks::SubFolder(this, i18n("New folder"));
491
listView()->setCurrentItem(f);
492
listView()->ensureItemVisible(f);
497
/** Reimplementation. Returns true if the drop is accepted. */
498
const bool CFolderBase::allowAutoOpen( const QMimeSource* ) const {
502
/** Reimplementation. Returns false because folders have no use for drops (except for the bookmark folders) */
503
bool CFolderBase::acceptDrop(const QMimeSource*) const {
507
QPtrList<QListViewItem> CFolderBase::getChildList() {
508
QPtrList<QListViewItem> childs;
509
if (!childCount()) //no childs available
512
QListViewItem* i = firstChild();
513
while (i && (i->parent() == this)) {
514
CItemBase* item = dynamic_cast<CItemBase*>(i);
515
if (item) { //we found a valid item
518
CFolderBase* folder = dynamic_cast<CFolderBase*>(i);
520
QPtrList<QListViewItem> subChilds = folder->getChildList();
521
for (QListViewItem* ci = subChilds.first(); ci; ci = subChilds.next()) {
528
i = i->nextSibling();
530
while (i && (i->parent() != this));
536
/****************************************/
537
/***** class: CTreeFolder *************/
538
/****************************************/
541
CTreeFolder::CTreeFolder(CMainIndex* mainIndex, const Type type, const QString& language) : CFolderBase(mainIndex, type) {
542
m_language = language;
545
CTreeFolder::CTreeFolder(CFolderBase* item, const Type type, const QString& language) : CFolderBase(item, type) {
546
m_language = language;
549
CTreeFolder::~CTreeFolder() {}
551
void CTreeFolder::addGroup(const Type type, const QString language) {
553
if (type == BookmarkFolder) {
554
i = new CBookmarkFolder(this);
556
else if (type == OldBookmarkFolder) {
557
i = new Bookmarks::OldBookmarksFolder(this);
560
i = new CTreeFolder(this, type, language);
563
if (!i->childCount())
567
void CTreeFolder::addModule(CSwordModuleInfo* const module) {
568
CModuleItem* i = new CModuleItem(this, module);
572
void CTreeFolder::addBookmark(CSwordModuleInfo* module, const QString& key, const QString& description) {
573
CBookmarkItem* i = new CBookmarkItem(this, module, key, description);
577
void CTreeFolder::update() {
578
CFolderBase::update();
581
void CTreeFolder::init() {
582
if (language() == "*") {
584
case BibleModuleFolder:
585
setText(0,i18n("Bibles"));
587
case CommentaryModuleFolder:
588
setText(0,i18n("Commentaries"));
590
case LexiconModuleFolder:
591
setText(0,i18n("Lexicons"));
593
case BookModuleFolder:
594
setText(0,i18n("Books"));
596
case DevotionalModuleFolder:
597
setText(0,i18n("Daily devotionals"));
599
case GlossaryModuleFolder:
600
setText(0,i18n("Glossaries"));
603
setText(0,i18n("Bookmarks"));
605
case OldBookmarkFolder:
606
setText(0,i18n("Old bookmarks"));
609
setText(0, i18n("Unknown"));
614
const CLanguageMgr::Language* const lang = CPointers::languageMgr()->languageForAbbrev( language() );
616
setText(0, !language().isEmpty() ? ( lang->isValid() ? lang->translatedName() : language()) : i18n("Unknown language"));
622
void CTreeFolder::initTree() {
623
// qWarning("CTreeMgr::initTree");
624
if (type() == Unknown)
627
CSwordModuleInfo::ModuleType moduleType = CSwordModuleInfo::Unknown;
628
if (type() == BibleModuleFolder)
629
moduleType = CSwordModuleInfo::Bible;
630
else if (type() == CommentaryModuleFolder)
631
moduleType = CSwordModuleInfo::Commentary;
632
else if (type() == LexiconModuleFolder || type() == GlossaryModuleFolder || type() == DevotionalModuleFolder)
633
moduleType = CSwordModuleInfo::Lexicon;
634
else if (type() == BookModuleFolder)
635
moduleType = CSwordModuleInfo::GenericBook;
637
//get all modules by using the given type
638
ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
639
ListCSwordModuleInfo usedModules;
640
ListCSwordModuleInfo::iterator end_it = allModules.end();
641
for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
642
// for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
643
if ((*it)->type() == moduleType) { //found a module, check if the type is correct (devotional etc.)
644
if (type() == GlossaryModuleFolder && !(*it)->category() == CSwordModuleInfo::Glossary) { //not a gglossary
647
if (type() == DevotionalModuleFolder && ((*it)->category() != CSwordModuleInfo::DailyDevotional)) {//not a devotional
650
if (type() == LexiconModuleFolder && ( ((*it)->category() == CSwordModuleInfo::DailyDevotional) || ((*it)->category() == CSwordModuleInfo::Glossary) )) {
651
//while looking for lexicons glossaries and devotionals shouldn't be used
655
if (language() == QString::fromLatin1("*") || (language() != QString::fromLatin1("*") && QString::fromLatin1((*it)->module()->Lang()) == language()) )//right type and language!
656
usedModules.append(*it);
660
//we have now all modules we want to have
661
if (language() == QString::fromLatin1("*")) { //create subfolders for each language
662
QStringList usedLangs;
663
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
664
/*ListCSwordModuleInfo::iterator*/
665
end_it = usedModules.end();
666
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
667
QString lang = QString::fromLatin1((*it)->module()->Lang());
668
// if (lang.isEmpty())
670
if (!usedLangs.contains(lang)) {
671
usedLangs.append(lang);
675
//ToDo:: Optimize the loop with const itrs
676
QStringList::iterator lang_it;
677
for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
678
addGroup(/**lang_it,*/ type(), *lang_it);
681
else if (usedModules.count() > 0) { //create subitems with the given type and language
682
/*ListCSwordModuleInfo::iterator*/ end_it = usedModules.end();
683
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
684
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
689
sortChildItems(0,true);
692
const QString& CTreeFolder::language() const {
696
/* --------------------------------------------------*/
697
/* ---------- new class: CBookmarkFolder::SubFolder--*/
698
/* --------------------------------------------------*/
700
namespace Bookmarks {
701
/* --------------------------------------------------------------------------*/
702
/* ---------- new class: CBookmarkFolder::OldBookmarkImport -----------------*/
703
/* --------------------------------------------------------------------------*/
704
const QString OldBookmarkImport::oldBookmarksXML( const QString& configFileName ) {
705
QString fileName = (configFileName.isEmpty()) ? "bt-groupmanager" : configFileName;
706
KConfig* config = new KSimpleConfig( fileName );
708
KConfigGroupSaver groupSaver(config, configFileName.isEmpty() ? "Groupmanager" : "Bookmarks");
710
QDomDocument doc("DOC");
711
doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
713
QDomElement content = doc.createElement("SwordBookmarks");
714
content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
715
doc.appendChild(content);
717
//first create the bookmark groups in the XML document, then add the bookmarks to each parent
718
QMap<int, QDomElement> parentMap; //maps parent ids to dom elements
721
QStringList groupList = config->readListEntry("Groups");
722
QValueList<int> parentList = config->readIntListEntry("Group parents");
724
QStringList::Iterator it_groups = groupList.begin();
725
QValueList<int>::Iterator it_parents = parentList.begin();
727
int parentIDCounter = 0;
728
while ( (it_groups != groupList.end()) && (it_parents != parentList.end()) ) {
729
QDomElement parentElement = (*it_parents == -1) ? content : parentMap[*it_parents];
730
if (parentElement.isNull()) {
731
qWarning("EMPTY PARENT FOUND!");
732
parentElement = content;
735
QDomElement elem = doc.createElement("Folder");
736
elem.setAttribute("caption", (*it_groups));
737
parentMap.insert(parentIDCounter, elem);
739
parentElement.appendChild( elem );
747
//groups are now read in, create now the bookmarks
748
parentList = config->readIntListEntry("Bookmark parents");
749
QStringList bookmarkList = config->readListEntry("Bookmarks");
750
QStringList bookmarkModulesList = config->readListEntry("Bookmark modules");
751
QStringList bookmarkDescriptionsList = config->readListEntry("Bookmark descriptions");
753
it_parents = parentList.begin();
754
QStringList::Iterator it_bookmarks = bookmarkList.begin();
755
QStringList::Iterator it_modules = bookmarkModulesList.begin();
756
QStringList::Iterator it_descriptions = bookmarkDescriptionsList.begin();
758
while ( it_bookmarks != bookmarkList.end()
759
&& it_parents != parentList.end()
760
&& it_modules != bookmarkModulesList.end()
762
QDomElement parentElement = ((*it_parents) == -1) ? content : parentMap[(*it_parents)];
763
if (parentElement.isNull()) {
764
qWarning("EMPTY PARENT FOUND!");
765
parentElement = content;
767
QDomElement elem = doc.createElement("Bookmark");
769
elem.setAttribute("key", *it_bookmarks);
770
elem.setAttribute("description", *it_descriptions);
771
elem.setAttribute("modulename", *it_modules);
773
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( *it_modules );
774
elem.setAttribute("moduledescription", m ? m->config(CSwordModuleInfo::Description) : QString::null);
776
parentElement.appendChild( elem );
785
return doc.toString();
788
/********************
789
* New class: OldBookmarkFolder
790
*********************/
792
OldBookmarksFolder::OldBookmarksFolder(CTreeFolder* folder) : CBookmarkFolder(folder, OldBookmarkFolder) {}
794
OldBookmarksFolder::~OldBookmarksFolder() {}
796
/** Reimplementation to handle special bookmark tree. */
797
void OldBookmarksFolder::initTree() {
798
// Import the bookmarks of the previous BibleTime versions
800
( CBTConfig::readOldBookmarks )) { //if we havn't yet loaded the old bookmarks
801
loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML() );
806
QDomElement OldBookmarksFolder::saveToXML( QDomDocument& doc ) {
807
QDomElement elem = doc.createElement("Folder");
808
elem.setAttribute("caption", text(0));
810
// Append the XML nodes of all child items
811
CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
813
if (i->parent() == this) {
814
QDomElement newElem = i->saveToXML( doc );
815
if (!newElem.isNull()) {
816
elem.appendChild( newElem ); //append to this folder
819
i = dynamic_cast<CItemBase*>( i->nextSibling() );
822
// Save to config, that we imported the old bookmarks and that we have them on disk
824
( CBTConfig::readOldBookmarks, true );
829
void OldBookmarksFolder::loadFromXML( QDomElement& /*element*/ ) {
830
//this function is empty because the folder imports the old 1.2 bookmarks from the bt-groupmanager config file
834
// New class SubFolder
836
SubFolder::SubFolder(CFolderBase* parentItem, const QString& caption) : CBookmarkFolder(parentItem, BookmarkFolder) {
837
m_startupXML = QDomElement();
838
setText( 0, caption );
841
SubFolder::SubFolder(CFolderBase* parentItem, QDomElement& xml ) : CBookmarkFolder(parentItem, BookmarkFolder) {
845
SubFolder::~SubFolder() {}
847
void SubFolder::init() {
849
if (!m_startupXML.isNull())
850
loadFromXML(m_startupXML);
852
setDropEnabled(true);
853
setRenameEnabled(0,true);
856
/** Reimplementation from CItemBase. */
857
const bool SubFolder::enableAction(const MenuAction action) {
858
if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks )
861
if (action == ExportBookmarks || action == ImportBookmarks )
862
return true; //not yet implemented
864
if ((action == PrintBookmarks) && childCount()){
865
CPrinter::KeyTree tree;
866
CPrinter::KeyTreeItem::Settings settings;
868
QPtrList<QListViewItem> items = getChildList();
870
//create a tree of keytreeitems using the bookmark hierarchy.
871
for (items.first(); items.current(); items.next()) {
872
CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(items.current());
874
tree.append( new CPrinter::KeyTreeItem( i->key(), i->module(), settings ) );
877
return tree.collectModules().count() > 0;
883
/** Returns the XML code which represents the content of this folder. */
884
QDomElement SubFolder::saveToXML( QDomDocument& doc ) {
886
* Save all subitems (bookmarks and folders) to the XML file.
887
* We get the XML code for the items by calling their own saveToXML implementations.
889
QDomElement elem = doc.createElement("Folder");
890
elem.setAttribute("caption", text(0));
892
//append the XML nodes of all child items
893
CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
895
if (i->parent() == this) {
896
QDomElement newElem = i->saveToXML( doc );
897
if (!newElem.isNull()) {
898
elem.appendChild( newElem ); //append to this folder
901
i = dynamic_cast<CItemBase*>( i->nextSibling() );
906
/** Loads the content of this folder from the XML code passed as argument to this function. */
907
void SubFolder::loadFromXML( QDomElement& elem ) {
908
//get the caption and restore all child items!
909
if (elem.hasAttribute("caption"))
910
setText(0, elem.attribute("caption"));
912
//restore all child items
913
QDomElement child = elem.firstChild().toElement();
914
CItemBase* oldItem = 0;
915
while ( !child.isNull() && child.parentNode() == elem ) {
917
if (child.tagName() == "Folder") {
918
i = new Bookmarks::SubFolder(this, child);
920
else if (child.tagName() == "Bookmark") {
921
i = new CBookmarkItem(this, child);
925
i->moveAfter(oldItem);
928
child = child.nextSibling().toElement();
934
/* --------------------------------------------------*/
935
/* ---------- new class: CBookmarkFolder ------------*/
936
/* --------------------------------------------------*/
938
CBookmarkFolder::CBookmarkFolder(CMainIndex* mainIndex, const Type type) : CTreeFolder(mainIndex, type, "*") {
939
setSortingEnabled(false);
942
CBookmarkFolder::CBookmarkFolder(CFolderBase* parentItem, const Type type) : CTreeFolder(parentItem, type, "*") {
943
setSortingEnabled(false);
946
CBookmarkFolder::~CBookmarkFolder() {}
948
void CBookmarkFolder::initTree() {
949
addGroup(OldBookmarkFolder, "*");
951
KStandardDirs stdDirs;
952
const QString path = stdDirs.saveLocation("data", "bibletime/");
953
if (!path.isEmpty()) {
954
loadBookmarks(path + "bookmarks.xml");
958
/** Reimplementation. */
959
const bool CBookmarkFolder::enableAction(const MenuAction action) {
960
if ((action == NewFolder) || (action == ImportBookmarks))
963
if ((action == ExportBookmarks) && childCount())
966
if ((action == PrintBookmarks) && childCount())
973
void CBookmarkFolder::exportBookmarks() {
974
QString fileName = KFileDialog::getSaveFileName(QString::null, i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Export bookmarks"));
975
if (!fileName.isEmpty()) {
976
saveBookmarks( fileName, false ); //false means we don't want to overwrite the file without asking the user
981
void CBookmarkFolder::importBookmarks() {
982
QString fileName = KFileDialog::getOpenFileName(QString::null, i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Import bookmarks"));
983
if (!fileName.isEmpty()) {
984
//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
985
if ( !loadBookmarks(fileName) ) { //if this failed try to load it as old bookmark file
986
loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML( fileName ) );
991
bool CBookmarkFolder::acceptDrop(const QMimeSource * src) const {
992
// qWarning("bool CBookmarkFolder::acceptDrop(const QMimeSource * src): return%ii", (CDragDropMgr::canDecode(src) && (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark)));
994
return CDragDropMgr::canDecode(src)
995
&& (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark);
998
void CBookmarkFolder::dropped(QDropEvent *e, QListViewItem* after) {
1000
CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
1001
CDragDropMgr::ItemList::Iterator it;
1002
CItemBase* previousItem = dynamic_cast<CItemBase*>(after);
1004
for( it = dndItems.begin(); it != dndItems.end(); ++it) {
1005
CSwordModuleInfo* module = CPointers::backend()->findModuleByName(
1006
(*it).bookmarkModule()
1009
CBookmarkItem* i = new CBookmarkItem(
1012
(*it).bookmarkKey(),
1013
(*it).bookmarkDescription()
1017
i->moveAfter( previousItem );
1026
/** Saves the bookmarks in a file. */
1027
const bool CBookmarkFolder::saveBookmarks( const QString& filename, const bool& forceOverwrite ) {
1028
QDomDocument doc("DOC");
1029
doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
1031
QDomElement content = doc.createElement("SwordBookmarks");
1032
content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
1033
doc.appendChild(content);
1035
//append the XML nodes of all child items
1036
CItemBase* i = dynamic_cast<CItemBase*>( firstChild() );
1038
if (i->parent() == this) { //only one level under this folder
1039
QDomElement newElem = i->saveToXML( doc ); // the cild creates it's own XML code
1040
if (!newElem.isNull()) {
1041
content.appendChild( newElem ); //append to this folder
1044
i = dynamic_cast<CItemBase*>( i->nextSibling() );
1047
return CToolClass::savePlainFile(filename, doc.toString(), forceOverwrite, QTextStream::UnicodeUTF8);
1050
const bool CBookmarkFolder::loadBookmarksFromXML( const QString& xml ) {
1052
doc.setContent(xml);
1053
QDomElement document = doc.documentElement();
1054
if( document.tagName() != "SwordBookmarks" ) {
1055
qWarning("Not a BibleTime Bookmark XML file");
1059
CItemBase* oldItem = 0;
1060
//restore all child items
1061
QDomElement child = document.firstChild().toElement();
1062
while ( !child.isNull() && child.parentNode() == document) {
1064
if (child.tagName() == "Folder") {
1065
i = new Bookmarks::SubFolder(this, child);
1067
else if (child.tagName() == "Bookmark") {
1068
i = new CBookmarkItem(this, child);
1076
i->moveAfter(oldItem);
1080
if (!child.nextSibling().isNull()) {
1081
child = child.nextSibling().toElement();
1090
/** Loads bookmarks from a file. */
1091
const bool CBookmarkFolder::loadBookmarks( const QString& filename ) {
1092
QFile file(filename);
1097
if (file.open(IO_ReadOnly)) {
1099
t.setEncoding(QTextStream::UnicodeUTF8); //set encoding before file is used for input!
1105
return loadBookmarksFromXML( xml );
1110
CGlossaryFolder::CGlossaryFolder(CMainIndex* mainIndex, const Type type, const QString& fromLanguage, const QString& toLanguage)
1111
: CTreeFolder(mainIndex, type, fromLanguage) {
1112
m_fromLanguage = fromLanguage;
1113
m_toLanguage = toLanguage;
1116
CGlossaryFolder::CGlossaryFolder(CFolderBase* item, const Type type, const QString& fromLanguage, const QString& toLanguage)
1117
: CTreeFolder(item, type, fromLanguage) {
1118
m_fromLanguage = fromLanguage;
1119
m_toLanguage = toLanguage;
1122
CGlossaryFolder::~CGlossaryFolder() {}
1124
void CGlossaryFolder::initTree() {
1125
if (type() == Unknown)
1128
//get all modules by using the lexicon type
1129
ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
1130
ListCSwordModuleInfo usedModules;
1131
// for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
1133
ListCSwordModuleInfo::iterator end_it = allModules.end();
1134
for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
1135
if ((*it)->type() == CSwordModuleInfo::Lexicon) { //found a module, check if the type is correct (devotional etc.)
1136
if ((type() == GlossaryModuleFolder) && ((*it)->category() != CSwordModuleInfo::Glossary)) { //not a glossary
1140
//ToDo: this is ugly code
1141
if (language() == QString::fromLatin1("*")
1142
|| (language() != QString::fromLatin1("*")
1143
&& (*it)->config(CSwordModuleInfo::GlossaryFrom) == fromLanguage()
1144
&& (*it)->config(CSwordModuleInfo::GlossaryTo) == toLanguage()
1146
) { //right type and language!
1147
usedModules.append(*it);
1152
//we have now all modules we want to have
1153
if (language() == QString::fromLatin1("*")) { //create subfolders for each language
1154
typedef std::pair<QString, QString> LanguagePair;
1155
typedef QValueList<LanguagePair> LanguagePairList;
1157
LanguagePairList usedLangs;
1158
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
1159
ListCSwordModuleInfo::iterator end_it = usedModules.end();
1160
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
1161
LanguagePair langPair(
1162
(*it)->config(CSwordModuleInfo::GlossaryFrom),
1163
(*it)->config(CSwordModuleInfo::GlossaryTo)
1166
if (!usedLangs.contains(langPair)) {
1167
usedLangs.append(langPair);
1171
LanguagePairList::iterator lang_it;
1172
for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
1173
addGroup(type(), (*lang_it).first, (*lang_it).second);
1176
else if (usedModules.count() > 0) { //create subitems with the given type and languages
1177
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
1178
ListCSwordModuleInfo::iterator end_it = usedModules.end();
1179
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
1184
sortChildItems(0,true);
1187
void CGlossaryFolder::init() {
1188
if (language() == "*") {
1189
setText(0,i18n("Glossaries"));
1192
const CLanguageMgr::Language* const fromLang = CPointers::languageMgr()->languageForAbbrev( m_fromLanguage );
1193
const CLanguageMgr::Language* const toLang = CPointers::languageMgr()->languageForAbbrev( m_toLanguage );
1195
QString fromLangString = fromLang->translatedName();
1196
QString toLangString = toLang->translatedName();
1198
if (fromLangString.isEmpty()) { //use abbrev!
1199
fromLangString = m_fromLanguage;
1201
if (toLangString.isEmpty()) { //use abbrev!
1202
toLangString = m_toLanguage;
1205
setText(0, fromLangString + " - " + toLangString );
1211
/** Returns the language this glossary folder maps from. */
1212
const QString& CGlossaryFolder::fromLanguage() const {
1213
return m_fromLanguage;
1216
/** Returns the language this glossary folder maps to. */
1217
const QString& CGlossaryFolder::toLanguage() const {
1218
return m_toLanguage;
1221
void CGlossaryFolder::addGroup(const Type type, const QString& fromLanguage, const QString& toLanguage) {
1222
CTreeFolder* i = new CGlossaryFolder(this, type, fromLanguage, toLanguage);
1224
if (!i->childCount()) {