Finished (for now) filling of bible passage and now renders html from it
[kworship.git] / kworship / KwBiblePlugin.cpp
blob629d8abdd76ad4d9040d6498a1e88544915c668f
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 KwBiblePlugin.cpp
22 * @brief Bibles plugin.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwBiblePlugin.h"
27 #include "KwApplication.h"
28 #include "kworship.h"
29 #include "KwDocument.h"
31 #include <KwBibleManager.h>
32 #include "KwBibleManagerSword.h"
33 #include "KwBibleManagerBibleGateway.h"
34 #include <KwBibleModule.h>
35 #include <KwBiblePlaylistItem.h>
37 #include <KwPlaylistModel.h>
39 #include <KLocale>
40 #include <KAction>
41 #include <KMessageBox>
43 #include <QMainWindow>
44 #include <QDockWidget>
45 #include <QHBoxLayout>
46 #include <QVBoxLayout>
47 #include <QComboBox>
48 #include <QLabel>
49 #include <QLineEdit>
50 #include <QTextEdit>
51 #include <QToolBar>
54 * Constructors + destructor
57 /// Default constructor.
58 KwBiblePlugin::KwBiblePlugin()
59 : KwPlugin("bible",
60 i18n("Bible"),
61 i18n("The bible plugin allows for the navigation and display of "
62 "bible extracts from SWORD and BibleGateway.com."))
63 , m_managers()
64 , m_insertIntoPlaylistAction(0)
65 , m_showNowAction(0)
66 , m_docker(0)
67 , m_managerTabs(0)
68 , m_comboBook(0)
69 , m_comboChapter(0)
70 , m_editRange(0)
71 , m_textPassage(0)
73 KwBibleManagerSword::registerManager();
74 KwBibleManagerBibleGateway::registerManager();
77 /// Destructor.
78 KwBiblePlugin::~KwBiblePlugin()
80 // Ensure all GUI stuff is cleaned up
81 KwBiblePlugin::_unload();
85 * Accessors
88 /// Get the current bible passage information.
89 bool KwBiblePlugin::resolvePassage(KwBibleManager** manager, KwBibleModule** module, KwBibleModule::Key* key, bool* usedSearch) const
91 // Get the current bible manager
92 int tab = m_managerTabs->currentIndex();
93 if (tab >= 0 && tab < m_managers.size())
95 const BibleManager& mgr = m_managers[tab];
96 *manager = mgr.manager;
98 // Is a bible selected?
99 int bibleInd = mgr.comboBibles->currentIndex();
100 QString bible;
101 KwBibleModule* mod = 0;
102 if (bibleInd >= 0)
104 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
105 mod = mgr.manager->module(bible);
107 if (0 != mod)
109 *module = mod;
110 // Is a book selected?
111 int bookIndex = m_comboBook->currentIndex();
112 int chapterIndex = -1;
113 if (bookIndex >= 0)
115 // Is a chapter selected?
116 chapterIndex = m_comboChapter->currentIndex();
119 bool valid;
120 KwBibleModule::Key relativeKey = mod->createKey(bookIndex, chapterIndex);
121 *key = mod->createKey(relativeKey, m_editRange->text(), &valid);
123 if (0 != usedSearch)
125 *usedSearch = true;
127 return valid;
130 if (0 != usedSearch)
132 *usedSearch = false;
134 return false;
138 * Private slots
141 /// Fired when the connect to bible button is pressed.
142 void KwBiblePlugin::slotConnect()
144 // Get the current bible manager
145 int tab = m_managerTabs->currentIndex();
146 Q_ASSERT(tab >= 0 && tab < m_managers.size());
147 BibleManager* mgr = &m_managers[tab];
149 // This will force the connection
150 fillBiblesList(mgr);
151 if (mgr->comboBibles->count() == 0)
153 KMessageBox::information(m_docker, i18n("No bibles found"));
155 else
157 mgr->comboBibles->setEnabled(true);
161 /// Fired when the bible is changed.
162 void KwBiblePlugin::slotBibleChanged()
164 // Get the current bible manager
165 int tab = m_managerTabs->currentIndex();
166 if (tab >= 0 && tab < m_managers.size())
168 BibleManager& mgr = m_managers[tab];
169 bool enabled = mgr.comboBibles->isEnabled();
171 // Is a bible selected?
172 int bibleInd = mgr.comboBibles->currentIndex();
173 QString bible;
174 KwBibleModule* module = 0;
175 if (bibleInd >= 0)
177 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
178 module = mgr.manager->module(bible);
181 // Update the list of books
182 QString book = m_comboBook->currentText();
183 int chapter = m_comboChapter->currentIndex();
184 m_comboBook->clear();
185 if (0 != module)
187 QStringList bookNames = module->books();
188 for (int i = 0; i < bookNames.size(); ++i)
190 const QString& bookName = bookNames[i];
191 m_comboBook->addItem(bookName, QVariant(i));
193 int index = m_comboBook->findText(book);
194 bool canPreserveBook = (index >= 0);
195 if (!canPreserveBook && bookNames.size() > 0)
197 index = 0;
199 m_comboBook->setCurrentIndex(index);
200 if (canPreserveBook && chapter >= 0)
202 // If we can restore book, also restore chapter
203 m_comboChapter->setCurrentIndex(chapter);
206 else
208 enabled = false;
211 m_comboBook->setEnabled(enabled);
212 m_comboChapter->setEnabled(enabled);
213 m_editRange->setEnabled(enabled);
217 /// Fired when the bible book is changed.
218 void KwBiblePlugin::slotBookChanged()
220 m_comboChapter->clear();
222 // Get the current bible manager
223 int tab = m_managerTabs->currentIndex();
224 if (tab >= 0 && tab < m_managers.size())
226 BibleManager& mgr = m_managers[tab];
228 // Is a bible selected?
229 int bibleInd = mgr.comboBibles->currentIndex();
230 QString bible;
231 KwBibleModule* module = 0;
232 if (bibleInd >= 0)
234 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
235 module = mgr.manager->module(bible);
237 if (0 != module)
239 // Is a book selected?
240 int index = m_comboBook->currentIndex();
241 if (index >= 0)
243 int bookIndex = m_comboBook->itemData(index).toInt();
244 int numChapters = module->numChapters(bookIndex);
245 for (int i = 0; i < numChapters; ++i)
247 m_comboChapter->addItem(QString("%1").arg(i+1), QVariant(i));
252 slotVerseRange();
255 /// Fired when the bible text needs to be retrieved.
256 void KwBiblePlugin::slotVerseRange()
258 KwBibleManager* manager;
259 KwBibleModule* module;
260 KwBibleModule::Key key;
261 bool usedSearch;
262 bool success = resolvePassage(&manager, &module, &key, &usedSearch);
263 if (usedSearch)
265 m_comboBook->setCurrentIndex(key.start.book);
266 m_comboChapter->setCurrentIndex(key.start.chapter);
268 KwBiblePassage passage;
269 module->fillPassage(key, &passage);
270 m_textPassage->document()->setHtml(passage.renderedText());
272 m_insertIntoPlaylistAction->setEnabled(true);
273 m_showNowAction->setEnabled(true);
275 // Update color of search box
276 static QPalette p = m_editRange->palette();
277 QPalette changedPal = p;
278 if (!success)
280 changedPal.setColor( QPalette::Normal, QPalette::Base, QColor(255, 127, 127) );
282 m_editRange->setPalette(changedPal);
284 return;
286 m_textPassage->document()->setPlainText(QString());
287 m_insertIntoPlaylistAction->setEnabled(false);
288 m_showNowAction->setEnabled(false);
291 /// Fired by the insert into playlist action.
292 void KwBiblePlugin::slotInsertIntoPlaylist()
294 KwBibleManager* manager;
295 KwBibleModule* module;
296 KwBibleModule::Key key;
297 bool success = resolvePassage(&manager, &module, &key);
299 if (success)
301 KwBiblePlaylistItem* item = new KwBiblePlaylistItem(module, key);
302 KwPlaylistModel* model = KwApplication::self()->mainWindow()->playlistModel();
303 model->addItem(QModelIndex(), item);
307 /// Fired by the show now action.
308 void KwBiblePlugin::slotShowNow()
313 * Loading and unloading virtual interface
316 void KwBiblePlugin::_load()
318 // Construct the bible managers.
319 QStringList managerNames;
320 managerNames << "SWORD";
321 managerNames << "BibleGateway.com";
322 QList<KwBibleManager*> managers;
323 foreach (QString name, managerNames)
325 KwBibleManager* manager = KwBibleManagerSword::singleton(name);
326 if (0 != manager)
328 managers += manager;
332 // Set up the docker
333 m_docker = new QDockWidget(i18n("Bible"));
334 m_docker->setObjectName("dockBible");
335 QWidget* mainDockWidget = new QWidget(/*m_docker*/);
336 QVBoxLayout* dockLayout = new QVBoxLayout(mainDockWidget);
337 m_docker->setWidget(mainDockWidget);
339 // The tab bar of bible managers
340 m_managerTabs = new QTabWidget(m_docker);
341 m_managerTabs->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
342 connect(m_managerTabs, SIGNAL(currentChanged(int)),
343 this, SLOT(slotBibleChanged()));
344 dockLayout->addWidget(m_managerTabs);
346 // Bible navigation combo boxes
347 QWidget* bibleNavigationWidget = new QWidget(mainDockWidget);
348 QHBoxLayout* bibleNavigationLayout = new QHBoxLayout(bibleNavigationWidget);
349 dockLayout->addWidget(bibleNavigationWidget);
351 m_comboBook = new QComboBox(bibleNavigationWidget);
352 m_comboChapter = new QComboBox(bibleNavigationWidget);
353 bibleNavigationLayout->addWidget(m_comboBook);
354 bibleNavigationLayout->addWidget(m_comboChapter);
356 // Verse range text box and label
357 QWidget* verseRangeWidget = new QWidget(mainDockWidget);
358 QHBoxLayout* verseRangeLayout = new QHBoxLayout(verseRangeWidget);
359 dockLayout->addWidget(verseRangeWidget);
361 QLabel* labelRange = new QLabel(i18n("&Verses"), verseRangeWidget);
362 m_editRange = new QLineEdit(verseRangeWidget);
363 labelRange->setBuddy(m_editRange);
364 verseRangeLayout->addWidget(labelRange);
365 verseRangeLayout->addWidget(m_editRange);
367 m_textPassage = new QTextEdit(mainDockWidget);
368 m_textPassage->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
369 dockLayout->addWidget(m_textPassage);
371 // Toolbar
372 QToolBar* bibleToolBar = new QToolBar("bibleToolBar");
373 bibleToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
374 dockLayout->addWidget(bibleToolBar);
376 m_insertIntoPlaylistAction = new KAction(KIcon("player_playlist"), i18n("Insert Into Playlist"), bibleToolBar);
377 m_insertIntoPlaylistAction->setEnabled(false);
378 connect(m_insertIntoPlaylistAction, SIGNAL(triggered(bool)),
379 this, SLOT(slotInsertIntoPlaylist()));
380 bibleToolBar->addAction(m_insertIntoPlaylistAction);
382 m_showNowAction = new KAction(KIcon("player_playlist"), i18n("Show Now"), bibleToolBar);
383 m_showNowAction->setEnabled(false);
384 connect(m_showNowAction, SIGNAL(triggered(bool)),
385 this, SLOT(slotShowNow()));
386 bibleToolBar->addAction(m_showNowAction);
388 // Fill out tabs and manager data
389 foreach (KwBibleManager* manager, managers)
391 QString name = manager->name();
392 BibleManager mgr;
393 mgr.manager = manager;
395 QWidget* tabWidget = new QWidget();
396 QHBoxLayout* layout = new QHBoxLayout(tabWidget);
398 mgr.comboBibles = new QComboBox();
399 connect(mgr.comboBibles, SIGNAL(currentIndexChanged(int)),
400 this, SLOT(slotBibleChanged()));
402 // Only fill the module list if the manager is local
403 // Otherwise we should wait until the user requests it
404 if (manager->isRemote())
406 mgr.comboBibles->setEnabled(false);
408 mgr.toolBar = new QToolBar();
409 KAction* connectToBible = new KAction(KIcon("network-connect"), i18n("Connect to %1", name), mgr.toolBar);
410 connect(connectToBible, SIGNAL(triggered(bool)),
411 this, SLOT(slotConnect()));
412 mgr.toolBar->addAction(connectToBible);
413 layout->addWidget(mgr.toolBar);
415 // Toolbar should be as small as possible
416 QSizePolicy policy;
418 policy = mgr.toolBar->sizePolicy();
419 policy.setHorizontalStretch(1);
420 mgr.toolBar->setSizePolicy(policy);
422 policy = mgr.comboBibles->sizePolicy();
423 policy.setHorizontalStretch(10);
424 mgr.comboBibles->setSizePolicy(policy);
426 else
428 mgr.toolBar = 0;
429 fillBiblesList(&mgr);
432 layout->addWidget(mgr.comboBibles);
434 m_managerTabs->addTab(tabWidget, name);
435 m_managers.push_back(mgr);
437 // Ensure widgets are apropriately modified
438 connect(m_comboBook, SIGNAL(currentIndexChanged(int)),
439 this, SLOT(slotBookChanged()));
440 connect(m_comboChapter, SIGNAL(currentIndexChanged(int)),
441 this, SLOT(slotVerseRange()));
442 connect(m_editRange, SIGNAL(textChanged(const QString&)),
443 this, SLOT(slotVerseRange()));
445 KwApplication::self()->mainWindow()->addDockWidget(Qt::LeftDockWidgetArea, m_docker);
447 slotBibleChanged();
450 void KwBiblePlugin::_unload()
452 // Clean up the bible managers.
453 /// @todo IMPLEMENT!!!
454 delete m_docker;
458 * Private functions
461 /// Fill up the bibles list for a manager.
462 void KwBiblePlugin::fillBiblesList(BibleManager* mgr)
464 QStringList languages = mgr->manager->languages();
465 mgr->comboBibles->clear();
466 mgr->comboBibles->addItem(i18n("-- select a translation --"));
467 foreach (QString language, languages)
469 QStringList modules = mgr->manager->moduleNamesInLanguage(language);
470 if (!modules.isEmpty())
472 mgr->comboBibles->addItem(language, QVariant(modules.first()));
473 foreach (QString module, modules)
475 mgr->comboBibles->addItem(" " + module, QVariant(module));