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-2021 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
29 extern size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen);
30 extern size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen);
31 
32 class CSwordBackend;
33 class CSwordKey;
34 namespace sword {
35 class ListKey;
36 class SWModule;
37 class 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 
49 class CSwordModuleInfo: public QObject {
50 
51  Q_OBJECT
52 
53 public: // 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;
61  char const * translatableOptionName;
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. */
87  enum ModuleType {
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 
108  enum ConfigEntry {
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 
133  enum Feature {
135  FeatureGreekDef = 1 << 1,
140  FeatureGlossary = 1 << 6,
141  FeatureImages = 1 << 7,
143  };
144  Q_DECLARE_FLAGS(Features, Feature)
145 
146  enum Category {
147  UnknownCategory = 0x0, /**< Unknown or unset category. */
148  NoCategory = 0x0,
149  Bibles = 0x01,
150  Commentaries = 0x02,
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 
161 public: // 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
197 wrong, 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  Deletes the current entry and removes it from the module.
318  */
319  void deleteEntry(CSwordKey * const key);
320 
321  /**
322  \returns the language of the module.
323  */
324  std::shared_ptr<Language const> language() const
325  { return m_cachedLanguage; }
326 
327  /** \returns the target language of the glossary, if this is a glossary. */
328  std::shared_ptr<Language const> glossaryTargetlanguage() const
330 
331  /**
332  \returns whether this module may be written to.
333  */
334  virtual bool isWritable() const { return false; }
335 
336  /**
337  * Returns true if this module is hidden (not to be shown with other modules in certain views).
338  */
339  bool isHidden() const { return m_hidden; }
340 
341  /**
342  Shows or hides the module.
343  \param hide Whether the module should be hidden.
344  \returns whether the hidden state was changed.
345  */
346  bool setHidden(bool hide);
347 
348  /**
349  \returns the category of this module.
350  */
352 
353  /**
354  * The about text which belongs to this module.
355  */
356  QString aboutText() const;
357 
358  /**
359  * Returns true if this module is Unicode encoded. False if the charset is iso8859-1.
360  * Protected because it should not be used outside of the CSword*ModuleInfo classes.
361  */
362  bool isUnicode() const noexcept;
363 
364  /**
365  Returns an icon for this module.
366  */
367  QIcon moduleIcon() const { return CSwordModuleInfo::moduleIcon(*this); }
368 
369  /**
370  Returns an icon for the given module.
371  \param[in] module The module whose icon to return.
372  */
373  static QIcon const & moduleIcon(CSwordModuleInfo const & module);
374 
375  /**
376  Returns an icon for the category of given module.
377  \param[in] module The module whose category icon to return.
378  */
379  static QIcon const & categoryIcon(CSwordModuleInfo::Category category);
380 
381  /**
382  Returns a translated name for the given category.
383  \param[in] module The category whose translated name to return.
384  */
385  static QString categoryName(const CSwordModuleInfo::Category & category);
386 
387  virtual CSwordKey * createKey() const = 0;
388 
389 public Q_SLOTS:
390 
391  void cancelIndexing(std::memory_order const memoryOrder =
392  std::memory_order_relaxed) noexcept
393  { m_cancelIndexing.store(true, memoryOrder); }
394 
395 protected: // methods:
396 
397  CSwordModuleInfo(sword::SWModule & module,
399  ModuleType type);
400 
401  CSwordBackend & backend() const { return m_backend; }
402 
403  QString getSimpleConfigEntry(const QString & name) const;
404  QString getFormattedConfigEntry(const QString & name) const;
405 
406  bool hasImportantFilterOption() const;
407  void setImportantFilterOptions(bool enable);
408 
409 Q_SIGNALS:
410 
412  void hiddenChanged(bool hidden);
413  void unlockedChanged(bool unlocked);
415  void indexingProgress(int);
416 
417 private: // fields:
418 
419  sword::SWModule & m_swordModule;
422  bool m_hidden;
423  std::atomic<bool> m_cancelIndexing;
424 
425  // Cached data:
426  QString const m_cachedName;
427  Features const m_cachedFeatures;
429  std::shared_ptr<Language const> const m_cachedLanguage;
430  std::shared_ptr<Language const> const m_cachedGlossaryTargetLanguage;
431  bool const m_cachedHasVersion;
432 
433 };
434 
435 Q_DECLARE_METATYPE(CSwordModuleInfo::Category)
436 Q_DECLARE_OPERATORS_FOR_FLAGS(CSwordModuleInfo::Categories)
The backend layer main class, a backend implementation of Sword.
Definition: cswordbackend.h:56
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
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
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
std::shared_ptr< Language const > glossaryTargetlanguage() const
static QString getGlobalBaseIndexLocation()
CSwordModuleInfo::Category const m_cachedCategory
virtual CSwordKey * createKey() const =0
ModuleType const m_type
std::shared_ptr< Language const > language() const
CSwordModuleInfo(CSwordModuleInfo const &)=delete
static QString categoryName(const CSwordModuleInfo::Category &category)
static FilterOption const strongNumbers
bool unlockKeyIsValid() const
static FilterOption const morphTags
CSwordBackend & backend() const
static FilterOption const scriptureReferences
void setImportantFilterOptions(bool enable)
QString getFormattedConfigEntry(const QString &name) const
CSwordModuleInfo & operator=(CSwordModuleInfo const &)=delete
QString const m_cachedName
void deleteEntry(CSwordKey *const key)
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
void hasIndexChanged(bool hasIndex)
void indexingFinished()
bool hasImportantFilterOption() const
QString aboutText() const
static FilterOption const morphSegmentation
QString const & name() const
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
QString getSimpleConfigEntry(const QString &name) const
CSwordModuleInfo & operator=(CSwordModuleInfo &&)=delete
std::atomic< bool > m_cancelIndexing
static FilterOption const footnotes
void unlockedChanged(bool unlocked)
std::shared_ptr< Language const > const m_cachedLanguage
bool isEncrypted() const
CSwordBackend & m_backend
::qint64 indexSize() const
CSwordModuleInfo::Category category() const
sword::SWModule & swordModule() 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