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 KwBiblePlugin.cpp
22 * @brief Bibles plugin.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwBiblePlugin.h"
27 #include "KwApplication.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>
41 #include <KMessageBox>
43 #include <QMainWindow>
44 #include <QDockWidget>
45 #include <QHBoxLayout>
46 #include <QVBoxLayout>
54 * Constructors + destructor
57 /// Default constructor.
58 KwBiblePlugin::KwBiblePlugin()
61 i18n("The bible plugin allows for the navigation and display of "
62 "bible extracts from SWORD and BibleGateway.com."))
64 , m_insertIntoPlaylistAction(0)
73 KwBibleManagerSword::registerManager();
74 KwBibleManagerBibleGateway::registerManager();
78 KwBiblePlugin::~KwBiblePlugin()
80 // Ensure all GUI stuff is cleaned up
81 KwBiblePlugin::_unload();
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();
101 KwBibleModule
* mod
= 0;
104 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
105 mod
= mgr
.manager
->module(bible
);
110 // Is a book selected?
111 int bookIndex
= m_comboBook
->currentIndex();
112 int chapterIndex
= -1;
115 // Is a chapter selected?
116 chapterIndex
= m_comboChapter
->currentIndex();
120 KwBibleModule::Key relativeKey
= mod
->createKey(bookIndex
, chapterIndex
);
121 *key
= mod
->createKey(relativeKey
, m_editRange
->text(), &valid
);
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
151 if (mgr
->comboBibles
->count() == 0)
153 KMessageBox::information(m_docker
, i18n("No bibles found"));
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();
174 KwBibleModule
* module
= 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();
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)
199 m_comboBook
->setCurrentIndex(index
);
200 if (canPreserveBook
&& chapter
>= 0)
202 // If we can restore book, also restore chapter
203 m_comboChapter
->setCurrentIndex(chapter
);
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();
231 KwBibleModule
* module
= 0;
234 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
235 module
= mgr
.manager
->module(bible
);
239 // Is a book selected?
240 int index
= m_comboBook
->currentIndex();
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
));
255 /// Fired when the bible text needs to be retrieved.
256 void KwBiblePlugin::slotVerseRange()
258 KwBibleManager
* manager
;
259 KwBibleModule
* module
;
260 KwBibleModule::Key key
;
262 bool success
= resolvePassage(&manager
, &module
, &key
, &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
;
280 changedPal
.setColor( QPalette::Normal
, QPalette::Base
, QColor(255, 127, 127) );
282 m_editRange
->setPalette(changedPal
);
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
);
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
);
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
);
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();
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
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
);
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
);
450 void KwBiblePlugin::_unload()
452 // Clean up the bible managers.
453 /// @todo IMPLEMENT!!!
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
));