1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file KwBiblePassage.cpp
22 * @brief A passage of rendered bible text.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwBiblePassage.h"
31 * Constructors + destructor
34 /// Default constructor.
35 KwBiblePassage::KwBiblePassage()
46 KwBiblePassage::~KwBiblePassage()
54 /// Clear the passage.
55 void KwBiblePassage::clearBooks()
57 // Deep cleanup operation
60 int lastBook
= m_firstBook
+ m_numBooks
;
61 for (int bookNumber
= m_firstBook
; bookNumber
< lastBook
; ++bookNumber
)
63 clearChapters(bookNumber
);
70 /// Clear the chapters in a book.
71 void KwBiblePassage::clearChapters(int bookNumber
)
73 Q_ASSERT(0 != m_books
&& bookNumber
>= m_firstBook
&& bookNumber
< m_firstBook
+m_numBooks
);
74 Book
* book
= &m_books
[bookNumber
-m_firstBook
];
75 if (0 != book
->chapters
)
77 int maxChapter
= book
->firstChapter
+ book
->numChapters
;
78 for (int chapterNumber
= book
->firstChapter
; chapterNumber
< maxChapter
; ++chapterNumber
)
80 clearVerses(bookNumber
, chapterNumber
);
82 delete [] book
->chapters
;
87 /// Clear the verses in a chapter.
88 void KwBiblePassage::clearVerses(int bookNumber
, int chapterNumber
)
90 bookNumber
-= m_firstBook
;
91 Q_ASSERT(0 != m_books
&& bookNumber
>= 0 && bookNumber
< m_numBooks
);
92 chapterNumber
-= m_books
[bookNumber
].firstChapter
;
93 Q_ASSERT(0 != m_books
[bookNumber
].chapters
&& chapterNumber
>= 0 && chapterNumber
< m_books
[bookNumber
].numChapters
);
94 Chapter
* chapter
= &m_books
[bookNumber
].chapters
[chapterNumber
];
95 if (0 != chapter
->verses
)
97 delete [] chapter
->verses
;
102 /// Set the source module.
103 void KwBiblePassage::setSource(const QString
& managerId
, const QString
& moduleId
)
105 m_managerId
= managerId
;
106 m_moduleId
= moduleId
;
109 /// Initialise the books in the passage.
110 void KwBiblePassage::initBooks(int firstBook
, int numBooks
)
113 m_firstBook
= firstBook
;
114 m_numBooks
= numBooks
;
115 m_books
= new Book
[numBooks
];
116 for (int i
= 0; i
< numBooks
; ++i
)
118 m_books
[i
].firstChapter
= -1;
119 m_books
[i
].numChapters
= 0;
120 m_books
[i
].chapters
= 0;
124 /// Initialise a book in the passage.
125 void KwBiblePassage::initBook(int bookNumber
,
126 const QString
& name
, int firstChapter
, int numChapters
)
128 clearChapters(bookNumber
);
129 bookNumber
-= m_firstBook
;
130 Book
* book
= &m_books
[bookNumber
];
132 book
->firstChapter
= firstChapter
;
133 book
->numChapters
= numChapters
;
134 book
->chapters
= new Chapter
[numChapters
];
135 for (int i
= 0; i
< numChapters
; ++i
)
137 book
->chapters
[i
].firstVerse
= -1;
138 book
->chapters
[i
].numVerses
= 0;
139 book
->chapters
[i
].verses
= 0;
143 /// Initialise a chapter in the passage.
144 void KwBiblePassage::initChapter(int bookNumber
, int chapterNumber
,
145 int firstVerse
, int numVerses
)
147 clearVerses(bookNumber
, chapterNumber
);
148 bookNumber
-= m_firstBook
;
149 chapterNumber
-= m_books
[bookNumber
].firstChapter
;
150 Chapter
* chapter
= &m_books
[bookNumber
].chapters
[chapterNumber
];
151 chapter
->firstVerse
= firstVerse
;
152 chapter
->numVerses
= numVerses
;
153 chapter
->verses
= new Verse
[numVerses
];
156 /// Initialise a verse in the passage.
157 void KwBiblePassage::initVerse(int bookNumber
, int chapterNumber
, int verseNumber
,
158 const QString
& headings
, const QString
& content
)
160 bookNumber
-= m_firstBook
;
161 Q_ASSERT(0 != m_books
&& bookNumber
>= 0 && bookNumber
< m_numBooks
);
162 chapterNumber
-= m_books
[bookNumber
].firstChapter
;
163 Q_ASSERT(0 != m_books
[bookNumber
].chapters
&& chapterNumber
>= 0 && chapterNumber
< m_books
[bookNumber
].numChapters
);
164 verseNumber
-= m_books
[bookNumber
].chapters
[chapterNumber
].firstVerse
;
165 Q_ASSERT(0 != m_books
[bookNumber
].chapters
[chapterNumber
].verses
&& verseNumber
>= 0 && verseNumber
< m_books
[bookNumber
].chapters
[chapterNumber
].numVerses
);
167 Verse
* verse
= &m_books
[bookNumber
].chapters
[chapterNumber
].verses
[verseNumber
];
168 verse
->headings
= headings
;
169 verse
->content
= content
;
176 /// Find whether the passage is empty.
177 bool KwBiblePassage::isEmpty() const
179 return (m_books
== 0);
182 /// Get textual key of this passage.
183 QString
KwBiblePassage::textualKey() const
188 return i18nc("empty bible passage", "empty");
190 Q_ASSERT(m_books
[0].numChapters
> 0);
191 Q_ASSERT(m_books
[0].chapters
[0].numVerses
> 0);
194 * @bug 2008-dec-22: There is a bug in Qt's handling of right-to-left scripts somewhere
195 * in QString::arg(QString) - in this case from m_books[i].name.
196 * It results in the substitutions taking place in the wrong order.
197 * There also appear to be similar problems rendering even if the
198 * substitutions appear to take place correctly.
199 * I haven't managed to find a satisfactory work-around for this problem
200 * so I'm ignoring it for the time being.
203 QString result
= i18nc("bible index (book, chapter:verse)", "%1 %2",
205 i18nc("bible index (chapter:verse)", "%1:%2",
206 m_books
[0].firstChapter
,
207 m_books
[0].chapters
[0].firstVerse
));
208 Book
* lastBook
= &m_books
[m_numBooks
- 1];
209 Chapter
* lastChapter
= &lastBook
->chapters
[lastBook
->numChapters
- 1];
210 // Overlapping multiple books
213 result
= i18nc("bible passage range (book chapter:verse, book chapter:verse)", "%1 - %2", result
,
214 i18nc("bible index (book, chapter:verse)", "%1 %2",
216 i18nc("bible index (chapter:verse)", "%1:%2",
217 lastBook
->firstChapter
+ lastBook
->numChapters
- 1,
218 lastChapter
->firstVerse
+ lastChapter
->numVerses
- 1)));
220 // Overlapping multiple chapters
221 else if (lastBook
->numChapters
> 1)
223 result
= i18nc("bible passage range (book chapter:verse, chapter:verse)", "%1 - %2", result
,
224 i18nc("bible index (chapter:verse)", "%1:%2",
225 lastBook
->firstChapter
+ lastBook
->numChapters
- 1,
226 lastChapter
->firstVerse
+ lastChapter
->numVerses
- 1));
228 // Overlapping multiple verses
229 else if (lastChapter
->numVerses
> 1)
231 result
= i18nc("bible passage range (book chapter:verse, verse)", "%1-%2", result
,
232 lastChapter
->firstVerse
+ lastChapter
->numVerses
- 1);
235 // Module name is quite important too
236 return i18nc("bible index (range, version)", "%1 (%2)", result
, m_moduleId
);
239 /// Get the first book number in the passage.
240 int KwBiblePassage::firstBookNumber() const
242 Q_ASSERT(false && "Unimplemented");
245 /// Get the last book number in the passage.
246 int KwBiblePassage::lastBookNumber() const
248 Q_ASSERT(false && "Unimplemented");
251 /// Get the first chapter number in a book of the passage.
252 int KwBiblePassage::firstChapterNumber(int bookNumber
) const
254 Q_ASSERT(false && "Unimplemented");
257 /// Get the last chapter number in a book of the passage.
258 int KwBiblePassage::lastChapterNumber(int bookNumber
) const
260 Q_ASSERT(false && "Unimplemented");
263 /// Get the first verse number in a chapter of the passage.
264 int KwBiblePassage::firstVerseNumber(int bookNumber
, int chapterNumber
) const
266 Q_ASSERT(false && "Unimplemented");
269 /// Get the last verse number in a chapter of the passage.
270 int KwBiblePassage::lastVerseNumber(int bookNumber
, int chapterNumber
) const
272 Q_ASSERT(false && "Unimplemented");
279 /// Get the entire passaage rendered as HTML.
280 QString
KwBiblePassage::renderedText() const
283 Book
* book
= m_books
;
284 for (int bookIndex
= 0; bookIndex
< m_numBooks
; ++bookIndex
)
286 Chapter
* chapter
= book
->chapters
;
287 for (int chapterIndex
= 0; chapterIndex
< book
->numChapters
; ++chapterIndex
)
289 Verse
* verse
= chapter
->verses
;
290 for (int verseIndex
= 0; verseIndex
< chapter
->numVerses
; ++verseIndex
)
292 if (!verse
->headings
.isEmpty())
294 result
+= verse
->headings
;
296 if (!verse
->content
.isEmpty())
298 result
+= QString("<sup>%1</sup>").arg(chapter
->firstVerse
+ verseIndex
);
299 result
+= verse
->content
;