BibleTime
cswordmoduleinfo.h
Go to the documentation of this file.
1/*********
2*
3* In the name of the Father, and of the Son, and of the Holy Spirit.
4*
5* This file is part of BibleTime's source code, https://bibletime.info/
6*
7* Copyright 1999-2025 by the BibleTime developers.
8* The BibleTime source code is licensed under the GNU General Public License
9* version 2.0.
10*
11**********/
12
13#pragma once
14
15#include <QObject>
16
17#include <atomic>
18#include <memory>
19#include <QIcon>
20#include <QMetaType>
21#include <QString>
22#include <QtGlobal>
23#include "../cswordmodulesearch.h"
24#include "../language.h"
25
26
27// CLucene no longer lists the following functions in its headers
28extern size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen);
29extern size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen);
30
31class CSwordBackend;
32class CSwordKey;
33namespace sword {
34class ListKey;
35class SWModule;
36class SWVersion;
37} // namespace sword
38
39/**
40 * Base class for Sword modules.
41 * This is the base class for all Sword modules. Every class handling a special Sword module type
42 * does inherit from this class.
43 *
44 * @author The BibleTime team
45 * @version $Id: cswordmoduleinfo.h,v 1.83 2007/02/04 23:12:32 joachim Exp $
46 */
47
49
50 Q_OBJECT
51
52public: // types:
53
54 struct FilterOption {
55 static char const * valueToOnOff(int value) noexcept;
56 static char const * valueToReadings(int value) noexcept;
57
58 char const * optionName;
59 std::string configOptionName;
61 char const * (*valueToString)(int value) noexcept = &valueToOnOff;
62 };
63
64 /* These are the options which could be supported by modules and by this
65 backend: */
66 static FilterOption const footnotes; /**< Footnotes embedded in the module's text */
67 static FilterOption const strongNumbers; /**< strong numbers, usually in the text for the info display */
68 static FilterOption const headings; /**< additional section headings */
69 static FilterOption const morphTags; /**< morphology */
70 static FilterOption const lemmas; /**< lemma tags */
71 static FilterOption const hebrewPoints;/**< Hebrew vowel points */
72 static FilterOption const hebrewCantillation; /**< Hebrew cantillation points */
73 static FilterOption const greekAccents; /**< Greek accents may be switched on and off */
74 static FilterOption const scriptureReferences; /**< scripture references may be switched on and off, just makes sense in Bibles */
75 static FilterOption const redLetterWords; /**< Jesus words in red, color is template specific */
76 static FilterOption const textualVariants; /**< variants */
77 static FilterOption const morphSegmentation; /**< morph word segmentation, supported by OSIS */
78
79 /** The text direction of a module */
80 enum TextDirection { /* The text direction of the modules's text */
81 LeftToRight, /**< Left to right text direction, the default setting */
82 RightToLeft /**< Right to left text directin, e.g. for hebrew */
83 };
84
85 /** The module type. */
87 Bible, /**< Bible module */
88 Commentary, /**< Commentary module */
89 Lexicon, /**< Lexicon module */
90 GenericBook, /**< Generic book module */
91 };
92
93 /**
94 * This enum is used to give
95 * back an error code after unlocking the module
96 * BibleTime stores the unlock key not in the module's config file but in BibleTime's
97 * configuration file.
98 */
100 noError, /**< No error occured, everything worked ok. The key was written to the BibleTime config */
101 wrongUnlockKey, /**< The wrong key was used. Module is not unlocked */
102 notLocked, /**< The module was not locked so it can't be unlocked */
103 noPermission /**< The key was not written to config because we have no permissions */
104 };
105
107 AboutInformation, /**< The about information of a module which is stored in the config file*/
108 AbsoluteDataPath, /**< The absolute data path stored in the config object */
109 CipherKey, /**< The cipher key which was used to unlock the module. Not necessarily set.*/
110 DataPath, /**< The relative path. See AbsoluteDataPath*/
111 Description, /**< The module description stored in the config file */
112 ModuleVersion, /**< The module's version.*/
113 MinimumSwordVersion, /**< The required Sword Version of this module. Otherwise some things may not work (compression etc.).*/
114 TextDir, /**< The text direction */
115 DisplayLevel, /**< Mostly used for books. Gives the level which should contain the connected entries.*/
116 GlossaryFrom, /**< lamguage from which the Glosaary tramslates */
117 GlossaryTo, /**< lamguages to which the glossary maps to */
128 Markup /**< The markup of this module */
129 };
130
142 Q_DECLARE_FLAGS(Features, Feature)
143
144 enum class Category {
145 Bibles = 0x01,
146 Commentaries = 0x02,
147 Books = 0x04,
148 Lexicons = 0x08,
149 Glossaries = 0x10,
150 DailyDevotionals = 0x20,
151 MapsAndImages = 0x40,
152 Questionable = 0x80,
153 };
154 Q_DECLARE_FLAGS(Categories, Category)
155
156public: // methods:
163 /**
164 * Returns the base directory for search indices
165 */
166 static QString getGlobalBaseIndexLocation();
168 /**
169 Removes the search index for this module (rm -rf).
170 */
171 void deleteIndex();
173 /**
174 Removes search index for a module, even if the module is not there any more.
175 \param[in] name name of the module.
176 */
177 static void deleteIndexForModule(const QString & name);
178
179 /**
180 * Returns the config entry which is pecified by the parameter.
181 */
182 QString config(const CSwordModuleInfo::ConfigEntry entry) const;
183
184 /**
185 * Returns the module object so all objects can access the original Sword module.
186 */
187 sword::SWModule & swordModule() const { return m_swordModule; }
188
189 /**
190 * Sets the unlock key of the modules and writes the key into the config file.
191 * @return True if the unlock process was succesful, if the key was
192wrong, or if the config file was write protected return false.
193 */
194 bool unlock(const QString & unlockKey);
195
196 /**
197 * This function does return true if the data files of the module are encrypted by the module author
198 * (the on who made the module) no matter if it's locked or not.
199 * @return True if this module is encryped
200 */
201 bool isEncrypted() const;
203 /**
204 * Gets the "UnlockInfo" tag value from the module's config file
205 * @return Unlock information string (may be empty if not specified for module)
206 **/
207 QString getUnlockInfo();
208
209 /**
210 * This function returns true if this module is locked (encrypted + correct cipher key),
211 * otherwise return false.
212 * @return True if this module is locked, i.e. encrypted but without a key set
213 */
214 bool isLocked() const;
215
216 /**
217 This function makes an estimate if a module was properly unlocked. It
218 returns true if the first entry of the module is not empty and
219 contains only printable characters (for the first 100 chars or so). If
220 that is the case, we can safely assume that a) the module was properly
221 unlocked and b) no buffer overflows will occur, which can happen when
222 Sword filters process garbage text which was not properly decrypted.
223 */
224 bool unlockKeyIsValid() const;
225
226 /**
227 \retval true if this module has a version number
228 \retval false if it doesn't have a version number
229 */
230 bool hasVersion() const { return m_cachedHasVersion; }
231
232 /**
233 \returns true if the module's index has been built.
234 */
235 bool hasIndex() const;
236
237 /**
238 \returns the path to this module's index base dir
239 */
240 QString getModuleBaseIndexLocation() const;
241
242 /**
243 \returns the path to this module's standard index
244 */
245 QString getModuleStandardIndexLocation() const;
246
247 /**
248 Builds a search index for this module
249 \throws when unsuccessful
250 */
251 void buildIndex();
252
253 /**
254 \returns index size
255 */
256 ::qint64 indexSize() const;
257
258 /**
259 This function uses CLucene to perform and index based search.
260 \returns the result
261 \throws on error
262 */
264 searchIndexed(QString const & searchedText,
265 sword::ListKey const & scope) const;
266
267 /**
268 \returns the type of the module.
269 */
270 ModuleType type() const { return m_type; }
271
272 /**
273 * Returns the required Sword version for this module.
274 * Returns -1 if no special Sword version is required.
275 */
276 sword::SWVersion minimumSwordVersion() const;
277
278 /**
279 \note The Sword library takes care of the duplicate names: _n is added
280 after each duplicate.
281 \returns The name of this module.
282 */
283 QString const & name() const { return m_cachedName; }
284
285 /**
286 * Snaps to the closest entry in the module if the current key is
287 * not present in the data files.
288 */
289 virtual bool snap() const { return false; }
290
291 /**
292 \returns whether the module supports the feature given as parameter.
293 */
294 bool has(CSwordModuleInfo::Feature const feature) const noexcept
295 { return m_cachedFeatures.testFlag(feature); }
296
297 bool has(CSwordModuleInfo::FilterOption const &) const;
298
299 /** \returns the text direction of the module's text. */
301
302 /** \returns the text direction of the module's text as an HTML value. */
303 char const * textDirectionAsHtml() const;
304
305 /**
306 Writes the new text at the given position into the module. This does
307 only work for writabe modules.
308 */
309 void write(CSwordKey * key, const QString & newText);
310
311 /**
312 \returns the language of the module.
313 */
314 std::shared_ptr<Language const> language() const
315 { return m_cachedLanguage; }
316
317 /** \returns the target language of the glossary, if this is a glossary. */
318 std::shared_ptr<Language const> glossaryTargetlanguage() const
320
321 /**
322 \returns whether this module may be written to.
323 */
324 virtual bool isWritable() const { return false; }
325
326 /**
327 * Returns true if this module is hidden (not to be shown with other modules in certain views).
328 */
329 bool isHidden() const { return m_hidden; }
330
331 /**
332 Shows or hides the module.
333 \param hide Whether the module should be hidden.
334 \returns whether the hidden state was changed.
335 */
336 bool setHidden(bool hide);
337
338 /**
339 \returns the category of this module.
340 */
342
343 /**
344 * The about text which belongs to this module.
345 */
346 QString aboutText() const;
347
348 /**
349 * Returns true if this module is Unicode encoded. False if the charset is iso8859-1.
350 * Protected because it should not be used outside of the CSword*ModuleInfo classes.
351 */
352 bool isUnicode() const noexcept;
353
354 /** \returns an icon for this module based on it's isLocked() status. */
355 QIcon moduleIcon() const;
356
357 /**
358 \param[in] category The category whose icon to return.
359 \returns an ("unlocked") icon for the given category.
360 */
362
363 /**
364 \param[in] category The category whose icon to return.
365 \returns an "add" icon for the given category.
366 */
367 static QIcon const & categoryIconAdd(
369
370 /**
371 \param[in] category The category whose icon to return.
372 \returns a "locked" icon for the given category.
373 */
374 static QIcon const & categoryIconLocked(
376
377 /**
378 Returns an "add" category icon based on a module type.
379 \param[in] module The module whose category icon to return.
380 */
381 static QIcon const & categoryIconAdd(CSwordModuleInfo::ModuleType type);
382
383 /**
384 Returns a translated name for the given category.
385 \param[in] module The category whose translated name to return.
386 */
387 static QString categoryName(const CSwordModuleInfo::Category & category);
388
389 virtual CSwordKey * createKey() const = 0;
390
391public Q_SLOTS:
392
393 void cancelIndexing(std::memory_order const memoryOrder =
394 std::memory_order_relaxed) noexcept
395 { m_cancelIndexing.store(true, memoryOrder); }
396
397protected: // methods:
398
399 CSwordModuleInfo(sword::SWModule & module,
402
403 CSwordBackend & backend() const { return m_backend; }
404
405 QString getSimpleConfigEntry(const QString & name) const;
406 QString getFormattedConfigEntry(const QString & name) const;
407
408 bool hasImportantFilterOption() const;
409 void setImportantFilterOptions(bool enable);
410
411Q_SIGNALS:
412
414 void hiddenChanged(bool hidden);
415 void unlockedChanged(bool unlocked);
418
419private: // fields:
420
421 sword::SWModule & m_swordModule;
425 std::atomic<bool> m_cancelIndexing;
426
427 // Cached data:
428 QString const m_cachedName;
429 Features const m_cachedFeatures;
431 std::shared_ptr<Language const> const m_cachedLanguage;
432 std::shared_ptr<Language const> const m_cachedGlossaryTargetLanguage;
434
435};
436
437Q_DECLARE_METATYPE(CSwordModuleInfo::Category)
438Q_DECLARE_OPERATORS_FOR_FLAGS(CSwordModuleInfo::Categories)
The backend layer main class, a backend implementation of Sword.
bool isHidden() const
bool has(CSwordModuleInfo::Feature const feature) const noexcept
CSwordModuleSearch::ModuleResultList searchIndexed(QString const &searchedText, sword::ListKey const &scope) const
sword::SWVersion minimumSwordVersion() const
CSwordBackend & backend() const
void write(CSwordKey *key, const QString &newText)
void cancelIndexing(std::memory_order const memoryOrder=std::memory_order_relaxed) noexcept
QString config(const CSwordModuleInfo::ConfigEntry entry) const
bool isUnicode() const noexcept
static FilterOption const redLetterWords
static FilterOption const headings
virtual CSwordKey * createKey() const =0
bool hasVersion() const
static FilterOption const textualVariants
static void deleteIndexForModule(const QString &name)
virtual bool snap() const
static QIcon const & categoryIconAdd(CSwordModuleInfo::Category category)
bool unlock(const QString &unlockKey)
static FilterOption const hebrewPoints
static QString getGlobalBaseIndexLocation()
CSwordModuleInfo::Category const m_cachedCategory
ModuleType const m_type
CSwordModuleInfo(CSwordModuleInfo const &)=delete
static QString categoryName(const CSwordModuleInfo::Category &category)
static FilterOption const strongNumbers
bool unlockKeyIsValid() const
static FilterOption const morphTags
static QIcon const & categoryIconLocked(CSwordModuleInfo::Category category)
static FilterOption const scriptureReferences
void setImportantFilterOptions(bool enable)
QString getFormattedConfigEntry(const QString &name) const
QString const m_cachedName
QString getModuleBaseIndexLocation() const
static FilterOption const hebrewCantillation
CSwordModuleInfo::TextDirection textDirection() const
bool const m_cachedHasVersion
ModuleType type() const
QString const & name() const
void hasIndexChanged(bool hasIndex)
void indexingFinished()
CSwordModuleInfo & operator=(CSwordModuleInfo &&)=delete
bool hasImportantFilterOption() const
QString aboutText() const
static FilterOption const morphSegmentation
QString getModuleStandardIndexLocation() const
char const * textDirectionAsHtml() const
sword::SWModule & m_swordModule
void hiddenChanged(bool hidden)
void indexingProgress(int)
bool setHidden(bool hide)
virtual bool isWritable() const
static FilterOption const greekAccents
Features const m_cachedFeatures
CSwordModuleInfo & operator=(CSwordModuleInfo const &)=delete
QString getSimpleConfigEntry(const QString &name) const
std::atomic< bool > m_cancelIndexing
static QIcon const & categoryIcon(CSwordModuleInfo::Category category)
static FilterOption const footnotes
void unlockedChanged(bool unlocked)
std::shared_ptr< Language const > const m_cachedLanguage
std::shared_ptr< Language const > glossaryTargetlanguage() const
std::shared_ptr< Language const > language() const
CSwordBackend & m_backend
::qint64 indexSize() const
sword::SWModule & swordModule() const
CSwordModuleInfo::Category category() const
std::shared_ptr< Language const > const m_cachedGlossaryTargetLanguage
CSwordModuleInfo(CSwordModuleInfo &&)=delete
static FilterOption const lemmas
size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen)
size_t lucene_wcstoutf8(char *, const wchar_t *, size_t maxslen)
std::vector< std::shared_ptr< sword::SWKey const > > ModuleResultList
static char const * valueToReadings(int value) noexcept
static char const * valueToOnOff(int value) noexcept