Restructured main with new KwApplication and plugin manager to use it
[kworship.git] / kworship / KwBiblePlugin.cpp
blob22898c156acad4d528a5dfa9b4e2d6ac7fd6431d
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)
75 /// Destructor.
76 KwBiblePlugin::~KwBiblePlugin()
78 // Ensure all GUI stuff is cleaned up
79 KwBiblePlugin::_unload();
83 * Private slots
86 /// Fired when the connect to bible button is pressed.
87 void KwBiblePlugin::slotConnect()
89 // Get the current bible manager
90 int tab = m_managerTabs->currentIndex();
91 Q_ASSERT(tab >= 0 && tab < m_managers.size());
92 BibleManager* mgr = &m_managers[tab];
94 // This will force the connection
95 fillBiblesList(mgr);
96 if (mgr->comboBibles->count() == 0)
98 KMessageBox::information(m_docker, i18n("No bibles found"));
100 else
102 mgr->comboBibles->setEnabled(true);
106 /// Fired when the bible is changed.
107 void KwBiblePlugin::slotBibleChanged()
109 // Get the current bible manager
110 int tab = m_managerTabs->currentIndex();
111 if (tab >= 0 && tab < m_managers.size())
113 BibleManager& mgr = m_managers[tab];
114 bool enabled = mgr.comboBibles->isEnabled();
116 // Is a bible selected?
117 int bibleInd = mgr.comboBibles->currentIndex();
118 QString bible;
119 KwBibleModule* module = 0;
120 if (bibleInd >= 0)
122 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
123 module = mgr.manager->module(bible);
126 // Update the list of books
127 QString book = m_comboBook->currentText();
128 int chapter = m_comboChapter->currentIndex();
129 m_comboBook->clear();
130 if (0 != module)
132 QStringList bookNames = module->books();
133 for (int i = 0; i < bookNames.size(); ++i)
135 const QString& bookName = bookNames[i];
136 m_comboBook->addItem(bookName, QVariant(i));
138 int index = m_comboBook->findText(book);
139 bool canPreserveBook = (index >= 0);
140 if (!canPreserveBook && bookNames.size() > 0)
142 index = 0;
144 m_comboBook->setCurrentIndex(index);
145 if (canPreserveBook && chapter >= 0)
147 // If we can restore book, also restore chapter
148 m_comboChapter->setCurrentIndex(chapter);
151 else
153 enabled = false;
156 m_comboBook->setEnabled(enabled);
157 m_comboChapter->setEnabled(enabled);
158 m_editRange->setEnabled(enabled);
162 /// Fired when the bible book is changed.
163 void KwBiblePlugin::slotBookChanged()
165 m_comboChapter->clear();
167 // Get the current bible manager
168 int tab = m_managerTabs->currentIndex();
169 if (tab >= 0 && tab < m_managers.size())
171 BibleManager& mgr = m_managers[tab];
173 // Is a bible selected?
174 int bibleInd = mgr.comboBibles->currentIndex();
175 QString bible;
176 KwBibleModule* module = 0;
177 if (bibleInd >= 0)
179 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
180 module = mgr.manager->module(bible);
182 if (0 != module)
184 // Is a book selected?
185 int index = m_comboBook->currentIndex();
186 if (index >= 0)
188 int bookIndex = m_comboBook->itemData(index).toInt();
189 int numChapters = module->numChapters(bookIndex);
190 for (int i = 0; i < numChapters; ++i)
192 m_comboChapter->addItem(QString("%1").arg(i+1), QVariant(i));
197 slotVerseRange();
200 /// Fired when the bible text needs to be retrieved.
201 void KwBiblePlugin::slotVerseRange()
203 // Get the current bible manager
204 int tab = m_managerTabs->currentIndex();
205 if (tab >= 0 && tab < m_managers.size())
207 BibleManager& mgr = m_managers[tab];
209 // Is a bible selected?
210 int bibleInd = mgr.comboBibles->currentIndex();
211 QString bible;
212 KwBibleModule* module = 0;
213 if (bibleInd >= 0)
215 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
216 module = mgr.manager->module(bible);
218 if (0 != module)
220 // Is a book selected?
221 int bookIndex = m_comboBook->currentIndex();
222 int chapterIndex = -1;
223 if (bookIndex >= 0)
225 // Is a chapter selected?
226 chapterIndex = m_comboChapter->currentIndex();
229 bool valid;
230 KwBibleModule::Key relativeKey = module->createKey(bookIndex, chapterIndex);
231 KwBibleModule::Key key = module->createKey(relativeKey, m_editRange->text(), &valid);
232 // Update book and chapter
233 m_comboBook->setCurrentIndex(key.start.book);
234 m_comboChapter->setCurrentIndex(key.start.chapter);
235 m_textPassage->document()->setHtml(module->renderText(key));
237 m_insertIntoPlaylistAction->setEnabled(true);
238 m_showNowAction->setEnabled(true);
240 // Update color of search box
241 static QPalette p = m_editRange->palette();
242 QPalette changedPal = p;
243 if (!valid)
245 changedPal.setColor( QPalette::Normal, QPalette::Base, QColor(255, 127, 127) );
247 m_editRange->setPalette(changedPal);
249 return;
252 m_textPassage->document()->setPlainText(QString());
253 m_insertIntoPlaylistAction->setEnabled(false);
254 m_showNowAction->setEnabled(false);
257 /// Fired by the insert into playlist action.
258 void KwBiblePlugin::slotInsertIntoPlaylist()
260 KwBiblePlaylistItem* item = new KwBiblePlaylistItem();
261 KwPlaylistModel* model = KwApplication::self()->mainWindow()->playlistModel();
262 model->addItem(QModelIndex(), item);
265 /// Fired by the show now action.
266 void KwBiblePlugin::slotShowNow()
271 * Loading and unloading virtual interface
274 void KwBiblePlugin::_load()
276 // Construct the bible managers.
277 QList<KwBibleManager*> managers;
278 managers.push_back(new KwBibleManagerSword);
279 managers.push_back(new KwBibleManagerBibleGateway);
281 // Set up the docker
282 m_docker = new QDockWidget(i18n("Bible"));
283 m_docker->setObjectName("dockBible");
284 QWidget* mainDockWidget = new QWidget(/*m_docker*/);
285 QVBoxLayout* dockLayout = new QVBoxLayout(mainDockWidget);
286 m_docker->setWidget(mainDockWidget);
288 // The tab bar of bible managers
289 m_managerTabs = new QTabWidget(m_docker);
290 m_managerTabs->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
291 connect(m_managerTabs, SIGNAL(currentChanged(int)),
292 this, SLOT(slotBibleChanged()));
293 dockLayout->addWidget(m_managerTabs);
295 // Bible navigation combo boxes
296 QWidget* bibleNavigationWidget = new QWidget(mainDockWidget);
297 QHBoxLayout* bibleNavigationLayout = new QHBoxLayout(bibleNavigationWidget);
298 dockLayout->addWidget(bibleNavigationWidget);
300 m_comboBook = new QComboBox(bibleNavigationWidget);
301 m_comboChapter = new QComboBox(bibleNavigationWidget);
302 bibleNavigationLayout->addWidget(m_comboBook);
303 bibleNavigationLayout->addWidget(m_comboChapter);
305 // Verse range text box and label
306 QWidget* verseRangeWidget = new QWidget(mainDockWidget);
307 QHBoxLayout* verseRangeLayout = new QHBoxLayout(verseRangeWidget);
308 dockLayout->addWidget(verseRangeWidget);
310 QLabel* labelRange = new QLabel(i18n("&Verses"), verseRangeWidget);
311 m_editRange = new QLineEdit(verseRangeWidget);
312 labelRange->setBuddy(m_editRange);
313 verseRangeLayout->addWidget(labelRange);
314 verseRangeLayout->addWidget(m_editRange);
316 m_textPassage = new QTextEdit(mainDockWidget);
317 m_textPassage->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
318 dockLayout->addWidget(m_textPassage);
320 // Toolbar
321 QToolBar* bibleToolBar = new QToolBar("bibleToolBar");
322 bibleToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
323 dockLayout->addWidget(bibleToolBar);
325 m_insertIntoPlaylistAction = new KAction(KIcon("player_playlist"), i18n("Insert Into Playlist"), bibleToolBar);
326 m_insertIntoPlaylistAction->setEnabled(false);
327 connect(m_insertIntoPlaylistAction, SIGNAL(triggered(bool)),
328 this, SLOT(slotInsertIntoPlaylist()));
329 bibleToolBar->addAction(m_insertIntoPlaylistAction);
331 m_showNowAction = new KAction(KIcon("player_playlist"), i18n("Show Now"), bibleToolBar);
332 m_showNowAction->setEnabled(false);
333 connect(m_showNowAction, SIGNAL(triggered(bool)),
334 this, SLOT(slotShowNow()));
335 bibleToolBar->addAction(m_showNowAction);
337 // Fill out tabs and manager data
338 foreach (KwBibleManager* manager, managers)
340 QString name = manager->name();
341 BibleManager mgr;
342 mgr.manager = manager;
344 QWidget* tabWidget = new QWidget();
345 QHBoxLayout* layout = new QHBoxLayout(tabWidget);
347 mgr.comboBibles = new QComboBox();
348 connect(mgr.comboBibles, SIGNAL(currentIndexChanged(int)),
349 this, SLOT(slotBibleChanged()));
351 // Only fill the module list if the manager is local
352 // Otherwise we should wait until the user requests it
353 if (manager->isRemote())
355 mgr.comboBibles->setEnabled(false);
357 mgr.toolBar = new QToolBar();
358 KAction* connectToBible = new KAction(KIcon("network-connect"), i18n("Connect to %1", name), mgr.toolBar);
359 connect(connectToBible, SIGNAL(triggered(bool)),
360 this, SLOT(slotConnect()));
361 mgr.toolBar->addAction(connectToBible);
362 layout->addWidget(mgr.toolBar);
364 // Toolbar should be as small as possible
365 QSizePolicy policy;
367 policy = mgr.toolBar->sizePolicy();
368 policy.setHorizontalStretch(1);
369 mgr.toolBar->setSizePolicy(policy);
371 policy = mgr.comboBibles->sizePolicy();
372 policy.setHorizontalStretch(10);
373 mgr.comboBibles->setSizePolicy(policy);
375 else
377 mgr.toolBar = 0;
378 fillBiblesList(&mgr);
381 layout->addWidget(mgr.comboBibles);
383 m_managerTabs->addTab(tabWidget, name);
384 m_managers.push_back(mgr);
386 // Ensure widgets are apropriately modified
387 connect(m_comboBook, SIGNAL(currentIndexChanged(int)),
388 this, SLOT(slotBookChanged()));
389 connect(m_comboChapter, SIGNAL(currentIndexChanged(int)),
390 this, SLOT(slotVerseRange()));
391 connect(m_editRange, SIGNAL(textChanged(const QString&)),
392 this, SLOT(slotVerseRange()));
394 KwApplication::self()->mainWindow()->addDockWidget(Qt::LeftDockWidgetArea, m_docker);
396 slotBibleChanged();
399 void KwBiblePlugin::_unload()
401 // Clean up the bible managers.
402 /// @todo IMPLEMENT!!!
403 delete m_docker;
407 * Private functions
410 /// Fill up the bibles list for a manager.
411 void KwBiblePlugin::fillBiblesList(BibleManager* mgr)
413 QStringList languages = mgr->manager->languages();
414 mgr->comboBibles->clear();
415 mgr->comboBibles->addItem(i18n("-- select a translation --"));
416 foreach (QString language, languages)
418 QStringList modules = mgr->manager->moduleNamesInLanguage(language);
419 if (!modules.isEmpty())
421 mgr->comboBibles->addItem(language, QVariant(modules.first()));
422 foreach (QString module, modules)
424 mgr->comboBibles->addItem(" " + module, QVariant(module));