From f0bfac8c57dd0142c3c3b3b1c3710a7df3799b0e Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 22 Dec 2008 16:48:24 +0000 Subject: [PATCH] Moved responsibility of getting bible passage out of KwBiblePassage into KwBibleModule, and made factory for bible managers --- include/Factory.h | 105 +++++++++++++++++++++++-- kworship/KwBiblePlugin.cpp | 23 ++++-- kworship/bible/KwBibleManager.cpp | 17 ++++ kworship/bible/KwBibleManager.h | 33 ++++++++ kworship/bible/KwBibleManagerBibleGateway.cpp | 2 + kworship/bible/KwBibleManagerBibleGateway.h | 2 + kworship/bible/KwBibleManagerSword.cpp | 2 + kworship/bible/KwBibleManagerSword.h | 2 + kworship/bible/KwBibleModule.h | 5 ++ kworship/bible/KwBibleModuleBibleGateway.cpp | 5 ++ kworship/bible/KwBibleModuleBibleGateway.h | 3 + kworship/bible/KwBibleModuleSword.cpp | 5 ++ kworship/bible/KwBibleModuleSword.h | 3 + kworship/bible/KwBiblePassage.cpp | 83 +++++++++++++++++--- kworship/bible/KwBiblePassage.h | 107 +++++++++++++++++++++++++- kworship/bible/KwBiblePlaylistItem.cpp | 5 +- kworship/bible/KwBiblePlaylistItem.h | 7 +- kworship/playlist/KwPlaylistItem.cpp | 2 +- 18 files changed, 379 insertions(+), 32 deletions(-) diff --git a/include/Factory.h b/include/Factory.h index 582e5a1..5d2fe8c 100644 --- a/include/Factory.h +++ b/include/Factory.h @@ -77,21 +77,37 @@ class Factory return false; } + /** Remove a type from the factory. + * @param key Identifier used to construct. + */ + bool removeType(const KEY& key) + { + + typename ConstructorHash::iterator it = m_constructors.find(key); + if (it != m_constructors.end()) + { + delete *it; + m_constructors.erase(it); + return true; + } + return false; + } + /* * Construction */ - BASE* construct(KEY key) + BASE* construct(const KEY& key) { return constructFromPack(key, TUPLE::pack()); } template - BASE* construct(KEY key, const Param1& param1) + BASE* construct(const KEY& key, const Param1& param1) { return constructFromPack(key, TUPLE::pack(param1)); } template - BASE* construct(KEY key, const Param1& param1, const Param2& param2) + BASE* construct(const KEY& key, const Param1& param1, const Param2& param2) { return constructFromPack(key, TUPLE::pack(param1, param2)); } @@ -100,7 +116,7 @@ class Factory * @param key identifier of type to construct. * @param pack pack of arguments. */ - BASE* constructFromPack(KEY key, const typename TUPLE::Pack& pack) + BASE* constructFromPack(const KEY& key, const typename TUPLE::Pack& pack) { typename ConstructorHash::const_iterator it = m_constructors.constFind(key); if (it != m_constructors.constEnd()) @@ -113,6 +129,57 @@ class Factory } } + BASE* singleton(const KEY& key) + { + return singletonFromPack(key, TUPLE::pack()); + } + template + BASE* singleton(const KEY& key, const Param1& param1) + { + return singletonFromPack(key, TUPLE::pack(param1)); + } + template + BASE* singleton(const KEY& key, const Param1& param1, const Param2& param2) + { + return singletonFromPack(key, TUPLE::pack(param1, param2)); + } + + /** Get a singleton of a type using a pack of arguments. + * @param key identifier of type to construct. + * @param pack pack of arguments. + */ + BASE* singletonFromPack(const KEY& key, const typename TUPLE::Pack& pack) + { + typename ConstructorHash::const_iterator it = m_constructors.constFind(key); + if (it != m_constructors.constEnd()) + { + return (*it)->singleton(pack); + } + else + { + return 0; + } + } + + /// Delete any existing singleton of a type. + void deleteSingleton(const KEY& key) + { + typename ConstructorHash::const_iterator it = m_constructors.constFind(key); + if (it != m_constructors.constEnd()) + { + (*it)->deleteSingleton(); + } + } + + /// Delete all singletons. + void deleteAllSingletons() + { + foreach (BaseConstructor* constructor, m_constructors) + { + constructor->deleteSingleton(); + } + } + private: /* @@ -123,9 +190,37 @@ class Factory class BaseConstructor { public: - virtual ~BaseConstructor() {} + BaseConstructor() + : m_singleton(0) + { + } + virtual ~BaseConstructor() + { + delete m_singleton; + } /// Construct an instance of a dervied type. virtual BASE* construct(const typename TUPLE::Pack& pack) const = 0; + /// Get a singleton object, constructing if necessary. + BASE* singleton(const typename TUPLE::Pack& pack) + { + if (0 == m_singleton) + { + m_singleton = construct(pack); + } + return m_singleton; + } + /// Delete singleton if it exists. + void deleteSingleton() + { + delete m_singleton; + m_singleton = 0; + } + + private: + // No copy construction + BaseConstructor(const BaseConstructor&); + + BASE* m_singleton; }; /** Type specific generic constructor. diff --git a/kworship/KwBiblePlugin.cpp b/kworship/KwBiblePlugin.cpp index 9901b5b..a6ae152 100644 --- a/kworship/KwBiblePlugin.cpp +++ b/kworship/KwBiblePlugin.cpp @@ -29,8 +29,8 @@ #include "KwDocument.h" #include -#include -#include +#include "KwBibleManagerSword.h" +#include "KwBibleManagerBibleGateway.h" #include #include @@ -70,6 +70,8 @@ KwBiblePlugin::KwBiblePlugin() , m_editRange(0) , m_textPassage(0) { + KwBibleManagerSword::registerManager(); + KwBibleManagerBibleGateway::registerManager(); } /// Destructor. @@ -293,7 +295,7 @@ void KwBiblePlugin::slotInsertIntoPlaylist() if (success) { - KwBiblePlaylistItem* item = new KwBiblePlaylistItem(manager->name(), module->name(), key); + KwBiblePlaylistItem* item = new KwBiblePlaylistItem(module, key); KwPlaylistModel* model = KwApplication::self()->mainWindow()->playlistModel(); model->addItem(QModelIndex(), item); } @@ -311,9 +313,18 @@ void KwBiblePlugin::slotShowNow() void KwBiblePlugin::_load() { // Construct the bible managers. - QList managers; - managers.push_back(new KwBibleManagerSword); - managers.push_back(new KwBibleManagerBibleGateway); + QStringList managerNames; + managerNames << "SWORD"; + managerNames << "BibleGateway.com"; + QList managers; + foreach (QString name, managerNames) + { + KwBibleManager* manager = KwBibleManagerSword::singleton(name); + if (0 != manager) + { + managers += manager; + } + } // Set up the docker m_docker = new QDockWidget(i18n("Bible")); diff --git a/kworship/bible/KwBibleManager.cpp b/kworship/bible/KwBibleManager.cpp index 79818b9..dfa4783 100644 --- a/kworship/bible/KwBibleManager.cpp +++ b/kworship/bible/KwBibleManager.cpp @@ -26,6 +26,23 @@ #include "KwBibleManager.h" /* + * Manager factory + */ + +/// Get a factory object. +KwBibleManager::Factory* KwBibleManager::factory() +{ + static Factory fac; + return &fac; +} + +/// Get a singleton for a manager. +KwBibleManager* KwBibleManager::singleton(const QString& key) +{ + return factory()->singleton(key); +} + +/* * Constructors + destructor */ diff --git a/kworship/bible/KwBibleManager.h b/kworship/bible/KwBibleManager.h index 235b387..011a2f7 100644 --- a/kworship/bible/KwBibleManager.h +++ b/kworship/bible/KwBibleManager.h @@ -26,16 +26,49 @@ * @author James Hogan */ +#include + #include #include #include class KwBibleModule; +#define KW_BIBLE_MANAGER(X, KEY) \ + private: \ + /* \ + * Static private variables \ + */ \ + static bool s_registered; \ + public: \ + static void registerManager() \ + { \ + if (!s_registered) \ + { \ + s_registered = KwBibleManager::factory()->addType< X >(KEY); \ + } \ + } + +#define KW_REGISTER_BIBLE_MANAGER(X) \ + bool X::s_registered = false; + /// A bible manager (analagous to a SWORD manager). class KwBibleManager { public: + + /* + * Manager factory + */ + + /// Factory of managers identified by strings. + typedef ::Factory Factory; + + /// Get a factory object. + static Factory* factory(); + + /// Get a singleton for a manager. + static KwBibleManager* singleton(const QString& key); /* * Constructors + destructor diff --git a/kworship/bible/KwBibleManagerBibleGateway.cpp b/kworship/bible/KwBibleManagerBibleGateway.cpp index 4d779f4..27c5c6f 100644 --- a/kworship/bible/KwBibleManagerBibleGateway.cpp +++ b/kworship/bible/KwBibleManagerBibleGateway.cpp @@ -34,6 +34,8 @@ #include #include +KW_REGISTER_BIBLE_MANAGER(KwBibleManagerBibleGateway) + /* * Constructors + destructor */ diff --git a/kworship/bible/KwBibleManagerBibleGateway.h b/kworship/bible/KwBibleManagerBibleGateway.h index 0a3f183..73d4cdc 100644 --- a/kworship/bible/KwBibleManagerBibleGateway.h +++ b/kworship/bible/KwBibleManagerBibleGateway.h @@ -38,6 +38,8 @@ class KwBibleModuleBibleGateway; /// A bible manager for BibleGateway.com. class KwBibleManagerBibleGateway : public KwBibleManager { + KW_BIBLE_MANAGER(KwBibleManagerBibleGateway, "BibleGateway.com") + public: /* diff --git a/kworship/bible/KwBibleManagerSword.cpp b/kworship/bible/KwBibleManagerSword.cpp index 159db6a..e8bed3c 100644 --- a/kworship/bible/KwBibleManagerSword.cpp +++ b/kworship/bible/KwBibleManagerSword.cpp @@ -31,6 +31,8 @@ #include #include +KW_REGISTER_BIBLE_MANAGER(KwBibleManagerSword) + /* * Constructors + destructor */ diff --git a/kworship/bible/KwBibleManagerSword.h b/kworship/bible/KwBibleManagerSword.h index 3de959e..6cd0a9c 100644 --- a/kworship/bible/KwBibleManagerSword.h +++ b/kworship/bible/KwBibleManagerSword.h @@ -39,6 +39,8 @@ namespace sword /// A bible manager (analagous to a SWORD manager). class KwBibleManagerSword : public KwBibleManager { + KW_BIBLE_MANAGER(KwBibleManagerSword, "SWORD"); + public: /* diff --git a/kworship/bible/KwBibleModule.h b/kworship/bible/KwBibleModule.h index 5d17d6c..dc912ec 100644 --- a/kworship/bible/KwBibleModule.h +++ b/kworship/bible/KwBibleModule.h @@ -29,6 +29,8 @@ #include #include +class KwBiblePassage; + /// A bible module (analagous to a SWORD module). class KwBibleModule { @@ -120,6 +122,9 @@ class KwBibleModule /// Get the number of verses in a chapter of a book. virtual int numVerses(int book, int chapter) = 0; + /// Fill a passage object. + virtual bool fillPassage(const Key& key, KwBiblePassage* outPassage) const = 0; + /// Get rendered text for a given passage. virtual QString renderText(const Key& key) = 0; diff --git a/kworship/bible/KwBibleModuleBibleGateway.cpp b/kworship/bible/KwBibleModuleBibleGateway.cpp index 32afd26..fd15417 100644 --- a/kworship/bible/KwBibleModuleBibleGateway.cpp +++ b/kworship/bible/KwBibleModuleBibleGateway.cpp @@ -160,6 +160,11 @@ int KwBibleModuleBibleGateway::numVerses(int book, int chapter) } } +bool KwBibleModuleBibleGateway::fillPassage(const Key& key, KwBiblePassage* outPassage) const +{ + return false; +} + QString KwBibleModuleBibleGateway::renderText(const KwBibleModule::Key& key) { QString result; diff --git a/kworship/bible/KwBibleModuleBibleGateway.h b/kworship/bible/KwBibleModuleBibleGateway.h index 291f704..5384b2e 100644 --- a/kworship/bible/KwBibleModuleBibleGateway.h +++ b/kworship/bible/KwBibleModuleBibleGateway.h @@ -64,6 +64,9 @@ class KwBibleModuleBibleGateway : public KwBibleModule virtual int numVerses(int book, int chapter); // Reimplemented + virtual bool fillPassage(const Key& key, KwBiblePassage* outPassage) const; + + // Reimplemented virtual QString renderText(const KwBibleModule::Key& key); protected: diff --git a/kworship/bible/KwBibleModuleSword.cpp b/kworship/bible/KwBibleModuleSword.cpp index 01d7f42..3d15785 100644 --- a/kworship/bible/KwBibleModuleSword.cpp +++ b/kworship/bible/KwBibleModuleSword.cpp @@ -108,6 +108,11 @@ int KwBibleModuleSword::numVerses(int book, int chapter) return 0; } +bool KwBibleModuleSword::fillPassage(const Key& key, KwBiblePassage* outPassage) const +{ + return false; +} + QString KwBibleModuleSword::renderText(const KwBibleModule::Key& key) { QString result; diff --git a/kworship/bible/KwBibleModuleSword.h b/kworship/bible/KwBibleModuleSword.h index d60d642..5d40237 100644 --- a/kworship/bible/KwBibleModuleSword.h +++ b/kworship/bible/KwBibleModuleSword.h @@ -65,6 +65,9 @@ class KwBibleModuleSword : public KwBibleModule virtual int numVerses(int book, int chapter); // Reimplemented + virtual bool fillPassage(const Key& key, KwBiblePassage* outPassage) const; + + // Reimplemented virtual QString renderText(const KwBibleModule::Key& key); protected: diff --git a/kworship/bible/KwBiblePassage.cpp b/kworship/bible/KwBiblePassage.cpp index 3470a70..58bea19 100644 --- a/kworship/bible/KwBiblePassage.cpp +++ b/kworship/bible/KwBiblePassage.cpp @@ -42,18 +42,6 @@ KwBiblePassage::KwBiblePassage() { } -/// Fill the passage from a given module. -KwBiblePassage::KwBiblePassage(const QString& managerId, const QString& moduleId, const KwBibleModule::Key& key) -: m_managerId(managerId) -, m_moduleId(moduleId) -, m_key(key) -, m_firstBook(0) -, m_numBooks(0) -, m_books(0) -{ - /// @todo Iterate through the verses getting the data. -} - /// Destructor. KwBiblePassage::~KwBiblePassage() { @@ -75,6 +63,48 @@ KwBiblePassage::~KwBiblePassage() * Main interface */ +/// Clear the passage. +void KwBiblePassage::clear() +{ +} + +/// Set the source module. +void KwBiblePassage::setSource(const QString& managerId, const QString& moduleId) +{ +} + +/// Initialise the books in the passage. +void KwBiblePassage::initBooks(int firstBook, int numBooks) +{ +} + +/// Initialise a book in the passage. +void KwBiblePassage::initBook(int bookNumber, + const QString& name, int firstChapter, int numChapters) +{ +} + +/// Initialise a chapter in the passage. +void KwBiblePassage::initChapter(int bookNumber, int chapterNumber, + int firstVerse, int numVerses) +{ +} + +/// Initialise a verse in the passage. +void KwBiblePassage::initVerse(int bookNumber, int chapterNumber, int verseNumber, + const QString& headings, const QString& content) +{ +} + +/* + * Accessors + */ + +/// Find whether the passage is empty. +bool KwBiblePassage::isEmpty() const +{ +} + /// Get textual key of this passage. QString KwBiblePassage::textualKey() const { @@ -122,3 +152,32 @@ QString KwBiblePassage::textualKey() const return i18nc("bible index (range, version)", "%1 (%2)", result, m_moduleId); } +/// Get the first book number in the passage. +int KwBiblePassage::firstBookNumber() const +{ +} + +/// Get the last book number in the passage. +int KwBiblePassage::lastBookNumber() const +{ +} + +/// Get the first chapter number in a book of the passage. +int KwBiblePassage::firstChapterNumber(int bookNumber) const +{ +} + +/// Get the last chapter number in a book of the passage. +int KwBiblePassage::lastChapterNumber(int bookNumber) const +{ +} + +/// Get the first verse number in a chapter of the passage. +int KwBiblePassage::firstVerseNumber(int bookNumber, int chapterNumber) const +{ +} + +/// Get the last verse number in a chapter of the passage. +int KwBiblePassage::lastVerseNumber(int bookNumber, int chapterNumber) const +{ +} diff --git a/kworship/bible/KwBiblePassage.h b/kworship/bible/KwBiblePassage.h index 0149482..f94174d 100644 --- a/kworship/bible/KwBiblePassage.h +++ b/kworship/bible/KwBiblePassage.h @@ -45,9 +45,6 @@ class KwBiblePassage /// Default constructor. KwBiblePassage(); - /// Fill the passage from a given module. - KwBiblePassage(const QString& managerId, const QString& moduleId, const KwBibleModule::Key& key); - /// Destructor. virtual ~KwBiblePassage(); @@ -55,9 +52,113 @@ class KwBiblePassage * Main interface */ + /** Clear the passage. + * Deletes all books. + */ + void clear(); + + /** Set the source module. + * @param managerId ID of the bible manager. + * @param moduleId ID of the bible module. + */ + void setSource(const QString& managerId, const QString& moduleId); + + /** Initialise the books in the passage. + * If books are already initialised they will be cleared first. + * @param firstBook Number of first book in passage. + * @param numBooks Number of books covered in this passage. + * @param numBooks > 0 + */ + void initBooks(int firstBook, int numBooks); + + /** Initialise a book in the passage. + * If the book is already initialised it will be cleared first. + * @param bookNumber Number of the book to initialise. + * @param name Name of the book. + * @param firstChapter Number of first chapter in book. + * @param numChapters Number of chapters covered in this book. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + * @pre numChapters > 0 + */ + void initBook(int bookNumber, + const QString& name, int firstChapter, int numChapters); + + /** Initialise a chapter in the passage. + * If the chapter is already initialised it will be cleared first. + * @param bookNumber Number of the book with the chapter to initialise. + * @param chapterNumber Number of the chapter to initialise. + * @param firstVerse Number of first verse in chapter. + * @param numVerses Number of verses covered in this chapter. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + * @pre firstChapterNumber(bookNumber) <= chapterNumber <= lastChapterNumber(bookNumber) + * @pre numVerses > 0 + */ + void initChapter(int bookNumber, int chapterNumber, + int firstVerse, int numVerses); + + /** Initialise a verse in the passage. + * If the verse is already initialised it will be cleared first. + * @param bookNumber Number of the book with the chapter to initialise. + * @param chapterNumber Number of the chapter with the verse to initialise. + * @param verseNumber Number of the verse to initialise. + * @param headings Headings HTML preceeding this verse. + * @param content Main HTML in this verse. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + * @pre firstChapterNumber(bookNumber) <= chapterNumber <= lastChapterNumber(bookNumber) + * @pre firstVerseNumber(bookNumber) <= verseNumber <= lastVerseNumber(bookNumber) + */ + void initVerse(int bookNumber, int chapterNumber, int verseNumber, + const QString& headings, const QString& content); + + /* + * Accessors + */ + + /// Find whether the passage is empty. + bool isEmpty() const; + /// Get textual key of this passage. QString textualKey() const; + /// Get the first book number in the passage. + int firstBookNumber() const; + /// Get the last book number in the passage. + int lastBookNumber() const; + + /** Get the first chapter number in a book of the passage. + * @param bookNumber The number of the book. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + */ + int firstChapterNumber(int bookNumber) const; + /** Get the last chapter number in a book of the passage. + * @param bookNumber The number of the book. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + */ + int lastChapterNumber(int bookNumber) const; + + /** Get the first verse number in a chapter of the passage. + * @param bookNumber The number of the book. + * @param chapterNumber The number of the chapter within the book. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + * @pre firstChapterNumber(bookNumber) <= chapterNumber <= lastChapterNumber(bookNumber) + */ + int firstVerseNumber(int bookNumber, int chapterNumber) const; + /** Get the last verse number in a chapter of the passage. + * @param bookNumber The number of the book. + * @param chapterNumber The number of the chapter within the book. + * @pre firstBookNumber() <= bookNumber <= lastBookNumber() + * @pre firstChapterNumber(bookNumber) <= chapterNumber <= lastChapterNumber(bookNumber) + */ + int lastVerseNumber(int bookNumber, int chapterNumber) const; + + /* + * Text extraction + */ + + /// Get the entire passaage rendered as HTML. + /// @todo Needs some rendering options, headings, footnotes etc. + QString renderedText(); + private: /* diff --git a/kworship/bible/KwBiblePlaylistItem.cpp b/kworship/bible/KwBiblePlaylistItem.cpp index 58738ec..2c110ac 100644 --- a/kworship/bible/KwBiblePlaylistItem.cpp +++ b/kworship/bible/KwBiblePlaylistItem.cpp @@ -33,10 +33,11 @@ KW_REGISTER_PLAYLIST_ITEM(KwBiblePlaylistItem, "bible") */ /// Construct from reference information. -KwBiblePlaylistItem::KwBiblePlaylistItem(const QString& managerName, const QString& moduleName, const KwBibleModule::Key& moduleKey) +KwBiblePlaylistItem::KwBiblePlaylistItem(const KwBibleModule* module, const KwBibleModule::Key& moduleKey) : KwPlaylistItem() -, m_passage(managerName, moduleName, moduleKey) +, m_passage() { + module->fillPassage(moduleKey, &m_passage); } /// Construct from a DOM element. diff --git a/kworship/bible/KwBiblePlaylistItem.h b/kworship/bible/KwBiblePlaylistItem.h index f79e063..e5a1da3 100644 --- a/kworship/bible/KwBiblePlaylistItem.h +++ b/kworship/bible/KwBiblePlaylistItem.h @@ -33,6 +33,8 @@ #include +class KwBibleManager; + /// A playlist item for bible passages. class KwBiblePlaylistItem : public KwPlaylistItem { @@ -45,11 +47,10 @@ class KwBiblePlaylistItem : public KwPlaylistItem */ /** Construct from reference information. - * @param managerName Identifier of bible manager. - * @param moduleName Identifier of bible module. + * @param module Bible module. * @param moduleKey Bible passage key. */ - KwBiblePlaylistItem(const QString& managerName, const QString& moduleName, const KwBibleModule::Key& moduleKey); + KwBiblePlaylistItem(const KwBibleModule* module, const KwBibleModule::Key& moduleKey); /// Construct from a DOM element. KwBiblePlaylistItem(const QDomElement& element, KwResourceManager* resourceManager); diff --git a/kworship/playlist/KwPlaylistItem.cpp b/kworship/playlist/KwPlaylistItem.cpp index 49ccf89..187c067 100644 --- a/kworship/playlist/KwPlaylistItem.cpp +++ b/kworship/playlist/KwPlaylistItem.cpp @@ -37,7 +37,7 @@ /// Get a factory object. KwPlaylistItem::Factory* KwPlaylistItem::factory() { - static KwPlaylistItem::Factory fac; + static Factory fac; return &fac; } -- 2.11.4.GIT