/********* * * This file is part of BibleTime's source code, http://www.bibletime.info/. * * Copyright 1999-2008 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "btmoduletreeitem.h" #include "backend/drivers/cswordmoduleinfo.h" #include "util/cpointers.h" #include "backend/managers/cswordbackend.h" #include "util/cresmgr.h" #include "util/ctoolclass.h" #include #include #include //This ctor creates the root item and the tree. BTModuleTreeItem::BTModuleTreeItem(QList& filters, BTModuleTreeItem::Grouping grouping, QList* modules) : m_moduleInfo(0), m_firstChild(0), m_next(0), m_type(BTModuleTreeItem::Root), m_category(CSwordModuleInfo::UnknownCategory) { if (modules) { m_originalModuleList = *modules; } else { m_originalModuleList = CPointers::backend()->moduleList(); } //populate the tree with groups/modules create_tree(filters, grouping); } /** * Private constructor which sets the members of the non-root item. This will be the first child of the * parent, the previous firstChild will be the next sibling of this. */ BTModuleTreeItem::BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& text, BTModuleTreeItem::Type type, CSwordModuleInfo* info, CSwordModuleInfo::Category category) : m_moduleInfo(info), m_text(text), m_firstChild(0), m_next(0), m_type(type), m_category(category) { if (info) { m_text = info->name(); m_type = BTModuleTreeItem::Module; } BTModuleTreeItem* tmp = parentItem->m_firstChild; parentItem->m_firstChild = this; if (tmp) this->m_next = tmp; } BTModuleTreeItem::~BTModuleTreeItem() { // this works recursively foreach(BTModuleTreeItem* i, children()) { delete i; } } QList BTModuleTreeItem::children() const { //qDebug("BTModuleTreeItem::children"); QList childList; if (m_firstChild) { BTModuleTreeItem* child = m_firstChild; while (child) { //qDebug() << "child:" << child->text(); childList.append(child); child = child->m_next; } } return childList; } //TODO QString BTModuleTreeItem::iconName() const { if (m_type == Category) { switch ( m_category) { case CSwordModuleInfo::Bibles: return CResMgr::categories::bibles::icon; break; case CSwordModuleInfo::Commentaries: return CResMgr::categories::commentaries::icon; break; case CSwordModuleInfo::Books: return CResMgr::categories::books::icon; break; case CSwordModuleInfo::Cult: return CResMgr::categories::cults::icon; break; case CSwordModuleInfo::Images: return CResMgr::categories::images::icon; break; case CSwordModuleInfo::DailyDevotional: return CResMgr::categories::dailydevotional::icon; break; case CSwordModuleInfo::Lexicons: return CResMgr::categories::lexicons::icon; break; case CSwordModuleInfo::Glossary: return CResMgr::categories::glossary::icon; break; default: break; } } else if (m_type == Module) { return CToolClass::getIconNameForModule(m_moduleInfo); } else if (m_type == Language) { //TODO: don't hardcode here return "flag.svg"; } return QString::null; } void BTModuleTreeItem::create_tree(QList& filters, BTModuleTreeItem::Grouping grouping) { qDebug("BTModuleTreeItem::create_tree"); static bool map_initialized = false; static QMap CategoryNamesMap; if (!map_initialized) { CategoryNamesMap.insert(CSwordModuleInfo::Commentaries, QObject::tr("Commentaries")); CategoryNamesMap.insert(CSwordModuleInfo::Cult, QObject::tr("Cults/Unorthodox")); CategoryNamesMap.insert(CSwordModuleInfo::Images, QObject::tr("Maps and Images")); CategoryNamesMap.insert(CSwordModuleInfo::DailyDevotional, QObject::tr("Daily Devotionals")); CategoryNamesMap.insert(CSwordModuleInfo::Lexicons, QObject::tr("Lexicons and Dictionaries")); CategoryNamesMap.insert(CSwordModuleInfo::Bibles, QObject::tr("Bibles")); CategoryNamesMap.insert(CSwordModuleInfo::Glossary, QObject::tr("Glossaries")); CategoryNamesMap.insert(CSwordModuleInfo::Books, QObject::tr("Books")); map_initialized = true; } //QList originalInfoList = CPointers::backend()->moduleList(); foreach (CSwordModuleInfo* info, m_originalModuleList) { bool included; included = true; foreach (BTModuleTreeItem::Filter* f, filters) { if (!f->filter(info)) { included = false; break; } } if (included) { //qDebug() << "a module will be included: " << info->name(); BTModuleTreeItem* parentGroupForModule = this; BTModuleTreeItem* parentGroupForLanguage = this; BTModuleTreeItem* parentGroupForCategory = this; //the order of if(grouping...) clauses is important if (grouping == BTModuleTreeItem::LangMod || grouping == BTModuleTreeItem::LangCatMod) { BTModuleTreeItem* langItem = create_parent_item(parentGroupForLanguage, info->language()->translatedName(), BTModuleTreeItem::Language); if (grouping == BTModuleTreeItem::LangMod) parentGroupForModule = langItem; else parentGroupForCategory = langItem; } if (grouping == BTModuleTreeItem::CatMod || grouping == BTModuleTreeItem::CatLangMod) { BTModuleTreeItem* catItem = create_parent_item(parentGroupForCategory, CategoryNamesMap.value(info->category()), BTModuleTreeItem::Category, info->category()); if (grouping == BTModuleTreeItem::CatMod) parentGroupForModule = catItem; else parentGroupForLanguage = catItem; } if (grouping == BTModuleTreeItem::CatLangMod) { // category is there already, create language and make it the parent for the module parentGroupForModule = create_parent_item(parentGroupForLanguage, info->language()->translatedName(), BTModuleTreeItem::Language); } if (grouping == BTModuleTreeItem::LangCatMod) { //language is there already, create category and make it the parent for the module parentGroupForModule = create_parent_item(parentGroupForCategory, CategoryNamesMap.value(info->category()), BTModuleTreeItem::Category, info->category()); } // the parent group for module has been set above, now just add the module to it new BTModuleTreeItem(parentGroupForModule, QString::null, BTModuleTreeItem::Module, info); } // end: if (included) } // Finally sort the items sort_children(this); } BTModuleTreeItem* BTModuleTreeItem::create_parent_item( BTModuleTreeItem* parentGroup, const QString& itemText, BTModuleTreeItem::Type type, CSwordModuleInfo::Category category) { BTModuleTreeItem* item = 0; foreach(BTModuleTreeItem* it, parentGroup->children()) { if (it->text() == itemText) { item = it; break; } } if (!item) item = new BTModuleTreeItem(parentGroup, itemText, type, 0, category); return item; } void BTModuleTreeItem::sort_children(BTModuleTreeItem* parent) { //qDebug("BTModuleTreeItem::sort_children"); // sort each child recursively depth-first foreach(BTModuleTreeItem* item, parent->children()) { sort_children(item); } QList items = parent->children(); if (items.size() > 0) { // Sort the list of the children according to each item's text qSort(items.begin(), items.end(), BTModuleTreeItem::localeAwareLessThan); //put the children back to tree in sorted order BTModuleTreeItem* first = items.at(0); BTModuleTreeItem* prev = first; foreach (BTModuleTreeItem* item2, items) { prev->m_next = item2; prev = item2; } prev->m_next = 0; parent->m_firstChild = first; // attach the partial tree to the parent } } bool BTModuleTreeItem::localeAwareLessThan(BTModuleTreeItem* first, BTModuleTreeItem* second) { static bool map_initialized = false; static QMap CategoryNameValueMap; if (!map_initialized) { //this is the sorting order for categories CategoryNameValueMap.insert(QObject::tr("Bibles"), 1); CategoryNameValueMap.insert(QObject::tr("Commentaries"), 2); CategoryNameValueMap.insert(QObject::tr("Books"), 3); CategoryNameValueMap.insert(QObject::tr("Lexicons and Dictionaries"), 4); CategoryNameValueMap.insert(QObject::tr("Glossaries"), 5); CategoryNameValueMap.insert(QObject::tr("Daily Devotionals"), 6); CategoryNameValueMap.insert(QObject::tr("Maps and Images"), 7); CategoryNameValueMap.insert(QObject::tr("Cults/Unorthodox"), 8); map_initialized = true; } //Categories are always in the same order, not alphabetically if (first->type() == BTModuleTreeItem::Category) { return (CategoryNameValueMap.value(first->text()) < CategoryNameValueMap.value(second->text())); } return (QString::localeAwareCompare(first->text(), second->text()) < 0 ); }