summaryrefslogtreecommitdiff
path: root/src/backend/drivers/cswordmoduleinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/drivers/cswordmoduleinfo.cpp')
-rw-r--r--src/backend/drivers/cswordmoduleinfo.cpp924
1 files changed, 454 insertions, 470 deletions
diff --git a/src/backend/drivers/cswordmoduleinfo.cpp b/src/backend/drivers/cswordmoduleinfo.cpp
index 08721c9..f86f9ac 100644
--- a/src/backend/drivers/cswordmoduleinfo.cpp
+++ b/src/backend/drivers/cswordmoduleinfo.cpp
@@ -2,35 +2,37 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2011 by the BibleTime developers.
+* Copyright 1999-2014 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
#include "backend/drivers/cswordmoduleinfo.h"
-#include <QSharedPointer>
#include <CLucene.h>
#include <QByteArray>
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
-#include <QList>
-#include <QRegExp>
#include <QSettings>
-#include "backend/config/cbtconfig.h"
+#include <QSharedPointer>
+#include <QTextDocument>
+#include "backend/config/btconfig.h"
#include "backend/drivers/cswordlexiconmoduleinfo.h"
#include "backend/keys/cswordkey.h"
#include "backend/managers/clanguagemgr.h"
#include "backend/managers/cswordbackend.h"
#include "backend/rendering/centrydisplay.h"
#include "backend/cswordmodulesearch.h"
+#include "bibletimeapp.h"
#include "btglobal.h"
+#include "frontend/messagedialog.h"
#include "util/cresmgr.h"
#include "util/directory.h"
#include "util/exceptions.h"
-#include "util/dialogutil.h"
+#include "util/geticon.h"
+#include "util/htmlescape.h"
// Sword includes:
#include <listkey.h>
@@ -41,29 +43,6 @@
#include <versekey.h>
-#if 0
-namespace {
-
-/** HELPER Method to dump all current EntryAttributes of a module. */
-void dumpEntryAttributes(sword::SWModule *m) {
- qDebug() << "Attributes for key: " << m->getKeyText();
- sword::AttributeTypeList::iterator i1;
- sword::AttributeList::iterator i2;
- sword::AttributeValue::iterator i3;
- for (i1 = m->getEntryAttributes().begin(); i1 != m->getEntryAttributes().end(); i1++) {
- qDebug() << "[ " << i1->first << " ]";
- for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) {
- qDebug() << "\t[ " << i2->first << " ]";
- for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) {
- qDebug() << "\t\t" << i3->first << " = " << i3->second;
- }
- }
- }
-}
-
-} // anonymous namespace
-#endif
-
//Increment this, if the index format changes
//Then indices on the user's systems will be rebuilt
const unsigned int INDEX_VERSION = 7;
@@ -72,72 +51,74 @@ const unsigned int INDEX_VERSION = 7;
//Lucene default is too small
const unsigned long BT_MAX_LUCENE_FIELD_LENGTH = 1024 * 1024;
-CSwordModuleInfo::CSwordModuleInfo(sword::SWModule *module,
- CSwordBackend * const usedBackend,
+CSwordModuleInfo::CSwordModuleInfo(sword::SWModule * module,
+ CSwordBackend & backend,
ModuleType type)
- : m_module(module),
- m_backend(usedBackend ? usedBackend : CSwordBackend::instance()),
+ : m_module((Q_ASSERT(module), module)),
+ m_backend(backend),
m_type(type),
m_cancelIndexing(false),
- m_cachedName(QString::fromUtf8(module->Name())),
- m_cachedHasVersion(!QString((*m_backend->getConfig())[module->Name()]["Version"]).isEmpty())
+ m_cachedName(QString::fromUtf8(module->getName())),
+ m_cachedHasVersion(!QString((*m_backend.getConfig())[module->getName()]["Version"]).isEmpty())
{
- Q_ASSERT(module != 0);
- Q_ASSERT(usedBackend != 0);
-
initCachedCategory();
initCachedLanguage();
- m_hidden = CBTConfig::get(CBTConfig::hiddenModules).contains(name());
-
- if (backend()) {
- if (hasVersion() && (minimumSwordVersion() > sword::SWVersion::currentVersion)) {
- qWarning("The module \"%s\" requires a newer Sword library. Please update to \"Sword %s\".",
- name().toUtf8().constData(), (const char *)minimumSwordVersion());
-
- /// \todo if this is the case, can we use the module at all?
- }
- }
-}
+ m_hidden = btConfig().value<QStringList>("state/hiddenModules",
+ QStringList()).contains(m_cachedName);
-CSwordModuleInfo::CSwordModuleInfo(const CSwordModuleInfo &o)
- : QObject(0), m_module(o.m_module), m_backend(o.m_backend),
- m_type(o.m_type), m_hidden(o.m_hidden),
- m_cancelIndexing(o.m_cancelIndexing), m_cachedName(o.m_cachedName),
- m_cachedCategory(o.m_cachedCategory),
- m_cachedLanguage(o.m_cachedLanguage),
- m_cachedHasVersion(o.m_cachedHasVersion)
+ if (m_cachedHasVersion
+ && (minimumSwordVersion() > sword::SWVersion::currentVersion))
+ {
+ qWarning("The module \"%s\" requires a newer Sword library. Please "
+ "update to \"Sword %s\".",
+ m_cachedName.toUtf8().constData(),
+ minimumSwordVersion().getText());
+
+ /// \todo if this is the case, can we use the module at all?
+ }
+}
+
+CSwordModuleInfo::CSwordModuleInfo(const CSwordModuleInfo & copy)
+ : QObject(NULL)
+ , m_module(copy.m_module)
+ , m_backend(copy.m_backend)
+ , m_type(copy.m_type)
+ , m_hidden(copy.m_hidden)
+ , m_cancelIndexing(copy.m_cancelIndexing)
+ , m_cachedName(copy.m_cachedName)
+ , m_cachedCategory(copy.m_cachedCategory)
+ , m_cachedLanguage(copy.m_cachedLanguage)
+ , m_cachedHasVersion(copy.m_cachedHasVersion)
{
// Intentionally empty
}
bool CSwordModuleInfo::unlock(const QString & unlockKey) {
- if (!isEncrypted()) {
+ if (!isEncrypted())
return false;
- }
bool unlocked = unlockKeyIsValid();
- CBTConfig::setModuleEncryptionKey(name(), unlockKey);
+ btConfig().setModuleEncryptionKey(m_cachedName, unlockKey);
/// \todo remove this comment once it is no longer needed
- /* There is currently a deficiency in sword 1.6.1 in that backend->setCipherKey() does
- * not work correctly for modules from which data was already fetched. Therefore we have to
- * reload the modules in bibletime.cpp
- */
- backend()->setCipherKey(m_module->Name(), unlockKey.toUtf8().constData());
+ /* There is currently a deficiency in sword 1.6.1 in that
+ backend->setCipherKey() does not work correctly for modules from which
+ data was already fetched. Therefore we have to reload the modules in
+ bibletime.cpp */
+ m_backend.setCipherKey(m_module->getName(), unlockKey.toUtf8().constData());
/// \todo write to Sword config as well
- if (unlockKeyIsValid() != unlocked) {
+ if (unlockKeyIsValid() != unlocked)
emit unlockedChanged(!unlocked);
- }
return true;
}
bool CSwordModuleInfo::isLocked() const {
- //still works, but the cipherkey is stored in CBTConfig.
- //Works because it is set in sword on program startup.
+ // still works, but the cipherkey is stored in BtConfig.
+ // Works because it is set in sword on program startup.
return isEncrypted() && !unlockKeyIsValid();
}
@@ -148,38 +129,35 @@ bool CSwordModuleInfo::isEncrypted() const {
* is encrypted but not necessarily locked
*/
- //This code is still right, though we do no longer write to the module config files any more
- std::map < sword::SWBuf, sword::ConfigEntMap, std::less < sword::SWBuf > >::iterator SectionMapIter;
- SectionMapIter = backend()->getConfig()->Sections.find(name().toUtf8().constData());
- if (SectionMapIter == backend()->getConfig()->Sections.end())
+ /* This code is still right, though we do no longer write to the module
+ config files any more. */
+ typedef sword::SectionMap::const_iterator SMCI;
+ SMCI it = m_backend.getConfig()->Sections.find(m_cachedName.toUtf8().constData());
+ if (it == m_backend.getConfig()->Sections.end())
return false;
- sword::ConfigEntMap config = SectionMapIter->second;
- sword::ConfigEntMap::iterator it = config.find("CipherKey");
- return it != config.end();
+ const sword::ConfigEntMap & config = it->second;
+ return config.find("CipherKey") != config.end();
}
bool CSwordModuleInfo::unlockKeyIsValid() const {
m_module->setPosition(sword::TOP);
- // This needs to use ::fromLatin1 because if the text is still locked,
- // a lot of garbage will show up. It will also work with properly decrypted
- // Unicode text, because all non-ASCII Unicode chars consist of bytes >127
- // and therefore contain no control (nonprintable) characters, which are all <127.
- QString test = isUnicode()
- ? QString::fromUtf8(m_module->getRawEntryBuf().c_str())
- : QString::fromLatin1( m_module->getRawEntryBuf().c_str() );
+ /* This needs to use ::fromLatin1 because if the text is still locked, a lot
+ of garbage will show up. It will also work with properly decrypted
+ Unicode text, because all non-ASCII Unicode chars consist of bytes >127
+ and therefore contain no control (nonprintable) characters, which are all
+ <127. */
+ const QString test(isUnicode()
+ ? QString::fromUtf8(m_module->getRawEntryBuf().c_str())
+ : QString::fromLatin1(m_module->getRawEntryBuf().c_str()));
- if (test.isEmpty()) {
+ if (test.isEmpty())
return false;
- }
- for (int i = 0; i <= test.length() && i < 100; i++) {
- if ( !test[i].isPrint() && !test[i].isNull() ) {
+ for (int i = 0; i < test.length() && i < 100; i++)
+ if (!test[i].isPrint() && !test[i].isNull())
return false;
- }
- }
-
return true;
}
@@ -188,336 +166,374 @@ QString CSwordModuleInfo::getGlobalBaseIndexLocation() {
}
QString CSwordModuleInfo::getModuleBaseIndexLocation() const {
- return getGlobalBaseIndexLocation() + QString("/") + name().toLocal8Bit();
+ return getGlobalBaseIndexLocation() + QString("/") + m_cachedName.toLocal8Bit();
}
-QString CSwordModuleInfo::getModuleStandardIndexLocation() const { //this for now returns the location of the main index
+QString CSwordModuleInfo::getModuleStandardIndexLocation() const {
+ // This for now returns the location of the main index
return getModuleBaseIndexLocation() + QString("/standard");
}
bool CSwordModuleInfo::hasIndex() const {
- //this will return true only
- //if the index exists and has correct version information for both index and module
- QDir d;
- if (!d.exists( getModuleStandardIndexLocation() )) {
- return false;
+ { // Is this a directory?
+ QFileInfo fi(getModuleStandardIndexLocation());
+ if (!fi.isDir())
+ return false;
}
- //first check if the index version and module version are ok
- QSettings module_config(getModuleBaseIndexLocation() + QString("/bibletime-index.conf"), QSettings::IniFormat);
+ // Are the index version and module version OK?
+ QSettings module_config(getModuleBaseIndexLocation()
+ + QString("/bibletime-index.conf"),
+ QSettings::IniFormat);
- if (hasVersion() &&
- module_config.value("module-version").toString() != config(CSwordModuleInfo::ModuleVersion))
+ if (m_cachedHasVersion
+ && module_config.value("module-version").toString()
+ != config(CSwordModuleInfo::ModuleVersion))
{
return false;
}
if (module_config.value("index-version").toUInt() != INDEX_VERSION) {
- qDebug("%s: INDEX_VERSION is not compatible with this version of BibleTime.", name().toUtf8().constData());
+ qDebug("%s: INDEX_VERSION is not compatible with this version of "
+ "BibleTime.",
+ m_cachedName.toUtf8().constData());
return false;
}
- //then check if the index is there
- return lucene::index::IndexReader::indexExists(getModuleStandardIndexLocation().toLatin1().constData());
+ // Is the index there?
+ return lucene::index::IndexReader::indexExists(getModuleStandardIndexLocation()
+ .toLatin1().constData());
}
bool CSwordModuleInfo::buildIndex() {
-
m_cancelIndexing = false;
try {
- //Without this we don't get strongs, lemmas, etc
- backend()->setFilterOptions ( CBTConfig::getFilterOptionDefaults() );
- //make sure we reset all important filter options which influcence the plain filters.
- // turn on these options, they are needed for the EntryAttributes population
- backend()->setOption( CSwordModuleInfo::strongNumbers, true );
- backend()->setOption( CSwordModuleInfo::morphTags, true );
- backend()->setOption( CSwordModuleInfo::footnotes, true );
- backend()->setOption( CSwordModuleInfo::headings, true );
- // we don't want the following in the text, the do not carry searchable information
- backend()->setOption( CSwordModuleInfo::morphSegmentation, false );
- backend()->setOption( CSwordModuleInfo::scriptureReferences, false );
- backend()->setOption( CSwordModuleInfo::redLetterWords, false );
-
- // do not use any stop words
- const TCHAR* stop_words[] = { NULL };
- lucene::analysis::standard::StandardAnalyzer an( (const TCHAR**)stop_words );
- QString index = getModuleStandardIndexLocation();
+ // Without this we don't get strongs, lemmas, etc.
+ m_backend.setFilterOptions(btConfig().getFilterOptions());
+ /* Make sure we reset all important filter options which influcence the
+ plain filters. Turn on these options, they are needed for the
+ EntryAttributes population */
+ m_backend.setOption(CSwordModuleInfo::strongNumbers, true);
+ m_backend.setOption(CSwordModuleInfo::morphTags, true);
+ m_backend.setOption(CSwordModuleInfo::footnotes, true);
+ m_backend.setOption(CSwordModuleInfo::headings, true);
+ /* We don't want the following in the text, the do not carry searchable
+ information. */
+ m_backend.setOption(CSwordModuleInfo::morphSegmentation, false);
+ m_backend.setOption(CSwordModuleInfo::scriptureReferences, false);
+ m_backend.setOption(CSwordModuleInfo::redLetterWords, false);
+
+ // Do not use any stop words:
+ static const TCHAR * stop_words[1u] = { NULL };
+ lucene::analysis::standard::StandardAnalyzer an(static_cast<const TCHAR **>(stop_words));
+ const QString index(getModuleStandardIndexLocation());
QDir dir("/");
- dir.mkpath( getGlobalBaseIndexLocation() );
- dir.mkpath( getModuleBaseIndexLocation() );
- dir.mkpath( getModuleStandardIndexLocation() );
+ dir.mkpath(getGlobalBaseIndexLocation());
+ dir.mkpath(getModuleBaseIndexLocation());
+ dir.mkpath(getModuleStandardIndexLocation());
- if (lucene::index::IndexReader::indexExists(index.toLatin1().constData())) {
- if (lucene::index::IndexReader::isLocked(index.toLatin1().constData()) ) {
+ if (lucene::index::IndexReader::indexExists(index.toLatin1().constData()))
+ if (lucene::index::IndexReader::isLocked(index.toLatin1().constData()))
lucene::index::IndexReader::unlock(index.toLatin1().constData());
- }
- }
- QSharedPointer<lucene::index::IndexWriter> writer( new lucene::index::IndexWriter(index.toLatin1().constData(), &an, true) ); //always create a new index
+ // Always create a new index:
+ typedef lucene::index::IndexWriter IW;
+ QSharedPointer<IW> writer(new IW(index.toLatin1().constData(), &an, true));
writer->setMaxFieldLength(BT_MAX_LUCENE_FIELD_LENGTH);
- writer->setUseCompoundFile(true); //merge segments into a single file
+ writer->setUseCompoundFile(true); // Merge segments into a single file
+#ifndef CLUCENE2
+ writer->setMinMergeDocs(1000);
+#endif
m_module->setPosition(sword::TOP);
- unsigned long verseLowIndex = m_module->Index();
+ unsigned long verseLowIndex = m_module->getIndex();
m_module->setPosition(sword::BOTTOM);
- unsigned long verseHighIndex = m_module->Index();
+ unsigned long verseHighIndex = m_module->getIndex();
- //verseLowIndex is not 0 in all cases (i.e. NT-only modules)
+ // verseLowIndex is not 0 in all cases (i.e. NT-only modules)
unsigned long verseIndex = verseLowIndex + 1;
unsigned long verseSpan = verseHighIndex - verseLowIndex;
- //Index() is not implemented properly for lexicons, so we use a
- //workaround.
- if (type() == CSwordModuleInfo::Lexicon) {
+ // Index() is not implemented properly for lexicons, so work around it:
+ if (m_type == CSwordModuleInfo::Lexicon) {
verseIndex = 0;
verseLowIndex = 0;
- verseSpan = ((CSwordLexiconModuleInfo*)this)->entries().size();
+ verseSpan = static_cast<CSwordLexiconModuleInfo *>(this)->entries().size();
}
emit indexingProgress(0);
- sword::SWKey* key = m_module->getKey();
- //VerseKey for bibles
- sword::VerseKey* vk = dynamic_cast<sword::VerseKey*>(key);
+ sword::SWKey * const key = m_module->getKey();
+ sword::VerseKey * const vk = dynamic_cast<sword::VerseKey *>(key);
if (vk) {
- // we have to be sure to insert the english key into the index, otherwise we'd be in trouble if the language changes
+ /* We have to be sure to insert the english key into the index,
+ otherwise we'd be in trouble if the language changes. */
vk->setLocale("en_US");
- //If we have a verse based module, we want to include the pre-chapter etc. headings in the search
- vk->Headings(1);
+ /* If we have a verse based module, we want to include the pre-
+ chapter etc. headings in the search. */
+ vk->setIntros(true);
}
- //holds UTF-8 data and is faster than QString.
- QByteArray textBuffer;
+ QByteArray textBuffer; // Holds UTF-8 data and is faster than QString.
// we start with the first module entry, key is automatically updated
// because key is a pointer to the modules key
m_module->setSkipConsecutiveLinks(true);
- wchar_t wcharBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1];
+ QScopedPointer<wchar_t, QScopedPointerArrayDeleter<wchar_t> >
+ sPwcharBuffer(new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]);
+ wchar_t * const wcharBuffer = sPwcharBuffer.data();
+ Q_ASSERT(wcharBuffer);
m_module->setPosition(sword::TOP);
- while (!(m_module->Error()) && !m_cancelIndexing) {
+ while (!(m_module->popError()) && !m_cancelIndexing) {
- // Also index Chapter 0 and Verse 0, because they might have information in the entry attributes
- // We used to just put their content into the textBuffer and continue to the next verse, but
- // with entry attributes this doesn't work any more.
- // Hits in the search dialog will show up as 1:1 (instead of 0)
+ /* Also index Chapter 0 and Verse 0, because they might have
+ information in the entry attributes. We used to just put their
+ content into the textBuffer and continue to the next verse, but
+ with entry attributes this doesn't work any more. Hits in the
+ search dialog will show up as 1:1 (instead of 0). */
QSharedPointer<lucene::document::Document> doc(new lucene::document::Document());
//index the key
lucene_utf8towcs(wcharBuffer, key->getText(), BT_MAX_LUCENE_FIELD_LENGTH);
- //doc->add(*lucene::document::Field::UnIndexed((const TCHAR*)_T("key"), (const TCHAR*)wcharBuffer));
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("key"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_YES | lucene::document::Field::INDEX_NO)));
-
- // index the main text
- //at this point we have to make sure we disabled the strongs and the other options
- //so the plain filters won't include the numbers somehow.
- lucene_utf8towcs(wcharBuffer, (const char*) textBuffer.append(m_module->StripText()), BT_MAX_LUCENE_FIELD_LENGTH);
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("content"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED)));
- textBuffer.resize(0); //clean up
-
- // index attributes
- sword::AttributeList::iterator attListI;
- sword::AttributeValue::iterator attValueI;
- // Footnotes
- for (attListI = m_module->getEntryAttributes()["Footnote"].begin();
- attListI != m_module->getEntryAttributes()["Footnote"].end();
- attListI++) {
- lucene_utf8towcs(wcharBuffer, attListI->second["body"], BT_MAX_LUCENE_FIELD_LENGTH);
- //doc->add(*lucene::document::Field::UnStored((const TCHAR*)_T("footnote"), wcharBuffer));
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("footnote"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED)));
- } // for attListI
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("key")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_YES
+ | lucene::document::Field::INDEX_NO)));
+
+ /* At this point we have to make sure we disabled the strongs and
+ the other options, so the plain filters won't include the numbers
+ somehow. */
+ textBuffer.append(m_module->stripText());
+ lucene_utf8towcs(wcharBuffer,
+ static_cast<const char *>(textBuffer),
+ BT_MAX_LUCENE_FIELD_LENGTH);
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("content")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_NO
+ | lucene::document::Field::INDEX_TOKENIZED)));
+ textBuffer.clear();
+
+ typedef sword::AttributeList::iterator ALI;
+ typedef sword::AttributeValue::iterator AVI;
+
+ for (ALI it = m_module->getEntryAttributes()["Footnote"].begin();
+ it != m_module->getEntryAttributes()["Footnote"].end();
+ ++it)
+ {
+ lucene_utf8towcs(wcharBuffer, it->second["body"], BT_MAX_LUCENE_FIELD_LENGTH);
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("footnote")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_NO
+ | lucene::document::Field::INDEX_TOKENIZED)));
+ }
// Headings
- for (attValueI = m_module->getEntryAttributes()["Heading"]["Preverse"].begin();
- attValueI != m_module->getEntryAttributes()["Heading"]["Preverse"].end();
- attValueI++) {
- lucene_utf8towcs(wcharBuffer, attValueI->second, BT_MAX_LUCENE_FIELD_LENGTH);
- //doc->add(*lucene::document::Field::UnStored((const TCHAR*)_T("heading"), wcharBuffer));
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("heading"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED)));
- } // for attValueI
+ for (AVI it = m_module->getEntryAttributes()["Heading"]["Preverse"].begin();
+ it != m_module->getEntryAttributes()["Heading"]["Preverse"].end();
+ ++it)
+ {
+ lucene_utf8towcs(wcharBuffer, it->second, BT_MAX_LUCENE_FIELD_LENGTH);
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("heading")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_NO
+ | lucene::document::Field::INDEX_TOKENIZED)));
+ }
// Strongs/Morphs
- for (attListI = m_module->getEntryAttributes()["Word"].begin();
- attListI != m_module->getEntryAttributes()["Word"].end();
- attListI++) {
- // for each attribute
- if (attListI->second["LemmaClass"] == "strong") {
- lucene_utf8towcs(wcharBuffer, attListI->second["Lemma"], BT_MAX_LUCENE_FIELD_LENGTH);
- //doc->add(*lucene::document::Field::UnStored((const TCHAR*)_T("strong"), wcharBuffer));
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("strong"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED)));
- //qWarning("Adding strong %s", attListI->second["Lemma"].c_str());
+ for (ALI it = m_module->getEntryAttributes()["Word"].begin();
+ it != m_module->getEntryAttributes()["Word"].end();
+ ++it)
+ {
+ if (it->second["LemmaClass"] == "strong") {
+ lucene_utf8towcs(wcharBuffer, it->second["Lemma"], BT_MAX_LUCENE_FIELD_LENGTH);
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("strong")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_NO
+ | lucene::document::Field::INDEX_TOKENIZED)));
}
- if (attListI->second.find("Morph") != attListI->second.end()) {
- lucene_utf8towcs(wcharBuffer, attListI->second["Morph"], BT_MAX_LUCENE_FIELD_LENGTH);
- //doc->add(*lucene::document::Field::UnStored((const TCHAR*)_T("morph"), wcharBuffer));
- doc->add(*(new lucene::document::Field((const TCHAR*)_T("morph"), (const TCHAR*)wcharBuffer, lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED)));
+ if (it->second.find("Morph") != it->second.end()) {
+ lucene_utf8towcs(wcharBuffer, it->second["Morph"], BT_MAX_LUCENE_FIELD_LENGTH);
+ doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("morph")),
+ static_cast<const TCHAR *>(wcharBuffer),
+ lucene::document::Field::STORE_NO
+ | lucene::document::Field::INDEX_TOKENIZED)));
}
- } // for attListI
+ }
writer->addDocument(doc.data());
//Index() is not implemented properly for lexicons, so we use a
//workaround.
- if (type() == CSwordModuleInfo::Lexicon) {
+ if (m_type == CSwordModuleInfo::Lexicon) {
verseIndex++;
- }
- else {
- verseIndex = m_module->Index();
+ } else {
+ verseIndex = m_module->getIndex();
}
if (verseIndex % 200 == 0) {
int indexingProgressValue;
- if (verseSpan == 0) { //prevent division by zero
- //m_indexingProgress.setValue( QVariant(0) );
+ if (verseSpan == 0) { // Prevent division by zero
indexingProgressValue = 0;
- }
- else {
- //m_indexingProgress.setValue( QVariant((int)((100*(verseIndex-verseLowIndex))/(verseHighIndex-verseLowIndex))) );
+ } else {
indexingProgressValue = (int)((100 * (verseIndex - verseLowIndex)) / (verseSpan));
}
- //m_indexingProgress.activate();
emit indexingProgress(indexingProgressValue);
}
m_module->increment();
} // while (!(m_module->Error()) && !m_cancelIndexing)
- if (!m_cancelIndexing) {
+ if (!m_cancelIndexing)
writer->optimize();
- }
writer->close();
if (m_cancelIndexing) {
deleteIndex();
m_cancelIndexing = false;
- }
- else {
- QSettings module_config(getModuleBaseIndexLocation() + QString("/bibletime-index.conf"), QSettings::IniFormat);
- if (hasVersion()) module_config.setValue("module-version", config(CSwordModuleInfo::ModuleVersion) );
+ } else {
+ QSettings module_config(getModuleBaseIndexLocation()
+ + QString("/bibletime-index.conf"),
+ QSettings::IniFormat);
+ if (m_cachedHasVersion)
+ module_config.setValue("module-version",
+ config(CSwordModuleInfo::ModuleVersion));
module_config.setValue("index-version", INDEX_VERSION);
emit hasIndexChanged(true);
}
- }
- catch (CLuceneError &e) {
+ } catch (CLuceneError & e) {
qWarning() << "CLucene exception occurred while indexing:" << e.what();
- util::showWarning(0, QCoreApplication::tr("Indexing aborted"), QCoreApplication::tr("An internal error occurred while building the index: %1").arg(e.what()));
+ message::showWarning(0,
+ QCoreApplication::tr("Indexing aborted"),
+ QCoreApplication::tr("An internal error occurred "
+ "while building the index: %1")
+ .arg(e.what()));
deleteIndex();
m_cancelIndexing = false;
return false;
- }
- catch (...) {
+ } catch (...) {
qWarning("CLucene exception occurred while indexing");
- util::showWarning(0, QCoreApplication::tr("Indexing aborted"), QCoreApplication::tr("An internal error occurred while building the index."));
+ message::showWarning(0,
+ QCoreApplication::tr("Indexing aborted"),
+ QCoreApplication::tr("An internal error occurred "
+ "while building the index."));
deleteIndex();
m_cancelIndexing = false;
return false;
}
-
return true;
}
void CSwordModuleInfo::deleteIndex() {
- deleteIndexForModule(name());
+ deleteIndexForModule(m_cachedName);
emit hasIndexChanged(false);
}
-void CSwordModuleInfo::deleteIndexForModule(const QString &name) {
- util::directory::removeRecursive( getGlobalBaseIndexLocation() + "/" + name );
+void CSwordModuleInfo::deleteIndexForModule(const QString & name) {
+ util::directory::removeRecursive(getGlobalBaseIndexLocation() + "/" + name);
}
unsigned long CSwordModuleInfo::indexSize() const {
namespace DU = util::directory;
- return DU::getDirSizeRecursive( getModuleBaseIndexLocation() );
+ return DU::getDirSizeRecursive(getModuleBaseIndexLocation());
}
-
-int CSwordModuleInfo::searchIndexed(const QString &searchedText,
- const sword::ListKey &scope,
- sword::ListKey &results) const
+int CSwordModuleInfo::searchIndexed(const QString & searchedText,
+ const sword::ListKey & scope,
+ sword::ListKey & results) const
{
- char utfBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1];
- wchar_t wcharBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1];
+ QScopedPointer<char, QScopedPointerArrayDeleter<char> >
+ sPutfBuffer(new char[BT_MAX_LUCENE_FIELD_LENGTH + 1]);
+ QScopedPointer<wchar_t, QScopedPointerArrayDeleter<wchar_t> >
+ sPwcharBuffer(new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]);
+ char * const utfBuffer = sPutfBuffer.data();
+ Q_ASSERT(utfBuffer);
+ wchar_t * const wcharBuffer = sPwcharBuffer.data();
+ Q_ASSERT(wcharBuffer);
// work around Swords thread insafety for Bibles and Commentaries
- QSharedPointer < CSwordKey > key(CSwordKey::createInstance(this));
- sword::SWKey* s = dynamic_cast < sword::SWKey * >(key.data());
- QList<sword::VerseKey*> list;
-
- if (s) {
- m_module->setKey(*s);
+ QSharedPointer<CSwordKey> key(CSwordKey::createInstance(this));
+ {
+ const sword::SWKey * const s = dynamic_cast<sword::SWKey *>(key.data());
+ if (s)
+ m_module->setKey(*s);
}
+ QList<sword::VerseKey *> list;
results.clear();
try {
// do not use any stop words
- const TCHAR* stop_words[] = { NULL };
- lucene::analysis::standard::StandardAnalyzer analyzer( stop_words );
+ static const TCHAR * stop_words[1u] = { NULL };
+ lucene::analysis::standard::StandardAnalyzer analyzer(stop_words);
lucene::search::IndexSearcher searcher(getModuleStandardIndexLocation().toLatin1().constData());
lucene_utf8towcs(wcharBuffer, searchedText.toUtf8().constData(), BT_MAX_LUCENE_FIELD_LENGTH);
- QSharedPointer<lucene::search::Query> q( lucene::queryParser::QueryParser::parse((const TCHAR*)wcharBuffer, (const TCHAR*)_T("content"), &analyzer) );
-
-#ifdef CLUCENE2
- QSharedPointer<lucene::search::Hits> h( searcher.search(q.data(), lucene::search::Sort::INDEXORDER()) );
-#else
- QSharedPointer<lucene::search::Hits> h( searcher.search(q.data(), lucene::search::Sort::INDEXORDER) );
-#endif
+ QSharedPointer<lucene::search::Query> q(lucene::queryParser::QueryParser::parse(static_cast<const TCHAR *>(wcharBuffer),
+ static_cast<const TCHAR *>(_T("content")),
+ &analyzer));
- /// \warning This is a workaround for Sword constness
- const bool useScope = (const_cast<sword::ListKey&>(scope).Count() > 0);
-// const bool isVerseModule = (type() == CSwordModuleInfo::Bible) || (type() == CSwordModuleInfo::Commentary);
+ QSharedPointer<lucene::search::Hits> h(searcher.search(q.data(),
+ #ifdef CLUCENE2
+ lucene::search::Sort::INDEXORDER()));
+ #else
+ lucene::search::Sort::INDEXORDER));
+ #endif
- lucene::document::Document* doc = 0;
- QSharedPointer<sword::SWKey> swKey( module()->CreateKey() );
+ const bool useScope = (scope.getCount() > 0);
+ lucene::document::Document * doc = 0;
+ QSharedPointer<sword::SWKey> swKey(m_module->createKey());
#ifdef CLUCENE2
for (unsigned int i = 0; i < h->length(); ++i) {
#else
- for (int i = 0; i < h->length(); ++i) {
+ for (int i = 0; i < h->length(); ++i) {
#endif
doc = &h->doc(i);
- lucene_wcstoutf8(utfBuffer, (const wchar_t*)doc->get((const TCHAR*)_T("key")), BT_MAX_LUCENE_FIELD_LENGTH);
+ lucene_wcstoutf8(utfBuffer,
+ static_cast<const wchar_t *>(doc->get(static_cast<const TCHAR *>(_T("key")))),
+ BT_MAX_LUCENE_FIELD_LENGTH);
swKey->setText(utfBuffer);
- // limit results based on scope
- //if (searchOptions & CSwordModuleSearch::useScope && scope.Count() > 0){
+ // Limit results based on scope:
if (useScope) {
- /// \warning This is a workaround for sword constness
- for (int j = 0; j < const_cast<sword::ListKey&>(scope).Count(); j++) {
- /// \warning This is a workaround for sword constness
- sword::ListKey &scope2 = const_cast<sword::ListKey&>(scope);
- sword::VerseKey* vkey = dynamic_cast<sword::VerseKey*>(scope2.getElement(j));
- if (vkey->LowerBound().compare(*swKey) <= 0 && vkey->UpperBound().compare(*swKey) >= 0) {
+ for (int j = 0; j < scope.getCount(); j++) {
+ Q_ASSERT(dynamic_cast<const sword::VerseKey *>(scope.getElement(j)));
+ const sword::VerseKey * const vkey = static_cast<const sword::VerseKey *>(scope.getElement(j));
+ if (vkey->getLowerBound().compare(*swKey) <= 0
+ && vkey->getUpperBound().compare(*swKey) >= 0)
+ {
results.add(*swKey);
}
}
- }
- else { // no scope, give me all buffers
- results.add(*swKey);
+ } else {
+ results.add(*swKey); // No scope, give me all buffers
}
}
- }
- catch (...) {
+ } catch (...) {
qWarning("CLucene exception occurred");
- util::showWarning(0, QCoreApplication::tr("Search aborted"), QCoreApplication::tr("An internal error occurred while executing your search."));
+ message::showWarning(0,
+ QCoreApplication::tr("Search aborted"),
+ QCoreApplication::tr("An internal error occurred "
+ "while executing your search."));
return 0;
}
qDeleteAll(list);
list.clear();
- return results.Count();
+ return results.getCount();
}
sword::SWVersion CSwordModuleInfo::minimumSwordVersion() const {
- return sword::SWVersion(config(CSwordModuleInfo::MinimumSwordVersion).toUtf8().constData());
+ return sword::SWVersion(config(CSwordModuleInfo::MinimumSwordVersion)
+ .toUtf8().constData());
}
QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) const {
@@ -527,37 +543,32 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons
return getFormattedConfigEntry("About");
case CipherKey: {
- if (CBTConfig::getModuleEncryptionKey(name()).isNull()) { //fall back!
- return QString(m_module->getConfigEntry("CipherKey"));
- }
- else {
- return CBTConfig::getModuleEncryptionKey(name());
+ if (btConfig().getModuleEncryptionKey(m_cachedName).isNull()) {
+ return QString(m_module->getConfigEntry("CipherKey")); // Fallback
+ } else {
+ return btConfig().getModuleEncryptionKey(m_cachedName);
}
}
case AbsoluteDataPath: {
- QString path( getSimpleConfigEntry("AbsoluteDataPath") );
- path.replace(QRegExp("/./"), "/"); // make /abs/path/./modules/ looking better
- //make sure we have a trailing slash!
-
- if (path.right(1) != "/") {
+ QString path(getSimpleConfigEntry("AbsoluteDataPath"));
+ if (!path.endsWith('/')) /// \todo is this needed?
path.append('/');
- }
return path;
}
- case DataPath: { //make sure we remove the dataFile part if it's a Lexicon
+ case DataPath: {
QString path(getSimpleConfigEntry("DataPath"));
- if ((type() == CSwordModuleInfo::GenericBook) || (type() == CSwordModuleInfo::Lexicon)) {
- int pos = path.lastIndexOf("/"); //last slash in the string
-
- if (pos != -1) {
- path = path.left(pos + 1); //include the slash
- }
+ // Make sure we remove the dataFile part if it's a Lexicon
+ if (m_type == CSwordModuleInfo::GenericBook
+ || m_type == CSwordModuleInfo::Lexicon)
+ {
+ int pos = path.lastIndexOf("/"); // Last slash in the string
+ if (pos != -1)
+ path = path.left(pos + 1); // Include the slash
}
-
return path;
}
@@ -565,84 +576,76 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons
return getFormattedConfigEntry("Description");
case ModuleVersion: {
- QString version(getSimpleConfigEntry("Version"));
-
- if (version.isEmpty()) {
- version = "1.0";
- }
-
- return version;
+ const QString version(getSimpleConfigEntry("Version"));
+ return version.isEmpty() ? "1.0" : version;
}
case MinimumSwordVersion: {
const QString minimumVersion(getSimpleConfigEntry("MinimumVersion"));
- return !minimumVersion.isEmpty() ? minimumVersion : QString("0.0");
+ return minimumVersion.isEmpty() ? "0.0" : minimumVersion;
}
case TextDir: {
const QString dir(getSimpleConfigEntry("Direction"));
- return !dir.isEmpty() ? dir : QString("LtoR");
+ return dir.isEmpty() ? QString("LtoR") : dir;
}
case DisplayLevel: {
const QString level(getSimpleConfigEntry("DisplayLevel"));
- return !level.isEmpty() ? level : QString("1");
+ return level.isEmpty() ? QString("1") : level;
}
case GlossaryFrom: {
- if (category() != Glossary) {
+ if (m_cachedCategory != Glossary)
return QString::null;
- };
const QString lang(getSimpleConfigEntry("GlossaryFrom"));
-
- return !lang.isEmpty() ? lang : QString::null;
+ return lang.isEmpty() ? QString::null : lang;
}
case GlossaryTo: {
- if (category() != Glossary) {
+ if (m_cachedCategory != Glossary) {
return QString::null;
};
const QString lang(getSimpleConfigEntry("GlossaryTo"));
-
- return !lang.isEmpty() ? lang : QString::null;
+ return lang.isEmpty() ? QString::null : lang;
}
case Markup: {
const QString markup(getSimpleConfigEntry("SourceType"));
- return !markup.isEmpty() ? markup : QString("Unknown");
+ return markup.isEmpty() ? QString("Unknown") : markup;
}
case DistributionLicense:
- return getSimpleConfigEntry("DistributionLicense");
+ return getFormattedConfigEntry("DistributionLicense");
case DistributionSource:
- return getSimpleConfigEntry("DistributionSource");
+ return getFormattedConfigEntry("DistributionSource");
case DistributionNotes:
- return getSimpleConfigEntry("DistributionNotes");
+ return getFormattedConfigEntry("DistributionNotes");
case TextSource:
- return getSimpleConfigEntry("TextSource");
+ return getFormattedConfigEntry("TextSource");
case CopyrightNotes:
- return getSimpleConfigEntry("CopyrightNotes");
+ return getFormattedConfigEntry("CopyrightNotes");
case CopyrightHolder:
- return getSimpleConfigEntry("CopyrightHolder");
+ return getFormattedConfigEntry("CopyrightHolder");
case CopyrightDate:
- return getSimpleConfigEntry("CopyrightDate");
+ return getFormattedConfigEntry("CopyrightDate");
case CopyrightContactName:
- return getSimpleConfigEntry("CopyrightContactName");
+ return getFormattedConfigEntry("CopyrightContactName");
case CopyrightContactAddress:
- return getSimpleConfigEntry("CopyrightContactAddress");
+ return getFormattedConfigEntry("CopyrightContactAddress");
case CopyrightContactEmail:
- return getSimpleConfigEntry("CopyrightContactEmail");
+ return getFormattedConfigEntry("CopyrightContactEmail");
default:
return QString::null;
@@ -651,75 +654,54 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons
bool CSwordModuleInfo::has(const CSwordModuleInfo::Feature feature) const {
switch (feature) {
-
- // case StrongsNumbers:
- // return m_module->getConfig().has("Feature", "StrongsNumber");
-
- case GreekDef:
- return m_module->getConfig().has("Feature", "GreekDef");
-
- case HebrewDef:
- return m_module->getConfig().has("Feature", "HebrewDef");
-
- case GreekParse:
- return m_module->getConfig().has("Feature", "GreekParse");
-
- case HebrewParse:
- return m_module->getConfig().has("Feature", "HebrewParse");
+ case GreekDef: return m_module->getConfig().has("Feature", "GreekDef");
+ case HebrewDef: return m_module->getConfig().has("Feature", "HebrewDef");
+ case GreekParse: return m_module->getConfig().has("Feature", "GreekParse");
+ case HebrewParse: return m_module->getConfig().has("Feature", "HebrewParse");
}
-
return false;
}
bool CSwordModuleInfo::has(const CSwordModuleInfo::FilterTypes option) const {
- //BAD workaround to see if the filter is GBF, OSIS or ThML!
- const QString name = backend()->configOptionName(option);
-
- if (m_module->getConfig().has("GlobalOptionFilter", QString("OSIS").append(name).toUtf8().constData())) {
- return true;
- }
-
- if (m_module->getConfig().has("GlobalOptionFilter", QString("GBF").append(name).toUtf8().constData())) {
- return true;
- }
-
- if (m_module->getConfig().has("GlobalOptionFilter", QString("ThML").append(name).toUtf8().constData())) {
- return true;
- }
-
- if (m_module->getConfig().has("GlobalOptionFilter", QString("UTF8").append(name).toUtf8().constData())) {
- return true;
- }
-
- if (m_module->getConfig().has("GlobalOptionFilter", name.toUtf8().constData())) {
- return true;
- }
-
- return false;
+ /// \todo This is a BAD workaround to see if the filter is GBF, OSIS or ThML!
+ const QString name = m_backend.configOptionName(option);
+ return m_module->getConfig().has("GlobalOptionFilter",
+ QString("OSIS").append(name).toUtf8().constData())
+ || m_module->getConfig().has("GlobalOptionFilter",
+ QString("GBF").append(name).toUtf8().constData())
+ || m_module->getConfig().has("GlobalOptionFilter",
+ QString("ThML").append(name).toUtf8().constData())
+ || m_module->getConfig().has("GlobalOptionFilter",
+ QString("UTF8").append(name).toUtf8().constData())
+ || m_module->getConfig().has("GlobalOptionFilter",
+ name.toUtf8().constData());
}
CSwordModuleInfo::TextDirection CSwordModuleInfo::textDirection() const {
- if (config(TextDir) == "RtoL")
- return CSwordModuleInfo::RightToLeft;
-
- return CSwordModuleInfo::LeftToRight;
+ return (config(TextDir) == "RtoL")
+ ? CSwordModuleInfo::RightToLeft
+ : CSwordModuleInfo::LeftToRight;
}
-void CSwordModuleInfo::write(CSwordKey *key, const QString &newText) {
- module()->setKey(key->key().toUtf8().constData());
+void CSwordModuleInfo::write(CSwordKey * key, const QString & newText) {
+ m_module->setKey(key->key().toUtf8().constData());
- //don't store a pointer to the const char* value somewhere because QCString doesn't keep the value of it
- module()->setEntry(isUnicode() ? newText.toUtf8().constData() : newText.toLocal8Bit().constData());
+ /* Don't store a pointer to the const char* value somewhere because QCString
+ doesn't keep the value of it. */
+ m_module->setEntry(isUnicode()
+ ? newText.toUtf8().constData()
+ : newText.toLocal8Bit().constData());
}
bool CSwordModuleInfo::deleteEntry(CSwordKey * const key) {
- module()->setKey(isUnicode() ? key->key().toUtf8().constData() : key->key().toLocal8Bit().constData());
+ m_module->setKey(isUnicode()
+ ? key->key().toUtf8().constData()
+ : key->key().toLocal8Bit().constData());
- if (module()) {
- module()->deleteEntry();
+ if (m_module) {
+ m_module->deleteEntry();
return true;
}
-
return false;
}
@@ -727,7 +709,7 @@ void CSwordModuleInfo::initCachedCategory() {
/// \todo Maybe we can use raw string comparsion instead of QString?
const QString cat(m_module->getConfigEntry("Category"));
- /// \warning cat has to be checked before type() !!!
+ /// \warning cat has to be checked before m_type !!!
if (cat == "Cults / Unorthodox / Questionable Material") {
m_cachedCategory = Cult;
} else if (cat == "Daily Devotional"
@@ -741,7 +723,7 @@ void CSwordModuleInfo::initCachedCategory() {
} else if (cat == "Images" || cat == "Maps") {
m_cachedCategory = Images;
} else {
- switch (type()) {
+ switch (m_type) {
case Bible: m_cachedCategory = Bibles; break;
case Commentary: m_cachedCategory = Commentaries; break;
case Lexicon: m_cachedCategory = Lexicons; break;
@@ -753,15 +735,15 @@ void CSwordModuleInfo::initCachedCategory() {
}
void CSwordModuleInfo::initCachedLanguage() {
- CLanguageMgr *lm = CLanguageMgr::instance();
- if (category() == Glossary) {
+ const CLanguageMgr & lm = *CLanguageMgr::instance();
+ if (m_cachedCategory == Glossary) {
/*
Special handling for glossaries, we use the "from language" as
language for the module.
*/
- m_cachedLanguage = lm->languageForAbbrev(config(GlossaryFrom));
+ m_cachedLanguage = lm.languageForAbbrev(config(GlossaryFrom));
} else {
- m_cachedLanguage = lm->languageForAbbrev(m_module->Lang());
+ m_cachedLanguage = lm.languageForAbbrev(m_module->getLanguage());
}
}
@@ -770,74 +752,87 @@ Rendering::CEntryDisplay * CSwordModuleInfo::getDisplay() const {
}
QString CSwordModuleInfo::aboutText() const {
+ using util::htmlEscape;
+
+ static const QString row("<tr><td><b>%1</b></td><td>%2</td></tr>");
+
QString text;
text += "<table>";
- text += QString("<tr><td><b>%1</b></td><td>%2</td><tr>")
+ text += row
.arg(tr("Version"))
- .arg(hasVersion() ? config(CSwordModuleInfo::ModuleVersion) : tr("unknown"));
+ .arg(m_cachedHasVersion
+ ? htmlEscape(config(CSwordModuleInfo::ModuleVersion))
+ : tr("unknown"));
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
- .arg(tr("Markup"))
- .arg(!QString(m_module->getConfigEntry("SourceType")).isEmpty() ? QString(m_module->
- getConfigEntry("SourceType")) : tr("unknown"));
+ {
+ const QString sourceType(m_module->getConfigEntry("SourceType"));
+ text += row
+ .arg(tr("Markup"))
+ .arg(!sourceType.isEmpty()
+ ? htmlEscape(sourceType)
+ : tr("unknown"));
+ }
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("Location"))
- .arg(config(CSwordModuleInfo::AbsoluteDataPath));
+ .arg(htmlEscape(config(CSwordModuleInfo::AbsoluteDataPath)));
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("Language"))
- .arg(language()->translatedName());
+ .arg(htmlEscape(m_cachedLanguage->translatedName()));
if (m_module->getConfigEntry("Category"))
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("Category"))
- .arg(m_module->getConfigEntry("Category"));
+ .arg(htmlEscape(m_module->getConfigEntry("Category")));
if (m_module->getConfigEntry("LCSH"))
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("LCSH"))
- .arg(m_module->getConfigEntry("LCSH"));
+ .arg(htmlEscape(m_module->getConfigEntry("LCSH")));
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("Writable"))
.arg(isWritable() ? tr("yes") : tr("no"));
if (isEncrypted())
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ text += row
.arg(tr("Unlock key"))
- .arg(config(CSwordModuleInfo::CipherKey));
+ .arg(htmlEscape(config(CSwordModuleInfo::CipherKey)));
QString options;
unsigned int opts;
- for (opts = CSwordModuleInfo::filterTypesMIN; opts <= CSwordModuleInfo::filterTypesMAX; ++opts) {
+ for (opts = CSwordModuleInfo::filterTypesMIN;
+ opts <= CSwordModuleInfo::filterTypesMAX;
+ ++opts)
+ {
if (has(static_cast < CSwordModuleInfo::FilterTypes > (opts))) {
- if (!options.isEmpty()) {
+ if (!options.isEmpty())
options += QString::fromLatin1(", ");
- }
-
- options += CSwordBackend::translatedOptionName(static_cast < CSwordModuleInfo::FilterTypes > (opts));
+ typedef CSwordModuleInfo::FilterTypes FT;
+ options += CSwordBackend::translatedOptionName(static_cast<FT>(opts));
}
}
- if (!options.isEmpty()) {
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
+ if (!options.isEmpty())
+ text += row
.arg(tr("Features"))
- .arg(options);
- }
+ .arg(htmlEscape(options));
text += "</table><hr>";
- if (category() == Cult) //clearly say the module contains cult/questionable materials
+ // Clearly say the module contains cult/questionable materials
+ if (m_cachedCategory == Cult)
text += QString("<br/><b>%1</b><br/><br/>")
- .arg(tr("Take care, this work contains cult / questionable material!"));
+ .arg(tr("Take care, this work contains cult / questionable "
+ "material!"));
text += QString("<b>%1:</b><br/>%2</font>")
.arg(tr("About"))
- .arg(config(AboutInformation));
+ .arg(config(AboutInformation)); // May contain HTML, don't escape
typedef QList<CSwordModuleInfo::ConfigEntry> ListConfigEntry;
@@ -871,61 +866,47 @@ QString CSwordModuleInfo::aboutText() const {
text += ("<hr><table>");
- for (ListConfigEntry::iterator it(entries.begin()); it != entries.end(); ++it) {
- QString t( config(*it) );
-
- if (!t.isEmpty()) {
- text += QString("<tr><td><b>%1</b></td><td>%2</td></tr>")
- .arg(entryMap[*it])
- .arg(config(*it));
- }
-
- }
+ for (ListConfigEntry::iterator it(entries.begin()); it != entries.end(); ++it)
+ if (!config(*it).isEmpty())
+ text += row
+ .arg(htmlEscape(entryMap[*it]))
+ .arg(htmlEscape(config(*it)));
text += "</table></font>";
return text;
}
-QIcon CSwordModuleInfo::moduleIcon(const CSwordModuleInfo *module) {
- const QString &filename = moduleIconFilename(module);
- if (filename.isEmpty()) return QIcon();
- return util::directory::getIcon(filename);
+QIcon CSwordModuleInfo::moduleIcon(const CSwordModuleInfo & module) {
+ const QString & filename = moduleIconFilename(module);
+ if (filename.isEmpty())
+ return QIcon();
+ return util::getIcon(filename);
}
-const QString &CSwordModuleInfo::moduleIconFilename(
- const CSwordModuleInfo *module)
-{
- const CSwordModuleInfo::Category cat(module->category());
+const QString & CSwordModuleInfo::moduleIconFilename(const CSwordModuleInfo & module) {
+ const CSwordModuleInfo::Category cat(module.m_cachedCategory);
switch (cat) {
case CSwordModuleInfo::Bibles:
- if (module->isLocked()) {
- return CResMgr::modules::bible::icon_locked;
- }
- else {
- return CResMgr::modules::bible::icon_unlocked;
- }
+ return module.isLocked()
+ ? CResMgr::modules::bible::icon_locked
+ : CResMgr::modules::bible::icon_unlocked;
+
case CSwordModuleInfo::Commentaries:
- if (module->isLocked()) {
- return CResMgr::modules::commentary::icon_locked;
- }
- else {
- return CResMgr::modules::commentary::icon_unlocked;
- }
+ return module.isLocked()
+ ? CResMgr::modules::commentary::icon_locked
+ : CResMgr::modules::commentary::icon_unlocked;
+
case CSwordModuleInfo::Lexicons:
- if (module->isLocked()) {
- return CResMgr::modules::lexicon::icon_locked;
- }
- else {
- return CResMgr::modules::lexicon::icon_unlocked;
- }
+ return module.isLocked()
+ ? CResMgr::modules::lexicon::icon_locked
+ : CResMgr::modules::lexicon::icon_unlocked;
+
case CSwordModuleInfo::Books:
- if (module->isLocked()) {
- return CResMgr::modules::book::icon_locked;
- }
- else {
- return CResMgr::modules::book::icon_unlocked;
- }
+ return module.isLocked()
+ ? CResMgr::modules::book::icon_locked
+ : CResMgr::modules::book::icon_unlocked;
+
case CSwordModuleInfo::Cult:
case CSwordModuleInfo::Images:
case CSwordModuleInfo::DailyDevotional:
@@ -936,16 +917,14 @@ const QString &CSwordModuleInfo::moduleIconFilename(
}
}
-QIcon CSwordModuleInfo::categoryIcon(const CSwordModuleInfo::Category &category)
-{
- QString filename = categoryIconFilename(category);
- if (filename.isEmpty()) return QIcon();
- return util::directory::getIcon(filename);
+QIcon CSwordModuleInfo::categoryIcon(const CSwordModuleInfo::Category & category) {
+ const QString filename(categoryIconFilename(category));
+ if (filename.isEmpty())
+ return QIcon();
+ return util::getIcon(filename);
}
-const QString &CSwordModuleInfo::categoryIconFilename(
- const CSwordModuleInfo::Category &category)
-{
+const QString & CSwordModuleInfo::categoryIconFilename(const CSwordModuleInfo::Category & category) {
static const QString noFilename;
switch (category) {
@@ -971,8 +950,7 @@ const QString &CSwordModuleInfo::categoryIconFilename(
}
}
-QString CSwordModuleInfo::categoryName(
- const CSwordModuleInfo::Category &category) {
+QString CSwordModuleInfo::categoryName(const CSwordModuleInfo::Category & category) {
switch (category) {
case CSwordModuleInfo::Bibles:
return tr("Bibles");
@@ -995,7 +973,7 @@ QString CSwordModuleInfo::categoryName(
}
}
-QString CSwordModuleInfo::getSimpleConfigEntry(const QString& name) const {
+QString CSwordModuleInfo::getSimpleConfigEntry(const QString & name) const {
QString ret = isUnicode()
? QString::fromUtf8(m_module->getConfigEntry(name.toUtf8().constData()))
: QString::fromLatin1(m_module->getConfigEntry(name.toUtf8().constData()));
@@ -1003,32 +981,38 @@ QString CSwordModuleInfo::getSimpleConfigEntry(const QString& name) const {
return ret.isEmpty() ? QString::null : ret;
}
-QString CSwordModuleInfo::getFormattedConfigEntry(const QString& name) const {
- sword::SWBuf RTF_Buffer(m_module->getConfigEntry(name.toUtf8().constData()));
- sword::RTFHTML RTF_Filter;
- RTF_Filter.processText(RTF_Buffer, 0, 0);
- QString ret = isUnicode()
- ? QString::fromUtf8(RTF_Buffer.c_str())
- : QString::fromLatin1(RTF_Buffer.c_str());
-
- return ret.isEmpty() ? QString::null : ret;
+/// \note See http://www.crosswire.org/wiki/DevTools:conf_Files#Localization
+QString CSwordModuleInfo::getFormattedConfigEntry(const QString & name) const {
+ const QStringList localeNames(QLocale(CSwordBackend::instance()->booknameLanguage()).uiLanguages());
+ for (int i = localeNames.size() - 1; i >= -1; --i) {
+ sword::SWBuf RTF_Buffer =
+ m_module->getConfigEntry(
+ QString(i >= 0 ? name + "_" + localeNames[i] : name)
+ .toUtf8().constData());
+ if (RTF_Buffer.length() > 0) {
+ sword::RTFHTML RTF_Filter;
+ RTF_Filter.processText(RTF_Buffer, 0, 0);
+ return isUnicode()
+ ? QString::fromUtf8(RTF_Buffer.c_str())
+ : QString::fromLatin1(RTF_Buffer.c_str());
+ }
+ }
+ return QString::null;
}
bool CSwordModuleInfo::setHidden(bool hide) {
- if (m_hidden == hide) return false;
+ if (m_hidden == hide)
+ return false;
m_hidden = hide;
- QStringList hiddenModules(CBTConfig::get(CBTConfig::hiddenModules));
+ QStringList hiddenModules(btConfig().value<QStringList>("state/hiddenModules"));
+ Q_ASSERT(hiddenModules.contains(m_cachedName) != hide);
if (hide) {
- Q_ASSERT(!hiddenModules.contains(name()));
- hiddenModules.append(name());
- }
- else {
- Q_ASSERT(hiddenModules.contains(name()));
- hiddenModules.removeOne(name());
+ hiddenModules.append(m_cachedName);
+ } else {
+ hiddenModules.removeOne(m_cachedName);
}
- CBTConfig::set(CBTConfig::hiddenModules, hiddenModules);
+ btConfig().setValue("state/hiddenModules", hiddenModules);
emit hiddenChanged(hide);
return true;
}
-