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, http://www.bibletime.info/. 6 * 7 * Copyright 1999-2016 by the BibleTime developers. 8 * The BibleTime source code is licensed under the GNU General Public License version 2.0. 9 * 10 **********/ 11 12 #ifndef CSWORDMODULEINFO_H 13 #define CSWORDMODULEINFO_H 14 15 #include <QObject> 16 #include "btdisplayholder.h" 17 18 #include "../managers/clanguagemgr.h" 19 20 #include <atomic> 21 #include <QIcon> 22 #include <QList> 23 #include <QMetaType> 24 #include <QString> 25 26 // Sword includes: 27 #include <listkey.h> 28 #include <swmodule.h> 29 #include <swsearchable.h> 30 #include <swversion.h> 31 32 33 #ifdef CLUCENE2 34 // CLucene no longer lists the following functions in its headers 35 extern size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen); 36 extern size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen); 37 #endif 38 39 class CSwordBackend; 40 class CSwordKey; 41 42 43 /** 44 * Base class for Sword modules. 45 * This is the base class for all Sword modules. Every class handling a special Sword module type 46 * does inherit from this class. 47 * 48 * @author The BibleTime team 49 * @version $Id: cswordmoduleinfo.h,v 1.83 2007/02/04 23:12:32 joachim Exp $ 50 */ 51 52 class CSwordModuleInfo 53 : public QObject 54 , public BtDisplayHolder<CSwordModuleInfo> 55 { 56 57 Q_OBJECT 58 59 public: /* Types: */ 60 61 /** 62 * These are the options which could be supported by modules and by this backend. 63 * It's used in @ref CSwordBackend::setOption. 64 */ 65 enum FilterTypes { 66 footnotes, /**< Footnotes embedded in the module's text */ 67 strongNumbers, /**< strong numbers, usually in the text for the info display */ 68 headings, /**< additional section headings */ 69 morphTags, /**< morphology */ 70 lemmas, /**< lemma tags */ 71 hebrewPoints,/**< Hebrew vowel points */ 72 hebrewCantillation, /**<Hewbrew caantillation points */ 73 greekAccents, /**< Greek accents may be switched on and off */ 74 scriptureReferences, /**< scripture references may be switched on and off, just makes sense in Bibles */ 75 redLetterWords, /**< Jesus words in red, color is template specific */ 76 textualVariants, /**< variants */ 77 morphSegmentation, /**< morph word segmentation, supported by OSIS */ 78 filterTypesMIN = footnotes, /**< first entry of this enum */ 79 filterTypesMAX = morphSegmentation /**< last item in this enum */ 80 // transliteration /* The following are handled in a special way */ 81 }; 82 83 /** The text direction of a module */ 84 enum TextDirection { /* The text direction of the modules's text */ 85 LeftToRight, /**< Left to right text direction, the default setting */ 86 RightToLeft /**< Right to left text directin, e.g. for hebrew */ 87 }; 88 89 /** The module type. */ 90 enum ModuleType { 91 Bible, /**< Bible module */ 92 Commentary, /**< Commentary module */ 93 Lexicon, /**< Lexicon module */ 94 GenericBook, /**< Generic book module */ 95 Unknown /**< Fall back type for unknown modules */ 96 }; 97 98 /** 99 * This enum is used to give 100 * back an error code after unlocking the module 101 * BibleTime stores the unlock key not in the module's config file but in BibleTime's 102 * configuration file. 103 */ 104 enum UnlockErrorCode { 105 noError, /**< No error occured, everything worked ok. The key was written to the BibleTime config */ 106 wrongUnlockKey, /**< The wrong key was used. Module is not unlocked */ 107 notLocked, /**< The module was not locked so it can't be unlocked */ 108 noPermission /**< The key was not written to config because we have no permissions */ 109 }; 110 111 enum ConfigEntry { 112 AboutInformation, /**< The about information of a module which is stored in the config file*/ 113 AbsoluteDataPath, /**< The absolute data path stored in the config object */ 114 CipherKey, /**< The cipher key which was used to unlock the module. Not necessarily set.*/ 115 DataPath, /**< The relative path. See AbsoluteDataPath*/ 116 Description, /**< The module description stored in the config file */ 117 ModuleVersion, /**< The module's version.*/ 118 MinimumSwordVersion, /**< The required Sword Version of this module. Otherwise some things may not work (compression etc.).*/ 119 TextDir, /**< The text direction */ 120 DisplayLevel, /**< Mostly used for books. Gives the level which should contain the connected entries.*/ 121 GlossaryFrom, /**< lamguage from which the Glosaary tramslates */ 122 GlossaryTo, /**< lamguages to which the glossary maps to */ 123 DistributionLicense, 124 DistributionSource, 125 DistributionNotes, 126 TextSource, 127 CopyrightNotes, 128 CopyrightHolder, 129 CopyrightDate, 130 CopyrightContactName, 131 CopyrightContactAddress, 132 CopyrightContactEmail, 133 Markup /**< The markup of this module */ 134 }; 135 136 enum Feature { 137 //StrongsNumbers, /**< Use for Bibles which have embedded strong numbers */ BT does not use this as a user option 138 GreekDef, 139 HebrewDef, 140 GreekParse, 141 HebrewParse, 142 featureMin = GreekDef, 143 featureMax = HebrewParse 144 }; 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, 154 DailyDevotional = 0x20, 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 163 CSwordModuleInfo(CSwordModuleInfo &&) = delete; 164 CSwordModuleInfo(CSwordModuleInfo const &) = delete; 165 CSwordModuleInfo & operator=(CSwordModuleInfo &&) = delete; 166 CSwordModuleInfo & operator=(CSwordModuleInfo const &) = delete; 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 */ module()192 inline sword::SWModule & module() const { 193 return m_module; 194 } 195 196 /** 197 * Sets the unlock key of the modules and writes the key into the config file. 198 * @return True if the unlock process was succesful, if the key was 199 wrong, or if the config file was write protected return false. 200 */ 201 bool unlock(const QString & unlockKey); 202 203 /** 204 * This function does return true if the data files of the module are encrypted by the module author 205 * (the on who made the module) no matter if it's locked or not. 206 * @return True if this module is encryped 207 */ 208 bool isEncrypted() const; 209 210 /** 211 * This function returns true if this module is locked (encrypted + correct cipher key), 212 * otherwise return false. 213 * @return True if this module is locked, i.e. encrypted but without a key set 214 */ 215 bool isLocked() const; 216 217 /** 218 This function makes an estimate if a module was properly unlocked. It 219 returns true if the first entry of the module is not empty and 220 contains only printable characters (for the first 100 chars or so). If 221 that is the case, we can safely assume that a) the module was properly 222 unlocked and b) no buffer overflows will occur, which can happen when 223 Sword filters process garbage text which was not properly decrypted. 224 */ 225 bool unlockKeyIsValid() const; 226 227 /** 228 \retval true if this module has a version number 229 \retval false if it doesn't have a version number 230 */ hasVersion()231 inline bool hasVersion() const { 232 return m_cachedHasVersion; 233 } 234 235 /** 236 \returns true if the module's index has been built. 237 */ 238 bool hasIndex() const; 239 240 /** 241 \returns the path to this module's index base dir 242 */ 243 QString getModuleBaseIndexLocation() const; 244 245 /** 246 \returns the path to this module's standard index 247 */ 248 QString getModuleStandardIndexLocation() const; 249 250 /** 251 Builds a search index for this module 252 \throws when unsuccessful 253 */ 254 void buildIndex(); 255 256 /** 257 \returns index size 258 */ 259 size_t indexSize() const; 260 261 /** 262 This function uses CLucene to perform and index based search. It also 263 overwrites the variable containing the last search result. 264 \returns the number of results found 265 \throws on error 266 */ 267 size_t searchIndexed(const QString & searchedText, 268 const sword::ListKey & scope, 269 sword::ListKey & results) const; 270 271 /** 272 \returns the type of the module. 273 */ type()274 inline ModuleType type() const { 275 return m_type; 276 } 277 278 /** 279 * Returns the required Sword version for this module. 280 * Returns -1 if no special Sword version is required. 281 */ 282 sword::SWVersion minimumSwordVersion() const; 283 284 /** 285 \note The Sword library takes care of the duplicate names: _n is added 286 after each duplicate. 287 \returns The name of this module. 288 */ name()289 inline const QString & name() const { 290 return m_cachedName; 291 } 292 293 /** 294 * Snaps to the closest entry in the module if the current key is 295 * not present in the data files. 296 */ snap()297 virtual inline bool snap() const { 298 return false; 299 } 300 301 /** 302 \returns whether the module supports the feature given as parameter. 303 */ 304 bool has(const CSwordModuleInfo::Feature) const; 305 306 bool has(const CSwordModuleInfo::FilterTypes ) const; 307 308 /** \returns the text direction of the module's text. */ 309 CSwordModuleInfo::TextDirection textDirection() const; 310 311 /** \returns the text direction of the module's text as an HTML value. */ 312 char const * textDirectionAsHtml() const; 313 314 /** 315 Writes the new text at the given position into the module. This does 316 only work for writabe modules. 317 */ 318 void write(CSwordKey * key, const QString & newText); 319 320 /** 321 Deletes the current entry and removes it from the module. 322 */ 323 void deleteEntry(CSwordKey * const key); 324 325 /** 326 \returns the language of the module. 327 */ language()328 inline const CLanguageMgr::Language * language() const { 329 return m_cachedLanguage; 330 } 331 332 /** 333 \returns whether this module may be written to. 334 */ isWritable()335 inline virtual bool isWritable() const { 336 return false; 337 } 338 339 /** 340 * Returns true if this module is hidden (not to be shown with other modules in certain views). 341 */ isHidden()342 inline bool isHidden() const { 343 return m_hidden; 344 } 345 346 /** 347 Shows or hides the module. 348 \param hide Whether the module should be hidden. 349 \returns whether the hidden state was changed. 350 */ 351 bool setHidden(bool hide); 352 353 /** 354 \returns the category of this module. 355 */ category()356 inline CSwordModuleInfo::Category category() const { 357 return m_cachedCategory; 358 } 359 360 /** 361 * The about text which belongs to this module. 362 */ 363 QString aboutText() const; 364 365 /** 366 * Returns true if this module is Unicode encoded. False if the charset is iso8859-1. 367 * Protected because it should not be used outside of the CSword*ModuleInfo classes. 368 */ isUnicode()369 inline bool isUnicode() const { 370 return m_module.isUnicode(); 371 } 372 373 /** 374 Returns an icon for this module. 375 */ moduleIcon()376 inline QIcon moduleIcon() const { 377 return CSwordModuleInfo::moduleIcon(*this); 378 } 379 380 /** 381 Returns an icon for the given module. 382 \param[in] module The module whose icon to return. 383 */ 384 static QIcon const & moduleIcon(CSwordModuleInfo const & module); 385 386 /** 387 Returns an icon for the category of given module. 388 \param[in] module The module whose category icon to return. 389 */ 390 static QIcon const & categoryIcon(CSwordModuleInfo::Category category); 391 392 /** 393 Returns a translated name for the given category. 394 \param[in] module The category whose translated name to return. 395 */ 396 static QString categoryName(const CSwordModuleInfo::Category & category); 397 398 /** 399 Returns a english name for the given category. 400 \param[in] module The category whose english name to return. 401 */ 402 static QString englishCategoryName(const CSwordModuleInfo::Category & category); 403 404 public slots: 405 406 inline void cancelIndexing(std::memory_order const memoryOrder = 407 std::memory_order_relaxed) noexcept 408 { m_cancelIndexing.store(true, memoryOrder); } 409 410 protected: /* Methods: */ 411 412 CSwordModuleInfo(sword::SWModule & module, 413 CSwordBackend & backend, 414 ModuleType type); 415 backend()416 inline CSwordBackend & backend() const { 417 return m_backend; 418 } 419 420 QString getSimpleConfigEntry(const QString & name) const; 421 QString getFormattedConfigEntry(const QString & name) const; 422 423 signals: 424 425 void hasIndexChanged(bool hasIndex); 426 void hiddenChanged(bool hidden); 427 void unlockedChanged(bool unlocked); 428 void indexingFinished(); 429 void indexingProgress(int); 430 431 private: /* Fields: */ 432 433 sword::SWModule & m_module; 434 CSwordBackend & m_backend; 435 ModuleType const m_type; 436 bool m_hidden; 437 std::atomic<bool> m_cancelIndexing; 438 439 // Cached data: 440 QString const m_cachedName; 441 CSwordModuleInfo::Category const m_cachedCategory; 442 const CLanguageMgr::Language * const m_cachedLanguage; 443 bool const m_cachedHasVersion; 444 445 }; 446 447 Q_DECLARE_METATYPE(CSwordModuleInfo::Category); 448 Q_DECLARE_OPERATORS_FOR_FLAGS(CSwordModuleInfo::Categories) 449 450 #endif 451