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>
42 #include <KGenericFactory>
44 #include <QMainWindow>
45 #include <QDockWidget>
46 #include <QHBoxLayout>
47 #include <QVBoxLayout>
54 K_EXPORT_COMPONENT_FACTORY( kworship_bible
, KGenericFactory
<KwBiblePlugin
>("kworship_bible") )
57 * Constructors + destructor
60 /// Default constructor.
61 KwBiblePlugin::KwBiblePlugin(const QObject
* parent
, const QStringList
& params
)
64 i18n("The bible plugin allows for the navigation and display of "
65 "bible extracts from SWORD and BibleGateway.com."))
67 , m_insertIntoPlaylistAction(0)
76 KwBibleManagerSword::registerManager();
77 KwBibleManagerBibleGateway::registerManager();
81 KwBiblePlugin::~KwBiblePlugin()
83 // Ensure all GUI stuff is cleaned up
84 KwBiblePlugin::_unload();
91 /// Get the current bible passage information.
92 bool KwBiblePlugin::resolvePassage(KwBibleManager
** manager
, KwBibleModule
** module
, KwBibleModule::Key
* key
, bool* usedSearch
) const
94 // Get the current bible manager
95 int tab
= m_managerTabs
->currentIndex();
96 if (tab
>= 0 && tab
< m_managers
.size())
98 const BibleManager
& mgr
= m_managers
[tab
];
99 *manager
= mgr
.manager
;
101 // Is a bible selected?
102 int bibleInd
= mgr
.comboBibles
->currentIndex();
104 KwBibleModule
* mod
= 0;
107 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
108 mod
= mgr
.manager
->module(bible
);
113 // Is a book selected?
114 int bookIndex
= m_comboBook
->currentIndex();
115 int chapterIndex
= -1;
118 // Is a chapter selected?
119 chapterIndex
= m_comboChapter
->currentIndex();
123 KwBibleModule::Key relativeKey
= mod
->createKey(bookIndex
, chapterIndex
);
124 *key
= mod
->createKey(relativeKey
, m_editRange
->text(), &valid
);
144 /// Fired when the connect to bible button is pressed.
145 void KwBiblePlugin::slotConnect()
147 // Get the current bible manager
148 int tab
= m_managerTabs
->currentIndex();
149 Q_ASSERT(tab
>= 0 && tab
< m_managers
.size());
150 BibleManager
* mgr
= &m_managers
[tab
];
152 // This will force the connection
154 if (mgr
->comboBibles
->count() == 0)
156 KMessageBox::information(m_docker
, i18n("No bibles found"));
160 mgr
->comboBibles
->setEnabled(true);
164 /// Fired when the bible is changed.
165 void KwBiblePlugin::slotBibleChanged()
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
];
172 bool enabled
= mgr
.comboBibles
->isEnabled();
174 // Is a bible selected?
175 int bibleInd
= mgr
.comboBibles
->currentIndex();
177 KwBibleModule
* module
= 0;
180 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
181 module
= mgr
.manager
->module(bible
);
184 // Update the list of books
185 QString book
= m_comboBook
->currentText();
186 int chapter
= m_comboChapter
->currentIndex();
187 m_comboBook
->clear();
190 QStringList bookNames
= module
->books();
191 for (int i
= 0; i
< bookNames
.size(); ++i
)
193 const QString
& bookName
= bookNames
[i
];
194 m_comboBook
->addItem(bookName
, QVariant(i
));
196 int index
= m_comboBook
->findText(book
);
197 bool canPreserveBook
= (index
>= 0);
198 if (!canPreserveBook
&& bookNames
.size() > 0)
202 m_comboBook
->setCurrentIndex(index
);
203 if (canPreserveBook
&& chapter
>= 0)
205 // If we can restore book, also restore chapter
206 m_comboChapter
->setCurrentIndex(chapter
);
214 m_comboBook
->setEnabled(enabled
);
215 m_comboChapter
->setEnabled(enabled
);
216 m_editRange
->setEnabled(enabled
);
220 /// Fired when the bible book is changed.
221 void KwBiblePlugin::slotBookChanged()
223 m_comboChapter
->clear();
225 // Get the current bible manager
226 int tab
= m_managerTabs
->currentIndex();
227 if (tab
>= 0 && tab
< m_managers
.size())
229 BibleManager
& mgr
= m_managers
[tab
];
231 // Is a bible selected?
232 int bibleInd
= mgr
.comboBibles
->currentIndex();
234 KwBibleModule
* module
= 0;
237 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
238 module
= mgr
.manager
->module(bible
);
242 // Is a book selected?
243 int index
= m_comboBook
->currentIndex();
246 int bookIndex
= m_comboBook
->itemData(index
).toInt();
247 int numChapters
= module
->numChapters(bookIndex
);
248 for (int i
= 0; i
< numChapters
; ++i
)
250 m_comboChapter
->addItem(QString("%1").arg(i
+1), QVariant(i
));
258 /// Fired when the bible text needs to be retrieved.
259 void KwBiblePlugin::slotVerseRange()
261 KwBibleManager
* manager
;
262 KwBibleModule
* module
;
263 KwBibleModule::Key key
;
265 bool success
= resolvePassage(&manager
, &module
, &key
, &usedSearch
);
268 m_comboBook
->setCurrentIndex(key
.start
.book
);
269 m_comboChapter
->setCurrentIndex(key
.start
.chapter
);
271 KwBiblePassage passage
;
272 module
->fillPassage(key
, &passage
);
273 m_textPassage
->document()->setHtml(passage
.renderedText());
275 m_insertIntoPlaylistAction
->setEnabled(true);
276 m_showNowAction
->setEnabled(true);
278 // Update color of search box
279 static QPalette p
= m_editRange
->palette();
280 QPalette changedPal
= p
;
283 changedPal
.setColor( QPalette::Normal
, QPalette::Base
, QColor(255, 127, 127) );
285 m_editRange
->setPalette(changedPal
);
289 m_textPassage
->document()->setPlainText(QString());
290 m_insertIntoPlaylistAction
->setEnabled(false);
291 m_showNowAction
->setEnabled(false);
294 /// Fired by the insert into playlist action.
295 void KwBiblePlugin::slotInsertIntoPlaylist()
297 KwBibleManager
* manager
;
298 KwBibleModule
* module
;
299 KwBibleModule::Key key
;
300 bool success
= resolvePassage(&manager
, &module
, &key
);
304 KwBiblePlaylistItem
* item
= new KwBiblePlaylistItem(module
, key
);
305 KwPlaylistModel
* model
= KwApplication::self()->mainWindow()->playlistModel();
306 model
->addItem(QModelIndex(), item
);
310 /// Fired by the show now action.
311 void KwBiblePlugin::slotShowNow()
316 * Loading and unloading virtual interface
319 void KwBiblePlugin::_load()
321 // Construct the bible managers.
322 QStringList managerNames
;
323 managerNames
<< "SWORD";
324 managerNames
<< "BibleGateway.com";
325 QList
<KwBibleManager
*> managers
;
326 foreach (QString name
, managerNames
)
328 KwBibleManager
* manager
= KwBibleManagerSword::singleton(name
);
336 m_docker
= new QDockWidget(i18n("Bible"));
337 m_docker
->setObjectName("dockBible");
338 QWidget
* mainDockWidget
= new QWidget(/*m_docker*/);
339 QVBoxLayout
* dockLayout
= new QVBoxLayout(mainDockWidget
);
340 m_docker
->setWidget(mainDockWidget
);
342 // The tab bar of bible managers
343 m_managerTabs
= new QTabWidget(m_docker
);
344 m_managerTabs
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Preferred
);
345 connect(m_managerTabs
, SIGNAL(currentChanged(int)),
346 this, SLOT(slotBibleChanged()));
347 dockLayout
->addWidget(m_managerTabs
);
349 // Bible navigation combo boxes
350 QWidget
* bibleNavigationWidget
= new QWidget(mainDockWidget
);
351 QHBoxLayout
* bibleNavigationLayout
= new QHBoxLayout(bibleNavigationWidget
);
352 dockLayout
->addWidget(bibleNavigationWidget
);
354 m_comboBook
= new QComboBox(bibleNavigationWidget
);
355 m_comboChapter
= new QComboBox(bibleNavigationWidget
);
356 bibleNavigationLayout
->addWidget(m_comboBook
);
357 bibleNavigationLayout
->addWidget(m_comboChapter
);
359 // Verse range text box and label
360 QWidget
* verseRangeWidget
= new QWidget(mainDockWidget
);
361 QHBoxLayout
* verseRangeLayout
= new QHBoxLayout(verseRangeWidget
);
362 dockLayout
->addWidget(verseRangeWidget
);
364 QLabel
* labelRange
= new QLabel(i18n("&Verses"), verseRangeWidget
);
365 m_editRange
= new QLineEdit(verseRangeWidget
);
366 labelRange
->setBuddy(m_editRange
);
367 verseRangeLayout
->addWidget(labelRange
);
368 verseRangeLayout
->addWidget(m_editRange
);
370 m_textPassage
= new QTextEdit(mainDockWidget
);
371 m_textPassage
->setTextInteractionFlags(Qt::TextSelectableByMouse
| Qt::TextSelectableByKeyboard
);
372 dockLayout
->addWidget(m_textPassage
);
375 QToolBar
* bibleToolBar
= new QToolBar("bibleToolBar");
376 bibleToolBar
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
377 dockLayout
->addWidget(bibleToolBar
);
379 m_insertIntoPlaylistAction
= new KAction(KIcon("player_playlist"), i18n("Insert Into Playlist"), bibleToolBar
);
380 m_insertIntoPlaylistAction
->setEnabled(false);
381 connect(m_insertIntoPlaylistAction
, SIGNAL(triggered(bool)),
382 this, SLOT(slotInsertIntoPlaylist()));
383 bibleToolBar
->addAction(m_insertIntoPlaylistAction
);
385 m_showNowAction
= new KAction(KIcon("player_playlist"), i18n("Show Now"), bibleToolBar
);
386 m_showNowAction
->setEnabled(false);
387 connect(m_showNowAction
, SIGNAL(triggered(bool)),
388 this, SLOT(slotShowNow()));
389 bibleToolBar
->addAction(m_showNowAction
);
391 // Fill out tabs and manager data
392 foreach (KwBibleManager
* manager
, managers
)
394 QString name
= manager
->name();
396 mgr
.manager
= manager
;
398 QWidget
* tabWidget
= new QWidget();
399 QHBoxLayout
* layout
= new QHBoxLayout(tabWidget
);
401 mgr
.comboBibles
= new QComboBox();
402 connect(mgr
.comboBibles
, SIGNAL(currentIndexChanged(int)),
403 this, SLOT(slotBibleChanged()));
405 // Only fill the module list if the manager is local
406 // Otherwise we should wait until the user requests it
407 if (manager
->isRemote())
409 mgr
.comboBibles
->setEnabled(false);
411 mgr
.toolBar
= new QToolBar();
412 KAction
* connectToBible
= new KAction(KIcon("network-connect"), i18n("Connect to %1", name
), mgr
.toolBar
);
413 connect(connectToBible
, SIGNAL(triggered(bool)),
414 this, SLOT(slotConnect()));
415 mgr
.toolBar
->addAction(connectToBible
);
416 layout
->addWidget(mgr
.toolBar
);
418 // Toolbar should be as small as possible
421 policy
= mgr
.toolBar
->sizePolicy();
422 policy
.setHorizontalStretch(1);
423 mgr
.toolBar
->setSizePolicy(policy
);
425 policy
= mgr
.comboBibles
->sizePolicy();
426 policy
.setHorizontalStretch(10);
427 mgr
.comboBibles
->setSizePolicy(policy
);
432 fillBiblesList(&mgr
);
435 layout
->addWidget(mgr
.comboBibles
);
437 m_managerTabs
->addTab(tabWidget
, name
);
438 m_managers
.push_back(mgr
);
440 // Ensure widgets are apropriately modified
441 connect(m_comboBook
, SIGNAL(currentIndexChanged(int)),
442 this, SLOT(slotBookChanged()));
443 connect(m_comboChapter
, SIGNAL(currentIndexChanged(int)),
444 this, SLOT(slotVerseRange()));
445 connect(m_editRange
, SIGNAL(textChanged(const QString
&)),
446 this, SLOT(slotVerseRange()));
448 KwApplication::self()->mainWindow()->addDockWidget(Qt::LeftDockWidgetArea
, m_docker
);
453 void KwBiblePlugin::_unload()
455 // Clean up the bible managers.
456 /// @todo IMPLEMENT!!!
464 /// Fill up the bibles list for a manager.
465 void KwBiblePlugin::fillBiblesList(BibleManager
* mgr
)
467 QStringList languages
= mgr
->manager
->languages();
468 mgr
->comboBibles
->clear();
469 mgr
->comboBibles
->addItem(i18n("-- select a translation --"));
470 foreach (QString language
, languages
)
472 QStringList modules
= mgr
->manager
->moduleNamesInLanguage(language
);
473 if (!modules
.isEmpty())
475 mgr
->comboBibles
->addItem(language
, QVariant(modules
.first()));
476 foreach (QString module
, modules
)
478 mgr
->comboBibles
->addItem(" " + module
, QVariant(module
));