20#include <QStringDecoder>
22#include "../../util/btconnect.h"
23#include "../../util/directory.h"
24#include "../btglobal.h"
25#include "../btinstallmgr.h"
26#include "../config/btconfig.h"
27#include "../drivers/cswordbiblemoduleinfo.h"
28#include "../drivers/cswordbookmoduleinfo.h"
29#include "../drivers/cswordcommentarymoduleinfo.h"
30#include "../drivers/cswordlexiconmoduleinfo.h"
34#pragma GCC diagnostic push
35#pragma GCC diagnostic ignored "-Wsuggest-override"
36#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
38#pragma clang diagnostic push
39#pragma clang diagnostic ignored "-Wsuggest-destructor-override"
41#include <encfiltmgr.h>
44#include <swfiltermgr.h>
49#pragma clang diagnostic pop
51#pragma GCC diagnostic pop
57 : m_manager(nullptr, nullptr, false,
58 new
sword::EncodingFilterMgr(
sword::ENC_UTF8), true)
61 auto const clearCache =
63 #if __cplusplus >= 202002L
66 std::atomic_store_explicit(
70 std::memory_order_relaxed);
86 : m_manager(!path.isEmpty() ? path.toLocal8Bit().constData() : nullptr,
87 false, new
sword::EncodingFilterMgr(
sword::ENC_UTF8),
105std::shared_ptr<CSwordBackend::AvailableLanguagesCacheContainer const>
107 #if __cplusplus >= 202002L
111 std::memory_order_acquire);
116 auto const generateCache =
119 for (
auto const *
const mod :
model.moduleList()) {
120 newCache.emplace(mod->language());
121 if (
auto lang2 = mod->glossaryTargetlanguage())
122 newCache.emplace(std::move(lang2));
125 return std::make_shared<AvailableLanguagesCacheContainer const>(
126 std::move(newCache));
129 for (
auto newCache = generateCache();; newCache = generateCache())
130 #
if __cplusplus >= 202002L
134 if (std::atomic_compare_exchange_strong_explicit(
139 std::memory_order_acq_rel,
140 std::memory_order_relaxed))
145 if (toBeDeleted.empty())
151 QMap<QString, sword::SWMgr *> mgrDict;
155 if (dataPath.left(2) == QStringLiteral(
"./"))
156 dataPath = dataPath.mid(2);
165 qWarning() <<
"Removing" << mInfo->name()
166 <<
"didn't succeed because the absolute path"
167 <<
prefixPath <<
"didn't contain the data path"
179 qDebug() <<
"Removing the module" << mInfo->name() <<
"...";
180 installMgr.removeModule(mgr, mInfo->swordModule().getName());
182 qDeleteAll(toBeDeleted);
188 QList<CSwordModuleInfo *> list;
189 for (
auto const & name : names)
197 for (
auto const & name : names)
211 for (
auto const & modulePair :
m_manager.getModules()) {
212 sword::SWModule *
const curMod = modulePair.second;
214 std::unique_ptr<CSwordModuleInfo> newModule;
216 std::string_view
const modType = curMod->getType();
217 using namespace std::literals;
218 if (modType ==
"Biblical Texts"sv) {
219 newModule = std::make_unique<CSwordBibleModuleInfo>(*curMod, *
this);
220 }
else if (modType ==
"Commentaries"sv) {
221 newModule = std::make_unique<CSwordCommentaryModuleInfo>(*curMod,
223 }
else if (modType ==
"Lexicons / Dictionaries"sv) {
224 newModule = std::make_unique<CSwordLexiconModuleInfo>(*curMod,
226 }
else if (modType ==
"Generic Books"sv) {
227 newModule = std::make_unique<CSwordBookModuleInfo>(*curMod, *
this);
234 if (!newModule->hasVersion()
235 || (newModule->minimumSwordVersion() <= sword::SWVersion::currentVersion))
244 if (newModule->isEncrypted()) {
245 auto const unlockKey(
246 btConfig().getModuleEncryptionKey(newModule->name()));
247 if (!unlockKey.isNull())
249 newModule->name().toUtf8().constData(),
250 unlockKey.toUtf8().constData());
264 sword::ConfigEntMap & section)
266 auto entry(section.find(
"SourceType"));
267 if (entry != section.end()) {
268 if (entry->second ==
"OSIS") {
269 module->addRenderFilter(&m_osisFilter);
271 }
else if (entry->second ==
"ThML") {
272 module->addRenderFilter(&m_thmlFilter);
274 }
else if (entry->second ==
"TEI") {
275 module->addRenderFilter(&m_teiFilter);
277 }
else if (entry->second ==
"GBF") {
278 module->addRenderFilter(&m_gbfFilter);
280 }
else if (entry->second ==
"PLAIN") {
281 module->addRenderFilter(&m_plainFilter);
287 entry = section.find(
"ModDrv");
288 if (entry != section.end() && (entry->second ==
"RawCom" || entry->second ==
"RawLD"))
289 module->addRenderFilter(&m_plainFilter);
306 for (
auto const & filterPair : cipherFilters) {
308 cleanupFilters.remove(filterPair.second);
309 delete filterPair.second;
311 cipherFilters.clear();
336 if (mod->name().compare(name, Qt::CaseInsensitive) == 0)
343 if (&mod->swordModule() == swmodule)
367 for (
auto const *
const mod :
m_dataModel->moduleList())
368 mod->swordModule().getKey()->setLocale(newLocaleName.constData());
382 config = myconfig =
nullptr;
384 findConfig(&configType, &
prefixPath, &configPath, &augPaths, &sysConfig);
386 loadConfigDir(configPath);
396 QList<QFileInfo> configs;
399 if (
auto conf = QFileInfo(userHomeSwordDir, QStringLiteral(
"sword.conf"));
403 configs << std::move(conf);
411 auto const swordPath = qEnvironmentVariable(
"SWORD_PATH");
412 for (
auto const & path : swordPath.split(QDir::listSeparator())) {
420 swordDirSet << dir.absolutePath();
423 if (
auto conf = QFileInfo(dir, QStringLiteral(
"Sword/sword.conf"));
425 configs << std::move(conf);
430 for (
auto const & path : QString(
m_manager.globalConfPath).split(
':'))
431 if (
auto conf = QFileInfo(path); conf.exists())
432 configs << std::move(conf);
437 static constexpr auto const decoderFlags = QStringDecoder::Flag::Stateless;
438 for (
auto const & fileInfo : configs) {
443 sword::SWConfig conf(fileInfo.absoluteFilePath().toUtf8().constData());
445 static auto const decodeConfEntry =
446 [](sword::SWBuf
const & buf) {
447 QStringDecoder utf8Decoder(
"UTF-8", decoderFlags);
449 QString result = utf8Decoder(buf.c_str());
450 if (!utf8Decoder.hasError())
452 QStringDecoder cp1252Decoder(
"Windows-1252", decoderFlags);
453 result = cp1252Decoder(buf.c_str());
454 if (!cp1252Decoder.hasError())
456 return QString::fromLatin1(buf.c_str());
459 swordDirSet << QDir(decodeConfEntry(conf[
"Install"][
"DataPath"])).absolutePath();
461 const sword::ConfigEntMap group(conf[
"Install"]);
462 for (
auto its = group.equal_range(
"AugmentPath");
463 its.first != its.second;
467 swordDirSet << QDir(decodeConfEntry(its.first->second)).absolutePath();
472 swordDirSet << userHomeSwordDir.absolutePath();
474 QStringList swordDirs;
475 for (
auto dir: swordDirSet)
476 swordDirs.append(dir);
482 for (
auto const & entry : entries) {
483 if (entry ==
'.' || entry == QStringLiteral(
".."))
486 if (!module->hasIndex()) {
487 qDebug() <<
"deleting outdated index for module" << entry;
493 "settings/behaviour/autoDeleteOrphanedIndices"),
true))
495 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.
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
std::shared_ptr< AvailableLanguagesCacheContainer const > availableLanguages() noexcept
void reloadModules()
Reloads all Sword modules.
std::shared_ptr< BtBookshelfModel > const m_dataModel
QList< CSwordModuleInfo * > getPointerList(const QStringList &names) const
std::shared_ptr< BtBookshelfModel > model()
CSwordModuleInfo * findFirstAvailableModule(CSwordModuleInfo::ModuleType type)
CSwordBackend::Private m_manager
void deleteOrphanedIndices()
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.
QList< CSwordModuleInfo * > const & moduleList() const
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
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