20 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
21 #include <QStringDecoder>
23 #include <string_view>
24 #include "../../util/btconnect.h"
25 #include "../../util/directory.h"
26 #include "../btglobal.h"
27 #include "../btinstallmgr.h"
28 #include "../config/btconfig.h"
29 #include "../drivers/cswordbiblemoduleinfo.h"
30 #include "../drivers/cswordbookmoduleinfo.h"
31 #include "../drivers/cswordcommentarymoduleinfo.h"
32 #include "../drivers/cswordlexiconmoduleinfo.h"
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wsuggest-override"
38 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
40 #pragma clang diagnostic push
41 #pragma clang diagnostic ignored "-Wsuggest-destructor-override"
43 #include <encfiltmgr.h>
46 #include <swfiltermgr.h>
48 #include <swversion.h>
51 #pragma clang diagnostic pop
53 #pragma GCC diagnostic pop
59 : m_manager(nullptr, nullptr, false,
60 new
sword::EncodingFilterMgr(
sword::ENC_UTF8), true)
63 auto const clearCache =
65 std::atomic_store_explicit(
68 std::memory_order_relaxed);
84 : m_manager(!path.isEmpty() ? path.toLocal8Bit().constData() : nullptr,
85 false, new
sword::EncodingFilterMgr(
sword::ENC_UTF8),
103 std::shared_ptr<CSwordBackend::AvailableLanguagesCacheContainer const>
107 std::memory_order_acquire);
111 auto const generateCache =
114 for (
auto const *
const mod :
model.moduleList()) {
115 newCache.emplace(mod->language());
116 if (
auto lang2 = mod->glossaryTargetlanguage())
117 newCache.emplace(std::move(lang2));
120 return std::make_shared<AvailableLanguagesCacheContainer const>(
121 std::move(newCache));
124 for (
auto newCache = generateCache();; newCache = generateCache())
125 if (std::atomic_compare_exchange_strong_explicit(
129 std::memory_order_acq_rel,
130 std::memory_order_relaxed))
135 if (toBeDeleted.empty())
141 QMap<QString, sword::SWMgr *> mgrDict;
145 if (dataPath.left(2) == QStringLiteral(
"./"))
146 dataPath = dataPath.mid(2);
155 qWarning() <<
"Removing" << mInfo->name()
156 <<
"didn't succeed because the absolute path"
157 <<
prefixPath <<
"didn't contain the data path"
169 qDebug() <<
"Removing the module" << mInfo->name() <<
"...";
170 installMgr.removeModule(mgr, mInfo->swordModule().getName());
172 qDeleteAll(toBeDeleted);
179 for (
auto const & name : names)
187 for (
auto const & name : names)
201 for (
auto const & modulePair :
m_manager.getModules()) {
202 sword::SWModule *
const curMod = modulePair.second;
204 std::unique_ptr<CSwordModuleInfo> newModule;
206 std::string_view
const modType = curMod->getType();
207 using namespace std::literals;
208 if (modType ==
"Biblical Texts"sv) {
209 newModule = std::make_unique<CSwordBibleModuleInfo>(*curMod, *
this);
210 }
else if (modType ==
"Commentaries"sv) {
211 newModule = std::make_unique<CSwordCommentaryModuleInfo>(*curMod,
213 }
else if (modType ==
"Lexicons / Dictionaries"sv) {
214 newModule = std::make_unique<CSwordLexiconModuleInfo>(*curMod,
216 }
else if (modType ==
"Generic Books"sv) {
217 newModule = std::make_unique<CSwordBookModuleInfo>(*curMod, *
this);
224 if (!newModule->hasVersion()
225 || (newModule->minimumSwordVersion() <= sword::SWVersion::currentVersion))
234 if (newModule->isEncrypted()) {
235 auto const unlockKey(
236 btConfig().getModuleEncryptionKey(newModule->name()));
237 if (!unlockKey.isNull())
239 newModule->name().toUtf8().constData(),
240 unlockKey.toUtf8().constData());
254 sword::ConfigEntMap & section)
256 auto entry(section.find(
"SourceType"));
257 if (entry != section.end()) {
258 if (entry->second ==
"OSIS") {
259 module->addRenderFilter(&m_osisFilter);
261 }
else if (entry->second ==
"ThML") {
262 module->addRenderFilter(&m_thmlFilter);
264 }
else if (entry->second ==
"TEI") {
265 module->addRenderFilter(&m_teiFilter);
267 }
else if (entry->second ==
"GBF") {
268 module->addRenderFilter(&m_gbfFilter);
270 }
else if (entry->second ==
"PLAIN") {
271 module->addRenderFilter(&m_plainFilter);
277 entry = section.find(
"ModDrv");
278 if (entry != section.end() && (entry->second ==
"RawCom" || entry->second ==
"RawLD"))
279 module->addRenderFilter(&m_plainFilter);
296 for (
auto const & filterPair : cipherFilters) {
298 cleanupFilters.remove(filterPair.second);
299 delete filterPair.second;
301 cipherFilters.clear();
326 if (mod->name().compare(name, Qt::CaseInsensitive) == 0)
333 if (&mod->swordModule() == swmodule)
357 for (
auto const *
const mod :
m_dataModel->moduleList())
358 mod->swordModule().getKey()->setLocale(newLocaleName.constData());
372 config = myconfig =
nullptr;
391 if (
auto conf = QFileInfo(userHomeSwordDir, QStringLiteral(
"sword.conf"));
395 configs << std::move(conf);
403 auto const swordPath = qEnvironmentVariable(
"SWORD_PATH");
404 for (
auto const & path : swordPath.split(QDir::listSeparator())) {
412 swordDirSet << dir.absolutePath();
415 if (
auto conf = QFileInfo(dir, QStringLiteral(
"Sword/sword.conf"));
417 configs << std::move(conf);
422 for (
auto const & path : QString(
m_manager.globalConfPath).split(
':'))
423 if (
auto conf = QFileInfo(path); conf.exists())
424 configs << std::move(conf);
429 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
430 static constexpr
auto const decoderFlags = QStringDecoder::Flag::Stateless;
432 for (
auto const & fileInfo : configs) {
437 sword::SWConfig conf(fileInfo.absoluteFilePath().toUtf8().constData());
439 static auto const decodeConfEntry =
440 [](sword::SWBuf
const & buf) {
441 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
442 return QString::fromUtf8(buf.c_str());
444 QStringDecoder utf8Decoder(
"UTF-8", decoderFlags);
446 QString result = utf8Decoder(buf.c_str());
447 if (!utf8Decoder.hasError())
449 QStringDecoder cp1252Decoder(
"Windows-1252", decoderFlags);
450 result = cp1252Decoder(buf.c_str());
451 if (!cp1252Decoder.hasError())
453 return QString::fromLatin1(buf.c_str());
457 swordDirSet << QDir(decodeConfEntry(conf[
"Install"][
"DataPath"])).absolutePath();
459 const sword::ConfigEntMap group(conf[
"Install"]);
460 for (
auto its = group.equal_range(
"AugmentPath");
461 its.first != its.second;
465 swordDirSet << QDir(decodeConfEntry(its.first->second)).absolutePath();
470 swordDirSet << userHomeSwordDir.absolutePath();
472 QStringList swordDirs;
473 for (
auto dir: swordDirSet)
474 swordDirs.append(dir);
480 for (
auto const & entry : entries) {
481 if (entry ==
'.' || entry == QStringLiteral(
".."))
484 if (!module->hasIndex()) {
485 qDebug() <<
"deleting outdated index for module" << entry;
491 "settings/behaviour/autoDeleteOrphanedIndices"),
true))
493 qDebug() <<
"deleting orphaned index in directory" << entry;
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
QList< CSwordModuleInfo const * > BtConstModuleList
The backend layer main class, a backend implementation of Sword.
void shutdownModules()
Deinitializes and frees the modules.
void setOption(CSwordModuleInfo::FilterOption const &type, const int state)
Sets the state of the given filter option.
std::shared_ptr< AvailableLanguagesCacheContainer const > availableLanguages() noexcept
CSwordBackend::LoadError initModules()
Initializes the Sword modules.
QStringList swordDirList() const
Sword prefix list.
std::set< std::shared_ptr< Language const > > AvailableLanguagesCacheContainer
static CSwordBackend * m_instance
void reloadModules()
Reloads all Sword modules.
std::shared_ptr< BtBookshelfModel > const m_dataModel
QList< CSwordModuleInfo * > getPointerList(const QStringList &names) const
CSwordModuleInfo * findFirstAvailableModule(CSwordModuleInfo::ModuleType type)
CSwordBackend::Private m_manager
void deleteOrphanedIndices()
QList< CSwordModuleInfo * > const & moduleList() const
CSwordModuleInfo * findModuleByName(const QString &name) const
Searches for a module with the given name.
QString prefixPath() const
void uninstallModules(BtConstModuleSet const &modules)
Uninstalls the given modules.
void sigSwordSetupChanged()
CSwordBackend()
Creates the regular CSwordBackend instance.
BtConstModuleList getConstPointerList(const QStringList &names) const
LoadError
The error codes which may be returned by the Load() call.
void setFilterOptions(const FilterOptions &options)
CSwordModuleInfo * findSwordModuleByPointer(const sword::SWModule *const swmodule) const
Searches for a module with the given sword module as module().
~CSwordBackend() override
void setBooknameLanguage(QString const &langName)
Sets the language for the international booknames of Sword.
std::shared_ptr< AvailableLanguagesCacheContainer const > m_availableLanguagesCache
std::shared_ptr< BtBookshelfModel > model()
QString booknameLanguage() const
static FilterOption const redLetterWords
static FilterOption const headings
static FilterOption const textualVariants
static void deleteIndexForModule(const QString &name)
static FilterOption const hebrewPoints
static QString getGlobalBaseIndexLocation()
static FilterOption const strongNumbers
static FilterOption const morphTags
static FilterOption const scriptureReferences
static FilterOption const hebrewCantillation
static FilterOption const morphSegmentation
static FilterOption const greekAccents
static FilterOption const footnotes
static FilterOption const lemmas
QString defaultLocaleName()
void setDefaultLocaleName(QString const &localeName)
const QDir & getUserHomeSwordDir()
void addRenderFilters(sword::SWModule *module, sword::ConfigEntMap §ion) override
char const *(* valueToString)(int value) noexcept