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.
bibletime/bibletime/frontend/mainindex/cindexitem.cpp

1229 lines
36 KiB

/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2006 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
//BibleTime includes
#include "cindexitem.h"
#include "cmainindex.h"
#include "backend/creferencemanager.h"
#include "backend/cswordmoduleinfo.h"
#include "backend/cswordkey.h"
#include "backend/cswordversekey.h"
#include "backend/clanguagemgr.h"
#include "frontend/searchdialog/csearchdialog.h"
#include "frontend/cexportmanager.h"
#include "frontend/cbtconfig.h"
#include "frontend/cinputdialog.h"
#include "frontend/cexportmanager.h"
#include "frontend/cdragdropmgr.h"
#include "frontend/cprinter.h"
#include "util/cresmgr.h"
#include "util/scoped_resource.h"
#include "util/ctoolclass.h"
#include <string.h>
//TQt includes
#include <tqdragobject.h>
#include <tqstringlist.h>
#include <tqfile.h>
#include <tqstring.h>
#include <tqtextstream.h>
//KDE includes
#include <tdeconfig.h>
#include <klocale.h>
#include <tdefiledialog.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#define CURRENT_SYNTAX_VERSION 1
using namespace Printing;
using std::string;
CItemBase::CItemBase(CMainIndex* mainIndex, const Type type)
: TDEListViewItem(mainIndex),
m_type(type),
m_sortingEnabled(true) {}
CItemBase::CItemBase(CItemBase* parentItem, const Type type)
: TDEListViewItem(parentItem),
m_type(type),
m_sortingEnabled(true) {}
CItemBase::~CItemBase() {}
const TQString CItemBase::toolTip() {
return TQString();
}
/** Returns the used main index. */
CMainIndex* CItemBase::listView() const {
return dynamic_cast<CMainIndex*>( TQListViewItem::listView() );
}
void CItemBase::init() {
update();
}
void CItemBase::update() {}
const CItemBase::Type& CItemBase::type() const {
return m_type;
};
void CItemBase::moveAfter( CItemBase* const item ) {
if (!item)
return;
if ( parent() == item->parent() ) { //same parent means level
moveItem(item); //both items are on the same level, so we can use moveItem
}
}
/** Returns true if the given action should be enabled in the popup menu. */
const bool CItemBase::enableAction( const MenuAction /*action*/ ) {
return false; //this base class has no valif actions
}
/** No descriptions */
const bool CItemBase::isMovable() {
return false;
}
const bool CItemBase::allowAutoOpen( const TQMimeSource* ) const {
return false;
};
/** This function engables or disables sorting depending on the parameter. */
void CItemBase::setSortingEnabled( const bool& enableSort ) {
m_sortingEnabled = enableSort;
}
/** Returns true whether the sorting is enabled or not. */
const bool CItemBase::isSortingEnabled() {
return m_sortingEnabled;
}
/** Reimplementation which takes care of the our sortingEnabled setting. */
void CItemBase::sortChildItems( int col, bool asc ) {
if (!isSortingEnabled()) {
return;
}
else {
TDEListViewItem::sortChildItems( col, asc );
}
}
/** Reimplementation which takes care of the our sortingEnabled setting. */
void CItemBase::sort() {
if (!isSortingEnabled()) {
return;
}
else {
TDEListViewItem::sort();
}
}
/* ---------------------------------------------- */
/* ---------- new class: CModuleItem ------------ */
/* ---------------------------------------------- */
CModuleItem::CModuleItem(CTreeFolder* parentItem, CSwordModuleInfo* module) : CItemBase(parentItem), m_module(module) {}
CModuleItem::~CModuleItem() {}
/** No descriptions */
void CModuleItem::update() {
if (m_module) {
setPixmap(0, CToolClass::getIconForModule(m_module));
setText(0,m_module->name() );
}
}
void CModuleItem::init() {
setDragEnabled(false);
setDropEnabled(true);
update();
}
/** 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. */
bool CModuleItem::acceptDrop( const TQMimeSource* src ) const {
if (CDragDropMgr::canDecode(src)) {
if (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark) {
CDragDropMgr::Item item = CDragDropMgr::decode(src).first();
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
if (m && (module()->type() == m->type())) { //it makes only sense
return true;
}
//but we also allow drops from bibles on commentaries and the other way from commentaries
else if (m && (module()->type() == CSwordModuleInfo::Bible) && (m->type() == CSwordModuleInfo::Commentary)) {
return true;
}
else if (m && (module()->type() == CSwordModuleInfo::Commentary) && (m->type() == CSwordModuleInfo::Bible)) {
return true;
}
}
else if(CDragDropMgr::dndType(src) == CDragDropMgr::Item::Text) { //text drop on a module
return true;
};
}
return false; //default return value
}
/** No descriptions */
void CModuleItem::dropped( TQDropEvent* e, TQListViewItem* /*after*/) {
/* Something was dropped on a module item
*
* 1. If the drop type is plain text open the searchdialog for this text and start the search
* 2. If the type is Bookmark, open the module at the specified position
*
* We support only the first drop item, more is not useful
*/
if (acceptDrop(e)) {
CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
CDragDropMgr::Item item = dndItems.first();
if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Text) { //open the searchdialog
// tqWarning("Text dropped!");
if ( module() ) {
ListCSwordModuleInfo modules;
modules.append(module());
Search::CSearchDialog::openDialog(modules, item.text());
}
}
else if (CDragDropMgr::dndType(e) == CDragDropMgr::Item::Bookmark) { //open the module
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( item.bookmarkModule() );
if (m) { //it makes only sense to create a new window for a module with the same type
if ((module()->type() == m->type()) ||
((module()->type() == CSwordModuleInfo::Bible || module()->type() == CSwordModuleInfo::Commentary)
&& (m->type() == CSwordModuleInfo::Bible || m->type() == CSwordModuleInfo::Commentary))) { //same base type of module
ListCSwordModuleInfo modules;
modules.append(module());
listView()->emitModulesChosen(modules, item.bookmarkKey());
};
}
}
};
}
/** Reimplementation. */
const TQString CModuleItem::toolTip() {
return CToolClass::moduleToolTip(module());
}
/** Returns the used module. */
CSwordModuleInfo* const CModuleItem::module() const {
return m_module;
}
/** Reimplementation from CItemBase. */
const bool CModuleItem::enableAction( const MenuAction action ) {
if (action == EditModule) {
if (!module())
return false;
return module()->isWritable();
}
if (action == SearchInModules || action == AboutModule)
return true;
if (module()->isEncrypted() && action == UnlockModule)
return true;
return false;
}
/* ----------------------------------------------*/
/* ---------- new class: CBookmarkItem ------------*/
/* ----------------------------------------------*/
CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, CSwordModuleInfo* module, const TQString& key, const TQString& description)
: CItemBase(parentItem),
m_description(description),
m_moduleName(module ? module->name() : TQString()) {
if ((module && (module->type() == CSwordModuleInfo::Bible) || (module->type() == CSwordModuleInfo::Commentary)) ) {
CSwordVerseKey vk(0);
vk = key;
vk.setLocale("en");
m_key = vk.key(); //the m_key member is always the english key!
}
else {
m_key = key;
};
m_startupXML = TQDomElement(); //empty XML code
}
CBookmarkItem::CBookmarkItem(CFolderBase* parentItem, TQDomElement& xml )
: CItemBase(parentItem),
m_key(TQString()),
m_description(TQString()),
m_moduleName(TQString()) {
m_startupXML = xml;
}
CBookmarkItem::~CBookmarkItem() {}
/** No descriptions */
void CBookmarkItem::update() {
setMultiLinesEnabled(true);
setPixmap(0,SmallIcon(CResMgr::mainIndex::bookmark::icon,16));
const TQString title = TQString::fromLatin1("%1 (%2)")
.arg(key())
.arg(module() ? module()->name() : i18n("unknown"));
setText(0, title);
}
void CBookmarkItem::init() {
if (!m_startupXML.isNull()) { //we have some XML code to parse
loadFromXML(m_startupXML);
}
update();
setDropEnabled(false);
setDragEnabled(false);
// if (!module())
// setSelectable(false);
}
/** Reimplementation. */
const TQString CBookmarkItem::toolTip() {
if (!module()) {
return TQString();
}
CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults();
filterOptions.footnotes = false;
filterOptions.scriptureReferences = false;
CPointers::backend()->setFilterOptions(filterOptions);
TQString ret;
util::scoped_ptr<CSwordKey> k( CSwordKey::createInstance(module()) );
k->key(this->key());
const CLanguageMgr::Language* lang = module()->language();
CBTConfig::FontSettingsPair fontPair = CBTConfig::get
(lang);
Q_ASSERT(k.get());
if (fontPair.first) { //use a special font
tqWarning("using a font, %s", TQString(fontPair.second.family()).latin1());
ret = TQString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr><font face=\"%4\" size=\"4\">%5</font>")
.arg(key())
.arg(module()->name())
.arg(description())
.arg(fontPair.second.family())
.arg(k->renderedText());
}
else {
ret = TQString::fromLatin1("<b>%1 (%2)</b><br/><small>%3</small><hr>%4")
.arg(key())
.arg(module()->name())
.arg(description())
.arg(k->renderedText());
}
return ret;
}
/** Returns the used module. */
CSwordModuleInfo* const CBookmarkItem::module() {
CSwordModuleInfo* const m = CPointers::backend()->findModuleByName(m_moduleName);
Q_ASSERT(m);
return m;
}
/** Returns the used key. */
const TQString CBookmarkItem::key() {
const TQString englishKeyName = englishKey();
if (!module()) {
return englishKeyName;
}
TQString returnKeyName = englishKeyName;
if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) {
CSwordVerseKey vk(0);
vk = englishKeyName;
vk.setLocale(CPointers::backend()->booknameLanguage().latin1() );
returnKeyName = vk.key(); //the returned key is always in the currently set bookname language
}
return returnKeyName;
}
/** Returns the used description. */
const TQString& CBookmarkItem::description() {
return m_description;
}
/** No descriptions */
const bool CBookmarkItem::isMovable() {
return true;
}
/** Reimplementation to handle the menu entries of the main index. */
const bool CBookmarkItem::enableAction(const MenuAction action) {
if (action == ChangeBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries)
return true;
return false;
}
/** Changes this bookmark. */
void CBookmarkItem::rename() {
bool ok = false;
const TQString newDescription = CInputDialog::getText(i18n("Change description ..."), i18n("Enter a new description for the chosen bookmark."), description(), &ok, listView(), true);
if (ok) {
m_description = newDescription;
update();
}
}
/** Reimplementation of CItemBase::saveToXML. */
TQDomElement CBookmarkItem::saveToXML( TQDomDocument& doc ) {
TQDomElement elem = doc.createElement("Bookmark");
elem.setAttribute("key", englishKey());
elem.setAttribute("description", description());
elem.setAttribute("modulename", m_moduleName);
elem.setAttribute("moduledescription", module() ? module()->config(CSwordModuleInfo::Description) : TQString());
return elem;
}
void CBookmarkItem::loadFromXML( TQDomElement& element ) {
if (element.isNull())
return;
//find the right module
if (element.hasAttribute("modulename")) {
//we use the name in all cases, even if the module isn't installed anymore
m_moduleName = element.attribute("modulename");
}
if (element.hasAttribute("key")) {
m_key = element.attribute("key");
}
if (element.hasAttribute("description")) {
m_description = element.attribute("description");
}
}
/** Returns the english key. */
const TQString& CBookmarkItem::englishKey() const {
return m_key;
}
/** Reimplementation. Returns false everytime because a bookmarks has not possible drops. */
bool CBookmarkItem::acceptDrop(const TQMimeSource* /*src*/) const {
return false;
}
/****************************************/
/***** class: CItemFolder *************/
/****************************************/
CFolderBase::CFolderBase(CMainIndex* mainIndex, const Type type) : CItemBase(mainIndex, type) {}
CFolderBase::CFolderBase(CFolderBase* parentItem, const Type type) : CItemBase(parentItem, type) {}
CFolderBase::CFolderBase(CFolderBase* parentFolder, const TQString& caption) : CItemBase(parentFolder) {
setText(0, caption);
}
CFolderBase::~CFolderBase() {}
const bool CFolderBase::isFolder() {
return true;
}
void CFolderBase::update() {
CItemBase::update();
if (isOpen() && childCount())
setPixmap(0, SmallIcon(CResMgr::mainIndex::openedFolder::icon, 16));
else
setPixmap(0, SmallIcon(CResMgr::mainIndex::closedFolder::icon, 16));
}
void CFolderBase::init() {
CItemBase::init();
setDropEnabled(false);
setDragEnabled(false);
}
/** No descriptions */
void CFolderBase::setOpen( bool open ) {
TDEListViewItem::setOpen(open);
update();
}
/** The function which renames this folder. */
void CFolderBase::rename() {
startRename(0);
}
/** Creates a new sub folder of this folder. */
void CFolderBase::newSubFolder() {
if (dynamic_cast<CBookmarkFolder*>(this) || dynamic_cast<Bookmarks::SubFolder*>(this) ) {
Bookmarks::SubFolder* f = new Bookmarks::SubFolder(this, i18n("New folder"));
f->init();
listView()->setCurrentItem(f);
listView()->ensureItemVisible(f);
f->rename();
}
}
/** Reimplementation. Returns true if the drop is accepted. */
const bool CFolderBase::allowAutoOpen( const TQMimeSource* ) const {
return true;
}
/** Reimplementation. Returns false because folders have no use for drops (except for the bookmark folders) */
bool CFolderBase::acceptDrop(const TQMimeSource*) const {
return false;
}
TQPtrList<TQListViewItem> CFolderBase::getChildList() {
TQPtrList<TQListViewItem> childs;
if (!childCount()) //no childs available
return childs;
TQListViewItem* i = firstChild();
while (i && (i->parent() == this)) {
CItemBase* item = dynamic_cast<CItemBase*>(i);
if (item) { //we found a valid item
childs.append(item);
CFolderBase* folder = dynamic_cast<CFolderBase*>(i);
if (folder) {
TQPtrList<TQListViewItem> subChilds = folder->getChildList();
for (TQListViewItem* ci = subChilds.first(); ci; ci = subChilds.next()) {
childs.append(ci);
}
}
}
do {
i = i->nextSibling();
}
while (i && (i->parent() != this));
}
return childs;
}
/****************************************/
/***** class: CTreeFolder *************/
/****************************************/
CTreeFolder::CTreeFolder(CMainIndex* mainIndex, const Type type, const TQString& language) : CFolderBase(mainIndex, type) {
m_language = language;
}
CTreeFolder::CTreeFolder(CFolderBase* item, const Type type, const TQString& language) : CFolderBase(item, type) {
m_language = language;
}
CTreeFolder::~CTreeFolder() {}
void CTreeFolder::addGroup(const Type type, const TQString language) {
CTreeFolder* i = 0;
if (type == BookmarkFolder) {
i = new CBookmarkFolder(this);
}
else if (type == OldBookmarkFolder) {
i = new Bookmarks::OldBookmarksFolder(this);
}
else {
i = new CTreeFolder(this, type, language);
}
i->init();
if (!i->childCount())
delete i;
}
void CTreeFolder::addModule(CSwordModuleInfo* const module) {
CModuleItem* i = new CModuleItem(this, module);
i->init();
}
void CTreeFolder::addBookmark(CSwordModuleInfo* module, const TQString& key, const TQString& description) {
CBookmarkItem* i = new CBookmarkItem(this, module, key, description);
i->init();
}
void CTreeFolder::update() {
CFolderBase::update();
}
void CTreeFolder::init() {
if (language() == "*") {
switch (type()) {
case BibleModuleFolder:
setText(0,i18n("Bibles"));
break;
case CommentaryModuleFolder:
setText(0,i18n("Commentaries"));
break;
case LexiconModuleFolder:
setText(0,i18n("Lexicons"));
break;
case BookModuleFolder:
setText(0,i18n("Books"));
break;
case DevotionalModuleFolder:
setText(0,i18n("Daily devotionals"));
break;
case GlossaryModuleFolder:
setText(0,i18n("Glossaries"));
break;
case BookmarkFolder:
setText(0,i18n("Bookmarks"));
break;
case OldBookmarkFolder:
setText(0,i18n("Old bookmarks"));
break;
default:
setText(0, i18n("Unknown"));
break;
};
}
else {
const CLanguageMgr::Language* const lang = CPointers::languageMgr()->languageForAbbrev( language() );
setText(0, !language().isEmpty() ? ( lang->isValid() ? lang->translatedName() : language()) : i18n("Unknown language"));
}
initTree();
update();
}
void CTreeFolder::initTree() {
// tqWarning("CTreeMgr::initTree");
if (type() == Unknown)
return;
CSwordModuleInfo::ModuleType moduleType = CSwordModuleInfo::Unknown;
if (type() == BibleModuleFolder)
moduleType = CSwordModuleInfo::Bible;
else if (type() == CommentaryModuleFolder)
moduleType = CSwordModuleInfo::Commentary;
else if (type() == LexiconModuleFolder || type() == GlossaryModuleFolder || type() == DevotionalModuleFolder)
moduleType = CSwordModuleInfo::Lexicon;
else if (type() == BookModuleFolder)
moduleType = CSwordModuleInfo::GenericBook;
//get all modules by using the given type
ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
ListCSwordModuleInfo usedModules;
ListCSwordModuleInfo::iterator end_it = allModules.end();
for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
// for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
if ((*it)->type() == moduleType) { //found a module, check if the type is correct (devotional etc.)
if (type() == GlossaryModuleFolder && !(*it)->category() == CSwordModuleInfo::Glossary) { //not a gglossary
continue;
}
if (type() == DevotionalModuleFolder && ((*it)->category() != CSwordModuleInfo::DailyDevotional)) {//not a devotional
continue;
}
if (type() == LexiconModuleFolder && ( ((*it)->category() == CSwordModuleInfo::DailyDevotional) || ((*it)->category() == CSwordModuleInfo::Glossary) )) {
//while looking for lexicons glossaries and devotionals shouldn't be used
continue;
}
if (language() == TQString::fromLatin1("*") || (language() != TQString::fromLatin1("*") && TQString::fromLatin1((*it)->module()->Lang()) == language()) )//right type and language!
usedModules.append(*it);
}
}
//we have now all modules we want to have
if (language() == TQString::fromLatin1("*")) { //create subfolders for each language
TQStringList usedLangs;
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
/*ListCSwordModuleInfo::iterator*/
end_it = usedModules.end();
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
TQString lang = TQString::fromLatin1((*it)->module()->Lang());
// if (lang.isEmpty())
// lang = ");
if (!usedLangs.contains(lang)) {
usedLangs.append(lang);
}
}
//ToDo:: Optimize the loop with const itrs
TQStringList::iterator lang_it;
for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
addGroup(/**lang_it,*/ type(), *lang_it);
}
}
else if (usedModules.count() > 0) { //create subitems with the given type and language
/*ListCSwordModuleInfo::iterator*/ end_it = usedModules.end();
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
addModule(*it);
}
}
sortChildItems(0,true);
}
const TQString& CTreeFolder::language() const {
return m_language;
};
/* --------------------------------------------------*/
/* ---------- new class: CBookmarkFolder::SubFolder--*/
/* --------------------------------------------------*/
namespace Bookmarks {
/* --------------------------------------------------------------------------*/
/* ---------- new class: CBookmarkFolder::OldBookmarkImport -----------------*/
/* --------------------------------------------------------------------------*/
const TQString OldBookmarkImport::oldBookmarksXML( const TQString& configFileName ) {
TQString fileName = (configFileName.isEmpty()) ? "bt-groupmanager" : configFileName;
TDEConfig* config = new KSimpleConfig( fileName );
TDEConfigGroupSaver groupSaver(config, configFileName.isEmpty() ? "Groupmanager" : "Bookmarks");
TQDomDocument doc("DOC");
doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement content = doc.createElement("SwordBookmarks");
content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
doc.appendChild(content);
//first create the bookmark groups in the XML document, then add the bookmarks to each parent
TQMap<int, TQDomElement> parentMap; //maps parent ids to dom elements
TQStringList groupList = config->readListEntry("Groups");
TQValueList<int> parentList = config->readIntListEntry("Group parents");
TQStringList::Iterator it_groups = groupList.begin();
TQValueList<int>::Iterator it_parents = parentList.begin();
int parentIDCounter = 0;
while ( (it_groups != groupList.end()) && (it_parents != parentList.end()) ) {
TQDomElement parentElement = (*it_parents == -1) ? content : parentMap[*it_parents];
if (parentElement.isNull()) {
tqWarning("EMPTY PARENT FOUND!");
parentElement = content;
};
TQDomElement elem = doc.createElement("Folder");
elem.setAttribute("caption", (*it_groups));
parentMap.insert(parentIDCounter, elem);
parentElement.appendChild( elem );
++it_parents;
++it_groups;
++parentIDCounter;
}
//groups are now read in, create now the bookmarks
parentList = config->readIntListEntry("Bookmark parents");
TQStringList bookmarkList = config->readListEntry("Bookmarks");
TQStringList bookmarkModulesList = config->readListEntry("Bookmark modules");
TQStringList bookmarkDescriptionsList = config->readListEntry("Bookmark descriptions");
it_parents = parentList.begin();
TQStringList::Iterator it_bookmarks = bookmarkList.begin();
TQStringList::Iterator it_modules = bookmarkModulesList.begin();
TQStringList::Iterator it_descriptions = bookmarkDescriptionsList.begin();
while ( it_bookmarks != bookmarkList.end()
&& it_parents != parentList.end()
&& it_modules != bookmarkModulesList.end()
) {
TQDomElement parentElement = ((*it_parents) == -1) ? content : parentMap[(*it_parents)];
if (parentElement.isNull()) {
tqWarning("EMPTY PARENT FOUND!");
parentElement = content;
};
TQDomElement elem = doc.createElement("Bookmark");
elem.setAttribute("key", *it_bookmarks);
elem.setAttribute("description", *it_descriptions);
elem.setAttribute("modulename", *it_modules);
CSwordModuleInfo* m = CPointers::backend()->findModuleByName( *it_modules );
elem.setAttribute("moduledescription", m ? m->config(CSwordModuleInfo::Description) : TQString());
parentElement.appendChild( elem );
++it_parents;
++it_modules;
++it_descriptions;
++it_bookmarks;
};
return doc.toString();
};
/********************
* New class: OldBookmarkFolder
*********************/
OldBookmarksFolder::OldBookmarksFolder(CTreeFolder* folder) : CBookmarkFolder(folder, OldBookmarkFolder) {}
OldBookmarksFolder::~OldBookmarksFolder() {}
/** Reimplementation to handle special bookmark tree. */
void OldBookmarksFolder::initTree() {
// Import the bookmarks of the previous BibleTime versions
if (!CBTConfig::get
( CBTConfig::readOldBookmarks )) { //if we havn't yet loaded the old bookmarks
loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML() );
}
}
TQDomElement OldBookmarksFolder::saveToXML( TQDomDocument& doc ) {
TQDomElement elem = doc.createElement("Folder");
elem.setAttribute("caption", text(0));
// Append the XML nodes of all child items
CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
while( i ) {
if (i->parent() == this) {
TQDomElement newElem = i->saveToXML( doc );
if (!newElem.isNull()) {
elem.appendChild( newElem ); //append to this folder
}
}
i = dynamic_cast<CItemBase*>( i->nextSibling() );
}
// Save to config, that we imported the old bookmarks and that we have them on disk
CBTConfig::set
( CBTConfig::readOldBookmarks, true );
return elem;
}
void OldBookmarksFolder::loadFromXML( TQDomElement& /*element*/ ) {
//this function is empty because the folder imports the old 1.2 bookmarks from the bt-groupmanager config file
}
// New class SubFolder
SubFolder::SubFolder(CFolderBase* parentItem, const TQString& caption) : CBookmarkFolder(parentItem, BookmarkFolder) {
m_startupXML = TQDomElement();
setText( 0, caption );
}
SubFolder::SubFolder(CFolderBase* parentItem, TQDomElement& xml ) : CBookmarkFolder(parentItem, BookmarkFolder) {
m_startupXML = xml;
}
SubFolder::~SubFolder() {}
void SubFolder::init() {
CFolderBase::init();
if (!m_startupXML.isNull())
loadFromXML(m_startupXML);
setDropEnabled(true);
setRenameEnabled(0,true);
}
/** Reimplementation from CItemBase. */
const bool SubFolder::enableAction(const MenuAction action) {
if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks )
return true;
if (action == ExportBookmarks || action == ImportBookmarks )
return true; //not yet implemented
if ((action == PrintBookmarks) && childCount()){
CPrinter::KeyTree tree;
CPrinter::KeyTreeItem::Settings settings;
TQPtrList<TQListViewItem> items = getChildList();
//create a tree of keytreeitems using the bookmark hierarchy.
for (items.first(); items.current(); items.next()) {
CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(items.current());
if (i) {
tree.append( new CPrinter::KeyTreeItem( i->key(), i->module(), settings ) );
}
}
return tree.collectModules().count() > 0;
}
return false;
}
/** Returns the XML code which represents the content of this folder. */
TQDomElement SubFolder::saveToXML( TQDomDocument& doc ) {
/**
* Save all subitems (bookmarks and folders) to the XML file.
* We get the XML code for the items by calling their own saveToXML implementations.
*/
TQDomElement elem = doc.createElement("Folder");
elem.setAttribute("caption", text(0));
//append the XML nodes of all child items
CItemBase* i = dynamic_cast<CItemBase*>(firstChild());
while( i ) {
if (i->parent() == this) {
TQDomElement newElem = i->saveToXML( doc );
if (!newElem.isNull()) {
elem.appendChild( newElem ); //append to this folder
}
}
i = dynamic_cast<CItemBase*>( i->nextSibling() );
}
return elem;
}
/** Loads the content of this folder from the XML code passed as argument to this function. */
void SubFolder::loadFromXML( TQDomElement& elem ) {
//get the caption and restore all child items!
if (elem.hasAttribute("caption"))
setText(0, elem.attribute("caption"));
//restore all child items
TQDomElement child = elem.firstChild().toElement();
CItemBase* oldItem = 0;
while ( !child.isNull() && child.parentNode() == elem ) {
CItemBase* i = 0;
if (child.tagName() == "Folder") {
i = new Bookmarks::SubFolder(this, child);
}
else if (child.tagName() == "Bookmark") {
i = new CBookmarkItem(this, child);
}
i->init();
if (oldItem)
i->moveAfter(oldItem);
oldItem = i;
child = child.nextSibling().toElement();
}
}
};
/* --------------------------------------------------*/
/* ---------- new class: CBookmarkFolder ------------*/
/* --------------------------------------------------*/
CBookmarkFolder::CBookmarkFolder(CMainIndex* mainIndex, const Type type) : CTreeFolder(mainIndex, type, "*") {
setSortingEnabled(false);
}
CBookmarkFolder::CBookmarkFolder(CFolderBase* parentItem, const Type type) : CTreeFolder(parentItem, type, "*") {
setSortingEnabled(false);
}
CBookmarkFolder::~CBookmarkFolder() {}
void CBookmarkFolder::initTree() {
addGroup(OldBookmarkFolder, "*");
TDEStandardDirs stdDirs;
const TQString path = stdDirs.saveLocation("data", "bibletime/");
if (!path.isEmpty()) {
loadBookmarks(path + "bookmarks.xml");
}
}
/** Reimplementation. */
const bool CBookmarkFolder::enableAction(const MenuAction action) {
if ((action == NewFolder) || (action == ImportBookmarks))
return true;
if ((action == ExportBookmarks) && childCount())
return true;
if ((action == PrintBookmarks) && childCount())
return true;
return false;
}
void CBookmarkFolder::exportBookmarks() {
TQString fileName = KFileDialog::getSaveFileName(TQString(), i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Export bookmarks"));
if (!fileName.isEmpty()) {
saveBookmarks( fileName, false ); //false means we don't want to overwrite the file without asking the user
};
}
void CBookmarkFolder::importBookmarks() {
TQString fileName = KFileDialog::getOpenFileName(TQString(), i18n("*.btb | BibleTime bookmark files (*.btb)\n*.* | All files (*.*)"), 0, i18n("BibleTime - Import bookmarks"));
if (!fileName.isEmpty()) {
//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
if ( !loadBookmarks(fileName) ) { //if this failed try to load it as old bookmark file
loadBookmarksFromXML( Bookmarks::OldBookmarkImport::oldBookmarksXML( fileName ) );
};
};
}
bool CBookmarkFolder::acceptDrop(const TQMimeSource * src) const {
// tqWarning("bool CBookmarkFolder::acceptDrop(const TQMimeSource * src): return%ii", (CDragDropMgr::canDecode(src) && (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark)));
return CDragDropMgr::canDecode(src)
&& (CDragDropMgr::dndType(src) == CDragDropMgr::Item::Bookmark);
}
void CBookmarkFolder::dropped(TQDropEvent *e, TQListViewItem* after) {
if (acceptDrop(e)) {
CDragDropMgr::ItemList dndItems = CDragDropMgr::decode(e);
CDragDropMgr::ItemList::Iterator it;
CItemBase* previousItem = dynamic_cast<CItemBase*>(after);
for( it = dndItems.begin(); it != dndItems.end(); ++it) {
CSwordModuleInfo* module = CPointers::backend()->findModuleByName(
(*it).bookmarkModule()
);
CBookmarkItem* i = new CBookmarkItem(
this,
module,
(*it).bookmarkKey(),
(*it).bookmarkDescription()
);
if (previousItem) {
i->moveAfter( previousItem );
}
i->init();
previousItem = i;
};
};
}
/** Saves the bookmarks in a file. */
const bool CBookmarkFolder::saveBookmarks( const TQString& filename, const bool& forceOverwrite ) {
TQDomDocument doc("DOC");
doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement content = doc.createElement("SwordBookmarks");
content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION);
doc.appendChild(content);
//append the XML nodes of all child items
CItemBase* i = dynamic_cast<CItemBase*>( firstChild() );
while( i ) {
if (i->parent() == this) { //only one level under this folder
TQDomElement newElem = i->saveToXML( doc ); // the cild creates it's own XML code
if (!newElem.isNull()) {
content.appendChild( newElem ); //append to this folder
}
}
i = dynamic_cast<CItemBase*>( i->nextSibling() );
}
return CToolClass::savePlainFile(filename, doc.toString(), forceOverwrite, TQTextStream::UnicodeUTF8);
}
const bool CBookmarkFolder::loadBookmarksFromXML( const TQString& xml ) {
TQDomDocument doc;
doc.setContent(xml);
TQDomElement document = doc.documentElement();
if( document.tagName() != "SwordBookmarks" ) {
tqWarning("Not a BibleTime Bookmark XML file");
return false;
}
CItemBase* oldItem = 0;
//restore all child items
TQDomElement child = document.firstChild().toElement();
while ( !child.isNull() && child.parentNode() == document) {
CItemBase* i = 0;
if (child.tagName() == "Folder") {
i = new Bookmarks::SubFolder(this, child);
}
else if (child.tagName() == "Bookmark") {
i = new CBookmarkItem(this, child);
}
if (!i) {
break;
}
i->init();
if (oldItem) {
i->moveAfter(oldItem);
}
oldItem = i;
if (!child.nextSibling().isNull()) {
child = child.nextSibling().toElement();
}
else {
break;
}
}
return true;
}
/** Loads bookmarks from a file. */
const bool CBookmarkFolder::loadBookmarks( const TQString& filename ) {
TQFile file(filename);
if (!file.exists())
return false;
TQString xml;
if (file.open(IO_ReadOnly)) {
TQTextStream t;
t.setEncoding(TQTextStream::UnicodeUTF8); //set encoding before file is used for input!
t.setDevice(TQT_TQIODEVICE(&file));
xml = t.read();
file.close();
}
return loadBookmarksFromXML( xml );
}
/* NEW CLASS */
CGlossaryFolder::CGlossaryFolder(CMainIndex* mainIndex, const Type type, const TQString& fromLanguage, const TQString& toLanguage)
: CTreeFolder(mainIndex, type, fromLanguage) {
m_fromLanguage = fromLanguage;
m_toLanguage = toLanguage;
}
CGlossaryFolder::CGlossaryFolder(CFolderBase* item, const Type type, const TQString& fromLanguage, const TQString& toLanguage)
: CTreeFolder(item, type, fromLanguage) {
m_fromLanguage = fromLanguage;
m_toLanguage = toLanguage;
}
CGlossaryFolder::~CGlossaryFolder() {}
void CGlossaryFolder::initTree() {
if (type() == Unknown)
return;
//get all modules by using the lexicon type
ListCSwordModuleInfo allModules =CPointers::backend()->moduleList();
ListCSwordModuleInfo usedModules;
// for (CSwordModuleInfo* m = allModules.first(); m; m = allModules.next()) {
ListCSwordModuleInfo::iterator end_it = allModules.end();
for (ListCSwordModuleInfo::iterator it(allModules.begin()); it != end_it; ++it) {
if ((*it)->type() == CSwordModuleInfo::Lexicon) { //found a module, check if the type is correct (devotional etc.)
if ((type() == GlossaryModuleFolder) && ((*it)->category() != CSwordModuleInfo::Glossary)) { //not a glossary
continue;
}
//found a glossary
//ToDo: this is ugly code
if (language() == TQString::fromLatin1("*")
|| (language() != TQString::fromLatin1("*")
&& (*it)->config(CSwordModuleInfo::GlossaryFrom) == fromLanguage()
&& (*it)->config(CSwordModuleInfo::GlossaryTo) == toLanguage()
)
) { //right type and language!
usedModules.append(*it);
}
}
}
//we have now all modules we want to have
if (language() == TQString::fromLatin1("*")) { //create subfolders for each language
typedef std::pair<TQString, TQString> LanguagePair;
typedef TQValueList<LanguagePair> LanguagePairList;
LanguagePairList usedLangs;
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
ListCSwordModuleInfo::iterator end_it = usedModules.end();
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
LanguagePair langPair(
(*it)->config(CSwordModuleInfo::GlossaryFrom),
(*it)->config(CSwordModuleInfo::GlossaryTo)
);
if (!usedLangs.contains(langPair)) {
usedLangs.append(langPair);
}
}
LanguagePairList::iterator lang_it;
for (lang_it = usedLangs.begin(); lang_it != usedLangs.end(); ++lang_it) {
addGroup(type(), (*lang_it).first, (*lang_it).second);
}
}
else if (usedModules.count() > 0) { //create subitems with the given type and languages
// for (CSwordModuleInfo* m = usedModules.first(); m; m = usedModules.next()) {
ListCSwordModuleInfo::iterator end_it = usedModules.end();
for (ListCSwordModuleInfo::iterator it(usedModules.begin()); it != end_it; ++it) {
addModule(*it);
}
}
sortChildItems(0,true);
}
void CGlossaryFolder::init() {
if (language() == "*") {
setText(0,i18n("Glossaries"));
}
else {
const CLanguageMgr::Language* const fromLang = CPointers::languageMgr()->languageForAbbrev( m_fromLanguage );
const CLanguageMgr::Language* const toLang = CPointers::languageMgr()->languageForAbbrev( m_toLanguage );
TQString fromLangString = fromLang->translatedName();
TQString toLangString = toLang->translatedName();
if (fromLangString.isEmpty()) { //use abbrev!
fromLangString = m_fromLanguage;
};
if (toLangString.isEmpty()) { //use abbrev!
toLangString = m_toLanguage;
};
setText(0, fromLangString + " - " + toLangString );
}
initTree();
update();
}
/** Returns the language this glossary folder maps from. */
const TQString& CGlossaryFolder::fromLanguage() const {
return m_fromLanguage;
}
/** Returns the language this glossary folder maps to. */
const TQString& CGlossaryFolder::toLanguage() const {
return m_toLanguage;
}
void CGlossaryFolder::addGroup(const Type type, const TQString& fromLanguage, const TQString& toLanguage) {
CTreeFolder* i = new CGlossaryFolder(this, type, fromLanguage, toLanguage);
i->init();
if (!i->childCount()) {
delete i;
}
}