KwBiblePassage::renderedText can be const
[kworship.git] / kworship / bible / KwBiblePassage.cpp
blobb83bc93ce1771d4383a522709ad0bad874d8d29c
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 /**
21 * @file KwBiblePassage.cpp
22 * @brief A passage of rendered bible text.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwBiblePassage.h"
28 #include <KLocale>
31 * Constructors + destructor
34 /// Default constructor.
35 KwBiblePassage::KwBiblePassage()
36 : m_managerId()
37 , m_moduleId()
38 , m_key()
39 , m_firstBook(0)
40 , m_numBooks(0)
41 , m_books(0)
45 /// Destructor.
46 KwBiblePassage::~KwBiblePassage()
51 * Main interface
54 /// Clear the passage.
55 void KwBiblePassage::clearBooks()
57 // Deep cleanup operation
58 if (0 != m_books)
60 int lastBook = m_firstBook + m_numBooks;
61 for (int bookNumber = m_firstBook; bookNumber < lastBook; ++bookNumber)
63 clearChapters(bookNumber);
65 delete [] m_books;
66 m_books = 0;
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;
83 book->chapters = 0;
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;
98 chapter->verses = 0;
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)
112 clearBooks();
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];
131 book->name = name;
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;
173 * Accessors
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
185 // Empty range
186 if (0 == m_numBooks)
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",
204 m_books[0].name,
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
211 if (m_numBooks > 1)
213 result = i18nc("bible passage range (book chapter:verse, book chapter:verse)", "%1 - %2", result,
214 i18nc("bible index (book, chapter:verse)", "%1 %2",
215 lastBook->name,
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");
276 * Text extraction
279 /// Get the entire passaage rendered as HTML.
280 QString KwBiblePassage::renderedText() const
282 QString result;
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;
301 ++verse;
303 ++chapter;
305 ++book;
307 return result;