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.

269 lines
5.9KB

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