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"
35#pragma GCC diagnostic push
36#pragma GCC diagnostic ignored "-Wsuggest-override"
37#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>
51#pragma clang diagnostic pop
54#pragma GCC diagnostic pop
61 : m_manager(nullptr, nullptr, false,
62 new
sword::EncodingFilterMgr(
sword::ENC_UTF8), true)
65 auto const clearCache =
69 std::memory_order_relaxed);
85 : m_manager(!path.isEmpty() ? path.toLocal8Bit().constData() : nullptr,
86 false, new
sword::EncodingFilterMgr(
sword::ENC_UTF8),
104std::shared_ptr<CSwordBackend::AvailableLanguagesCacheContainer const>
110 auto const generateCache =
113 for (
auto const *
const mod :
model.moduleList()) {
114 newCache.emplace(mod->language());
115 if (
auto lang2 = mod->glossaryTargetlanguage())
116 newCache.emplace(std::move(lang2));
119 return std::make_shared<AvailableLanguagesCacheContainer const>(
120 std::move(newCache));
123 for (
auto newCache = generateCache();; newCache = generateCache())
127 std::memory_order_acq_rel,
128 std::memory_order_relaxed))
133 if (toBeDeleted.empty())
139 QMap<QString, sword::SWMgr *> mgrDict;
143 if (dataPath.left(2) == QStringLiteral(
"./"))
144 dataPath = dataPath.mid(2);
153 qWarning() <<
"Removing" << mInfo->name()
154 <<
"didn't succeed because the absolute path"
155 <<
prefixPath <<
"didn't contain the data path"
167 qDebug() <<
"Removing the module" << mInfo->name() <<
"...";
168 installMgr.removeModule(mgr, mInfo->swordModule().getName());
170 qDeleteAll(toBeDeleted);
176 QList<CSwordModuleInfo *> list;
177 for (
auto const & name : names)
185 for (
auto const & name : names)
199 for (
auto const & modulePair :
m_manager.getModules()) {
200 sword::SWModule *
const curMod = modulePair.second;
202 std::unique_ptr<CSwordModuleInfo> newModule;
204 std::string_view
const modType = curMod->getType();
205 using namespace std::literals;
206 if (modType ==
"Biblical Texts"sv) {
207 newModule = std::make_unique<CSwordBibleModuleInfo>(*curMod, *
this);
208 }
else if (modType ==
"Commentaries"sv) {
209 newModule = std::make_unique<CSwordCommentaryModuleInfo>(*curMod,
211 }
else if (modType ==
"Lexicons / Dictionaries"sv) {
212 newModule = std::make_unique<CSwordLexiconModuleInfo>(*curMod,
214 }
else if (modType ==
"Generic Books"sv) {
215 newModule = std::make_unique<CSwordBookModuleInfo>(*curMod, *
this);
222 if (!newModule->hasVersion()
223 || (newModule->minimumSwordVersion() <= sword::SWVersion::currentVersion))
232 if (newModule->isEncrypted()) {
233 auto const unlockKey(
234 btConfig().getModuleEncryptionKey(newModule->name()));
235 if (!unlockKey.isNull())
237 newModule->name().toUtf8().constData(),
238 unlockKey.toUtf8().constData());
252 sword::ConfigEntMap & section)
254 auto entry(section.find(
"SourceType"));
255 if (entry != section.end()) {
256 if (entry->second ==
"OSIS") {
257 module->addRenderFilter(&m_osisFilter);
259 }
else if (entry->second ==
"ThML") {
260 module->addRenderFilter(&m_thmlFilter);
262 }
else if (entry->second ==
"TEI") {
263 module->addRenderFilter(&m_teiFilter);
265 }
else if (entry->second ==
"GBF") {
266 module->addRenderFilter(&m_gbfFilter);
268 }
else if (entry->second ==
"PLAIN") {
269 module->addRenderFilter(&m_plainFilter);
275 entry = section.find(
"ModDrv");
276 if (entry != section.end() && (entry->second ==
"RawCom" || entry->second ==
"RawLD"))
277 module->addRenderFilter(&m_plainFilter);
294 for (
auto const & filterPair : cipherFilters) {
296 cleanupFilters.remove(filterPair.second);
297 delete filterPair.second;
299 cipherFilters.clear();
324 if (mod->name().compare(name, Qt::CaseInsensitive) == 0)
331 if (&mod->swordModule() == swmodule)
355 for (
auto const *
const mod :
m_dataModel->moduleList())
356 mod->swordModule().getKey()->setLocale(newLocaleName.constData());
370 config = myconfig =
nullptr;
372 findConfig(&configType, &
prefixPath, &configPath, &augPaths, &sysConfig);
374 loadConfigDir(configPath);
384 QList<QFileInfo> configs;
387 if (
auto conf = QFileInfo(userHomeSwordDir, QStringLiteral(
"sword.conf"));
391 configs << std::move(conf);
399 auto const swordPath = qEnvironmentVariable(
"SWORD_PATH");
400 for (
auto const & path : swordPath.split(QDir::listSeparator())) {
408 swordDirSet << dir.absolutePath();
411 if (
auto conf = QFileInfo(dir, QStringLiteral(
"Sword/sword.conf"));
413 configs << std::move(conf);
418 for (
auto const & path : QString(
m_manager.globalConfPath).split(
':'))
419 if (
auto conf = QFileInfo(path); conf.exists())
420 configs << std::move(conf);
425 static constexpr auto const decoderFlags = QStringDecoder::Flag::Stateless;
426 for (
auto const & fileInfo : configs) {
431 sword::SWConfig conf(fileInfo.absoluteFilePath().toUtf8().constData());
433 static auto const decodeConfEntry =
434 [](sword::SWBuf
const & buf) {
435 QStringDecoder utf8Decoder(
"UTF-8", decoderFlags);
437 QString result = utf8Decoder(buf.c_str());
438 if (!utf8Decoder.hasError())
440 QStringDecoder cp1252Decoder(
"Windows-1252", decoderFlags);
441 result = cp1252Decoder(buf.c_str());
442 if (!cp1252Decoder.hasError())
444 return QString::fromLatin1(buf.c_str());
447 swordDirSet << QDir(decodeConfEntry(conf[
"Install"][
"DataPath"])).absolutePath();
449 const sword::ConfigEntMap group(conf[
"Install"]);
450 for (
auto its = group.equal_range(
"AugmentPath");
451 its.first != its.second;
455 swordDirSet << QDir(decodeConfEntry(its.first->second)).absolutePath();
460 swordDirSet << userHomeSwordDir.absolutePath();
462 QStringList swordDirs;
463 for (
auto dir: swordDirSet)
464 swordDirs.append(dir);
470 for (
auto const & entry : entries) {
471 if (entry ==
'.' || entry == QStringLiteral(
".."))
474 if (!module->hasIndex()) {
475 qDebug() <<
"deleting outdated index for module" << entry;
481 "settings/behaviour/autoDeleteOrphanedIndices"),
true))
483 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.
std::atomic< std::shared_ptr< AvailableLanguagesCacheContainer const > > m_availableLanguagesCache
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.
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