Bibletime – a bible study tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cswordbiblemoduleinfo.cpp 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*********
  2. *
  3. * This file is part of BibleTime's source code, http://www.bibletime.info/.
  4. *
  5. * Copyright 1999-2006 by the BibleTime developers.
  6. * The BibleTime source code is licensed under the GNU General Public License version 2.0.
  7. *
  8. **********/
  9. //BibleTime includes
  10. #include "cswordbiblemoduleinfo.h"
  11. #include "cswordbackend.h"
  12. #include "cswordversekey.h"
  13. // #include "util/cpointers.h"
  14. //Qt includes
  15. #include <tqfile.h>
  16. //Sword includes
  17. #include <versekey.h>
  18. // Boost includes
  19. // TODO: Detect Boost in autoconf
  20. #include <boost/scoped_ptr.hpp>
  21. static sword::VerseKey staticKey;
  22. CSwordBibleModuleInfo::CSwordBibleModuleInfo( sword::SWModule* module, CSwordBackend* const usedBackend )
  23. : CSwordModuleInfo(module, usedBackend),
  24. m_lowerBound(0),
  25. m_upperBound(0),
  26. m_bookList(0),
  27. m_cachedLocale("unknown"),
  28. m_hasOT(-1),
  29. m_hasNT(-1) {}
  30. CSwordBibleModuleInfo::CSwordBibleModuleInfo( const CSwordBibleModuleInfo& m ) :
  31. CSwordModuleInfo(m),
  32. m_lowerBound(0),
  33. m_upperBound(0),
  34. m_bookList(0) {
  35. if (m.m_bookList) {
  36. m_bookList = new TQStringList();
  37. *m_bookList = *m.m_bookList;
  38. }
  39. m_hasOT = m.m_hasOT;
  40. m_hasNT = m.m_hasNT;
  41. m_cachedLocale = m.m_cachedLocale;
  42. }
  43. CSwordModuleInfo* CSwordBibleModuleInfo::clone() {
  44. return new CSwordBibleModuleInfo(*this);
  45. }
  46. CSwordBibleModuleInfo::~CSwordBibleModuleInfo() {
  47. delete m_bookList;
  48. }
  49. void CSwordBibleModuleInfo::initBounds() {
  50. if (m_hasOT == -1) {
  51. m_hasOT = hasTestament(OldTestament);
  52. }
  53. if (m_hasNT == -1) {
  54. m_hasNT = hasTestament(NewTestament);
  55. }
  56. if (m_hasOT) {
  57. m_lowerBound.key("Genesis 1:1");
  58. }
  59. else {
  60. m_lowerBound.key("Matthew 1:1");
  61. }
  62. if (!m_hasNT) {
  63. m_upperBound.key("Malachi 4:6");
  64. }
  65. else {
  66. m_upperBound.key("Revelation of John 22:21");
  67. }
  68. }
  69. /** Returns the books available in this module */
  70. TQStringList* const CSwordBibleModuleInfo::books() {
  71. if (m_cachedLocale != backend()->booknameLanguage()) { //if the locale has changed
  72. delete m_bookList;
  73. m_bookList = 0;
  74. }
  75. if (!m_bookList) {
  76. m_bookList = new TQStringList();
  77. initBounds();
  78. int min = 0;
  79. int max = 1;
  80. //find out if we have ot and nt, only ot or only nt
  81. if (m_hasOT>0 && m_hasNT>0) { //both
  82. min = 0;
  83. max = 1;
  84. }
  85. else if (m_hasOT>0 && !m_hasNT) { //only OT
  86. min = 0;
  87. max = 0;
  88. }
  89. else if (!m_hasOT && m_hasNT>0) { //only NT
  90. min = 1;
  91. max = 1;
  92. }
  93. else if (!m_hasOT && !m_hasNT) { //somethings wrong here! - no OT and no NT
  94. qWarning("CSwordBibleModuleInfo (%s) no OT and not NT! Check your config!", module()->Name());
  95. min = 0;
  96. max = -1;
  97. }
  98. boost::scoped_ptr<sword::VerseKey> key((sword::VerseKey *)module()->CreateKey());
  99. (*key) = sword::TOP;
  100. for (key->Testament(min+1); !key->Error() && (key->Testament()-1) <= max; key->Book(key->Book()+1)) {
  101. m_bookList->append( TQString::fromUtf8(key->getBookName()) );
  102. }
  103. m_cachedLocale = backend()->booknameLanguage();
  104. }
  105. return m_bookList;
  106. }
  107. /** Returns the number of chapters for the given book. */
  108. const unsigned int CSwordBibleModuleInfo::chapterCount(const unsigned int book) {
  109. int result = 0;
  110. boost::scoped_ptr<sword::VerseKey> key((sword::VerseKey *)module()->CreateKey());
  111. (*key) = sword::TOP;
  112. // works for old and new versions
  113. key->Book(book);
  114. (*key) = sword::MAXCHAPTER;
  115. result = key->Chapter();
  116. return result;
  117. }
  118. const unsigned int CSwordBibleModuleInfo::chapterCount(const TQString& book) {
  119. return chapterCount( bookNumber(book) );
  120. }
  121. /** Returns the number of verses for the given chapter. */
  122. const unsigned int CSwordBibleModuleInfo::verseCount( const unsigned int book, const unsigned int chapter ) {
  123. unsigned int result = 0;
  124. boost::scoped_ptr<sword::VerseKey> key((sword::VerseKey *)module()->CreateKey());
  125. (*key) = sword::TOP;
  126. // works for old and new versions
  127. key->Book(book);
  128. key->Chapter(chapter);
  129. (*key) = sword::MAXVERSE;
  130. result = key->Verse();
  131. return result;
  132. }
  133. const unsigned int CSwordBibleModuleInfo::verseCount( const TQString& book, const unsigned int chapter ) {
  134. return verseCount( bookNumber(book), chapter );
  135. }
  136. const unsigned int CSwordBibleModuleInfo::bookNumber(const TQString &book) {
  137. unsigned int bookNumber = 0;
  138. //find out if we have ot and nt, only ot or only nt
  139. initBounds();
  140. boost::scoped_ptr<sword::VerseKey> key((sword::VerseKey *)module()->CreateKey());
  141. (*key) = sword::TOP;
  142. #ifdef SWORD_MULTIVERSE
  143. key->setBookName(book.utf8().data());
  144. bookNumber = ((key->Testament() > 1) ? key->BMAX[0] : 0) + key->Book();
  145. #else
  146. bool found = false;
  147. int min = 0;
  148. int max = 1;
  149. if ((m_hasOT>0 && m_hasNT>0) || (m_hasOT == -1 && m_hasNT == -1)) {
  150. min = 0;
  151. max = 1;
  152. bookNumber = 0;
  153. }
  154. else if (m_hasOT>0 && !m_hasNT) {
  155. min = 0;
  156. max = 0;
  157. bookNumber = 0;
  158. }
  159. else if (!m_hasOT && m_hasNT>0) {
  160. min = 1;
  161. max = 1;
  162. bookNumber = key->BMAX[0];
  163. }
  164. else if (!m_hasOT && !m_hasNT) {
  165. min = 0;
  166. max = -1; //no loop
  167. bookNumber = 0;
  168. }
  169. for (int i = min; i <= max && !found; ++i) {
  170. for ( int j = 0; j < key->BMAX[i] && !found; ++j) {
  171. ++bookNumber;
  172. if (book == TQString::fromUtf8( key->books[i][j].name) )
  173. found = true;
  174. }
  175. }
  176. #endif
  177. return bookNumber;
  178. }
  179. /** Returns true if his module has the text of desired type of testament */
  180. const bool CSwordBibleModuleInfo::hasTestament( CSwordBibleModuleInfo::Testament type ) {
  181. if (m_hasOT == -1 || m_hasNT == -1) {
  182. const bool oldStatus = module()->getSkipConsecutiveLinks();
  183. module()->setSkipConsecutiveLinks(true);
  184. *module() = sword::TOP; //position to first entry
  185. sword::VerseKey key( module()->KeyText() );
  186. if (key.Testament() == 1) { // OT && NT
  187. m_hasOT = 1;
  188. }
  189. else if (key.Testament() == 2) { //no OT
  190. m_hasOT = 0;
  191. }
  192. *module() = sword::BOTTOM;
  193. key = module()->KeyText();
  194. if (key.Testament() == 1) { // only OT, no NT
  195. m_hasNT = 0;
  196. }
  197. else if (key.Testament() == 2) { //has NT
  198. m_hasNT = 1;
  199. }
  200. module()->setSkipConsecutiveLinks(oldStatus);
  201. }
  202. switch (type) {
  203. case OldTestament:
  204. return m_hasOT>0;
  205. case NewTestament:
  206. return m_hasNT>0;
  207. default:
  208. return false;
  209. }
  210. }