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 =
65 std::memory_order_relaxed);
81 : m_manager(!path.isEmpty() ? path.toLocal8Bit().constData() : nullptr,
82 false, new
sword::EncodingFilterMgr(
sword::ENC_UTF8),
100std::shared_ptr<CSwordBackend::AvailableLanguagesCacheContainer const>
106 auto const generateCache =
109 for (
auto const *
const mod :
model.moduleList()) {
110 newCache.emplace(mod->language());
111 if (
auto lang2 = mod->glossaryTargetlanguage())
112 newCache.emplace(std::move(lang2));
115 return std::make_shared<AvailableLanguagesCacheContainer const>(
116 std::move(newCache));
119 for (
auto newCache = generateCache();; newCache = generateCache())
123 std::memory_order_acq_rel,
124 std::memory_order_relaxed))
129 if (toBeDeleted.empty())
135 QMap<QString, sword::SWMgr *> mgrDict;
139 if (dataPath.left(2) == QStringLiteral(
"./"))
140 dataPath = dataPath.mid(2);
149 qWarning() <<
"Removing" << mInfo->name()
150 <<
"didn't succeed because the absolute path"
151 <<
prefixPath <<
"didn't contain the data path"
163 qDebug() <<
"Removing the module" << mInfo->name() <<
"...";
164 installMgr.removeModule(mgr, mInfo->swordModule().getName());
166 qDeleteAll(toBeDeleted);
172 QList<CSwordModuleInfo *> list;
173 for (
auto const & name : names)
181 for (
auto const & name : names)
195 for (
auto const & modulePair :
m_manager.getModules()) {
196 sword::SWModule *
const curMod = modulePair.second;
198 std::unique_ptr<CSwordModuleInfo> newModule;
200 std::string_view
const modType = curMod->getType();
201 using namespace std::literals;
202 if (modType ==
"Biblical Texts"sv) {
203 newModule = std::make_unique<CSwordBibleModuleInfo>(*curMod, *
this);
204 }
else if (modType ==
"Commentaries"sv) {
205 newModule = std::make_unique<CSwordCommentaryModuleInfo>(*curMod,
207 }
else if (modType ==
"Lexicons / Dictionaries"sv) {
208 newModule = std::make_unique<CSwordLexiconModuleInfo>(*curMod,
210 }
else if (modType ==
"Generic Books"sv) {
211 newModule = std::make_unique<CSwordBookModuleInfo>(*curMod, *
this);
218 if (!newModule->hasVersion()
219 || (newModule->minimumSwordVersion() <= sword::SWVersion::currentVersion))
228 if (newModule->isEncrypted()) {
229 auto const unlockKey(
230 btConfig().getModuleEncryptionKey(newModule->name()));
231 if (!unlockKey.isNull())
233 newModule->name().toUtf8().constData(),
234 unlockKey.toUtf8().constData());
248 sword::ConfigEntMap & section)
250 auto entry(section.find(
"SourceType"));
251 if (entry != section.end()) {
252 if (entry->second ==
"OSIS") {
253 module->addRenderFilter(&m_osisFilter);
255 }
else if (entry->second ==
"ThML") {
256 module->addRenderFilter(&m_thmlFilter);
258 }
else if (entry->second ==
"TEI") {
259 module->addRenderFilter(&m_teiFilter);
261 }
else if (entry->second ==
"GBF") {
262 module->addRenderFilter(&m_gbfFilter);
264 }
else if (entry->second ==
"PLAIN") {
265 module->addRenderFilter(&m_plainFilter);
271 entry = section.find(
"ModDrv");
272 if (entry != section.end() && (entry->second ==
"RawCom" || entry->second ==
"RawLD"))
273 module->addRenderFilter(&m_plainFilter);
290 for (
auto const & filterPair : cipherFilters) {
292 cleanupFilters.remove(filterPair.second);
293 delete filterPair.second;
295 cipherFilters.clear();
320 if (mod->name().compare(name, Qt::CaseInsensitive) == 0)
327 if (&mod->swordModule() == swmodule)
351 for (
auto const *
const mod :
m_dataModel->moduleList())
352 mod->swordModule().getKey()->setLocale(newLocaleName.constData());
366 config = myconfig =
nullptr;
368 findConfig(&configType, &
prefixPath, &configPath, &augPaths, &sysConfig);
370 loadConfigDir(configPath);
380 QList<QFileInfo> configs;
383 if (
auto conf = QFileInfo(userHomeSwordDir, QStringLiteral(
"sword.conf"));
387 configs << std::move(conf);
395 auto const swordPath = qEnvironmentVariable(
"SWORD_PATH");
396 for (
auto const & path : swordPath.split(QDir::listSeparator())) {
404 swordDirSet << dir.absolutePath();
407 if (
auto conf = QFileInfo(dir, QStringLiteral(
"Sword/sword.conf"));
409 configs << std::move(conf);
414 for (
auto const & path : QString(
m_manager.globalConfPath).split(
':'))
415 if (
auto conf = QFileInfo(path); conf.exists())
416 configs << std::move(conf);
421 static constexpr auto const decoderFlags = QStringDecoder::Flag::Stateless;
422 for (
auto const & fileInfo : configs) {
427 sword::SWConfig conf(fileInfo.absoluteFilePath().toUtf8().constData());
429 static auto const decodeConfEntry =
430 [](sword::SWBuf
const & buf) {
431 QStringDecoder utf8Decoder(
"UTF-8", decoderFlags);
433 QString result = utf8Decoder(buf.c_str());
434 if (!utf8Decoder.hasError())
436 QStringDecoder cp1252Decoder(
"Windows-1252", decoderFlags);
437 result = cp1252Decoder(buf.c_str());
438 if (!cp1252Decoder.hasError())
440 return QString::fromLatin1(buf.c_str());
443 swordDirSet << QDir(decodeConfEntry(conf[
"Install"][
"DataPath"])).absolutePath();
445 const sword::ConfigEntMap group(conf[
"Install"]);
446 for (
auto its = group.equal_range(
"AugmentPath");
447 its.first != its.second;
451 swordDirSet << QDir(decodeConfEntry(its.first->second)).absolutePath();
456 swordDirSet << userHomeSwordDir.absolutePath();
458 QStringList swordDirs;
459 for (
auto dir: swordDirSet)
460 swordDirs.append(dir);
466 for (
auto const & entry : entries) {
467 if (entry ==
'.' || entry == QStringLiteral(
".."))
470 if (!module->hasIndex()) {
471 qDebug() <<
"deleting outdated index for module" << entry;
477 "settings/behaviour/autoDeleteOrphanedIndices"),
true))
479 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