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