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 "KwBibleModule.h"
33 #include "KwBiblePlaylistItem.h"
35 #include <KwPlaylistModel.h>
39 #include <KMessageBox>
40 #include <KGenericFactory>
41 #include <KServiceTypeTrader>
43 #include <QMainWindow>
44 #include <QDockWidget>
45 #include <QHBoxLayout>
46 #include <QVBoxLayout>
53 K_EXPORT_COMPONENT_FACTORY( kworship_bible
, KGenericFactory
<KwBiblePlugin
>("kworship_bible") )
56 * Constructors + destructor
59 /// Default constructor.
60 KwBiblePlugin::KwBiblePlugin(QObject
* parent
, const QStringList
& params
)
61 : KwPlugin(parent
, "bible",
63 i18n("The bible plugin allows for the navigation and display of "
64 "bible extracts from various sources."))
66 , m_insertIntoPlaylistAction(0)
76 setXMLFile("bible/kworship_bibleui.rc");
80 KwBiblePlugin::~KwBiblePlugin()
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()-1;
117 if (chapterIndex
< 0)
124 KwBibleModule::Key relativeKey
= mod
->createKey(bookIndex
, chapterIndex
);
125 *key
= mod
->createKey(relativeKey
, m_editRange
->text(), &valid
);
145 /// Fired when the connect to bible button is pressed.
146 void KwBiblePlugin::slotConnect()
148 // Get the current bible manager
149 int tab
= m_managerTabs
->currentIndex();
150 Q_ASSERT(tab
>= 0 && tab
< m_managers
.size());
151 BibleManager
* mgr
= &m_managers
[tab
];
153 // This will force the connection
157 /// Fired when the bible is changed.
158 void KwBiblePlugin::slotBibleChanged()
160 // Get the current bible manager
161 int tab
= m_managerTabs
->currentIndex();
162 if (tab
>= 0 && tab
< m_managers
.size())
164 BibleManager
& mgr
= m_managers
[tab
];
165 bool enabled
= mgr
.comboBibles
->isEnabled();
167 // Is a bible selected?
168 int bibleInd
= mgr
.comboBibles
->currentIndex();
170 KwBibleModule
* module
= 0;
173 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
174 module
= mgr
.manager
->module(bible
);
177 // Update the list of books
178 QString book
= m_comboBook
->currentText();
179 int chapter
= m_comboChapter
->currentIndex()-1;
180 m_comboBook
->clear();
183 QStringList bookNames
= module
->books();
184 for (int i
= 0; i
< bookNames
.size(); ++i
)
186 const QString
& bookName
= bookNames
[i
];
187 m_comboBook
->addItem(bookName
, QVariant(i
));
189 int index
= m_comboBook
->findText(book
);
190 bool canPreserveBook
= (index
>= 0);
191 if (!canPreserveBook
&& bookNames
.size() > 0)
195 m_comboBook
->setCurrentIndex(index
);
196 if (canPreserveBook
&& chapter
>= 0)
198 // If we can restore book, also restore chapter
199 m_comboChapter
->setCurrentIndex(chapter
+1);
207 m_comboBook
->setEnabled(enabled
);
208 m_comboChapter
->setEnabled(enabled
);
209 m_editRange
->setEnabled(enabled
);
213 /// Fired when the bible book is changed.
214 void KwBiblePlugin::slotBookChanged()
216 m_comboChapter
->clear();
217 m_comboChapter
->addItem(QString(), QVariant(-1));
219 // Get the current bible manager
220 int tab
= m_managerTabs
->currentIndex();
221 if (tab
>= 0 && tab
< m_managers
.size())
223 BibleManager
& mgr
= m_managers
[tab
];
225 // Is a bible selected?
226 int bibleInd
= mgr
.comboBibles
->currentIndex();
228 KwBibleModule
* module
= 0;
231 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
232 module
= mgr
.manager
->module(bible
);
236 // Is a book selected?
237 int index
= m_comboBook
->currentIndex();
240 int bookIndex
= m_comboBook
->itemData(index
).toInt();
241 int numChapters
= module
->numChapters(bookIndex
);
242 for (int i
= 0; i
< numChapters
; ++i
)
244 m_comboChapter
->addItem(QString("%1").arg(i
+1), QVariant(i
));
252 /// Fired when the bible text needs to be retrieved.
253 void KwBiblePlugin::slotVerseRange()
255 KwBibleManager
* manager
;
256 KwBibleModule
* module
;
257 KwBibleModule::Key key
;
259 bool success
= resolvePassage(&manager
, &module
, &key
, &usedSearch
);
262 m_comboBook
->setCurrentIndex(key
.start
.book
);
263 m_comboChapter
->setCurrentIndex(key
.start
.chapter
+1);
265 KwBiblePassage passage
;
266 module
->fillPassage(key
, &passage
);
267 m_textPassage
->document()->setHtml(passage
.renderedText());
269 m_insertIntoPlaylistAction
->setEnabled(true);
270 m_showNowAction
->setEnabled(true);
272 // Update color of search box
273 static QPalette p
= m_editRange
->palette();
274 QPalette changedPal
= p
;
277 changedPal
.setColor( QPalette::Normal
, QPalette::Base
, QColor(255, 127, 127) );
279 m_editRange
->setPalette(changedPal
);
283 m_textPassage
->document()->setPlainText(QString());
284 m_insertIntoPlaylistAction
->setEnabled(false);
285 m_showNowAction
->setEnabled(false);
288 /// Fired by the insert into playlist action.
289 void KwBiblePlugin::slotInsertIntoPlaylist()
291 KwBibleManager
* manager
;
292 KwBibleModule
* module
;
293 KwBibleModule::Key key
;
294 bool success
= resolvePassage(&manager
, &module
, &key
);
298 KwBiblePlaylistItem
* item
= new KwBiblePlaylistItem();
299 module
->fillPassage(key
, &item
->passage());
300 KwPlaylistModel
* model
= KwApplication::self()->mainWindow()->playlistModel();
301 model
->addItem(QModelIndex(), item
);
305 /// Fired by the show now action.
306 void KwBiblePlugin::slotShowNow()
311 * Loading and unloading virtual interface
315 void KwBiblePlugin::_load()
317 // Construct the bible managers and put into a list.
318 // Have the local bible managers first in the list.
319 KService::List offers
= KServiceTypeTrader::self()->query("KWorship/Bible");
320 QList
<KwBibleManager
*> managers
;
321 QList
<KwBibleManager
*> remoteManagers
;
322 foreach (KService::Ptr service
, offers
)
324 qDebug() << " Found KWorship bible backend: " << service
->desktopEntryName();
326 KwBibleManager
* backend
= service
->createInstance
<KwBibleManager
>(this, QVariantList(), &err
);
329 qDebug() << " Loaded successfully";
330 if (backend
->isRemote())
332 remoteManagers
+= backend
;
341 qDebug() << " Could not be loaded: " << err
;
344 managers
+= remoteManagers
;
347 m_docker
= new QDockWidget(i18n("Bible"));
348 m_docker
->setObjectName("dockBible");
349 QWidget
* mainDockWidget
= new QWidget(/*m_docker*/);
350 QVBoxLayout
* dockLayout
= new QVBoxLayout(mainDockWidget
);
351 m_docker
->setWidget(mainDockWidget
);
353 // The tab bar of bible managers
354 m_managerTabs
= new QTabWidget(m_docker
);
355 m_managerTabs
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Preferred
);
356 connect(m_managerTabs
, SIGNAL(currentChanged(int)),
357 this, SLOT(slotBibleChanged()));
358 dockLayout
->addWidget(m_managerTabs
);
360 // Bible navigation combo boxes
361 QWidget
* bibleNavigationWidget
= new QWidget(mainDockWidget
);
362 QHBoxLayout
* bibleNavigationLayout
= new QHBoxLayout(bibleNavigationWidget
);
363 dockLayout
->addWidget(bibleNavigationWidget
);
365 m_comboBook
= new QComboBox(bibleNavigationWidget
);
366 m_comboChapter
= new QComboBox(bibleNavigationWidget
);
367 bibleNavigationLayout
->addWidget(m_comboBook
);
368 bibleNavigationLayout
->addWidget(m_comboChapter
);
370 // Verse range text box and label
371 QWidget
* verseRangeWidget
= new QWidget(mainDockWidget
);
372 QHBoxLayout
* verseRangeLayout
= new QHBoxLayout(verseRangeWidget
);
373 dockLayout
->addWidget(verseRangeWidget
);
375 QLabel
* labelRange
= new QLabel(i18n("&Verses"), verseRangeWidget
);
376 m_editRange
= new QLineEdit(verseRangeWidget
);
377 labelRange
->setBuddy(m_editRange
);
378 verseRangeLayout
->addWidget(labelRange
);
379 verseRangeLayout
->addWidget(m_editRange
);
381 m_textPassage
= new QTextEdit(mainDockWidget
);
382 m_textPassage
->setTextInteractionFlags(Qt::TextSelectableByMouse
| Qt::TextSelectableByKeyboard
);
383 dockLayout
->addWidget(m_textPassage
);
386 QToolBar
* bibleToolBar
= new QToolBar("bibleToolBar");
387 bibleToolBar
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
388 dockLayout
->addWidget(bibleToolBar
);
390 m_insertIntoPlaylistAction
= new KAction(KIcon("player_playlist"), i18n("Insert Into Playlist"), bibleToolBar
);
391 m_insertIntoPlaylistAction
->setEnabled(false);
392 connect(m_insertIntoPlaylistAction
, SIGNAL(triggered(bool)),
393 this, SLOT(slotInsertIntoPlaylist()));
394 bibleToolBar
->addAction(m_insertIntoPlaylistAction
);
396 m_showNowAction
= new KAction(KIcon("player_playlist"), i18n("Show Now"), bibleToolBar
);
397 m_showNowAction
->setEnabled(false);
398 connect(m_showNowAction
, SIGNAL(triggered(bool)),
399 this, SLOT(slotShowNow()));
400 bibleToolBar
->addAction(m_showNowAction
);
402 // Fill out tabs and manager data
403 foreach (KwBibleManager
* manager
, managers
)
405 QString name
= manager
->name();
407 mgr
.manager
= manager
;
409 QWidget
* tabWidget
= new QWidget();
410 QHBoxLayout
* layout
= new QHBoxLayout(tabWidget
);
412 mgr
.comboBibles
= new QComboBox();
413 connect(mgr
.comboBibles
, SIGNAL(currentIndexChanged(int)),
414 this, SLOT(slotBibleChanged()));
416 // Only fill the module list if the manager is local
417 // Otherwise we should wait until the user requests it
418 if (manager
->isRemote())
420 mgr
.comboBibles
->setEnabled(false);
422 mgr
.toolBar
= new QToolBar();
423 KAction
* connectToBible
= new KAction(KIcon("network-connect"), i18n("Connect to %1", name
), mgr
.toolBar
);
424 connect(connectToBible
, SIGNAL(triggered(bool)),
425 this, SLOT(slotConnect()));
426 mgr
.toolBar
->addAction(connectToBible
);
427 layout
->addWidget(mgr
.toolBar
);
429 // Toolbar should be as small as possible
432 policy
= mgr
.toolBar
->sizePolicy();
433 policy
.setHorizontalStretch(1);
434 mgr
.toolBar
->setSizePolicy(policy
);
436 policy
= mgr
.comboBibles
->sizePolicy();
437 policy
.setHorizontalStretch(10);
438 mgr
.comboBibles
->setSizePolicy(policy
);
443 fillBiblesList(&mgr
);
446 layout
->addWidget(mgr
.comboBibles
);
448 m_managerTabs
->addTab(tabWidget
, name
);
449 m_managers
.push_back(mgr
);
451 // Ensure widgets are apropriately modified
452 connect(m_comboBook
, SIGNAL(currentIndexChanged(int)),
453 this, SLOT(slotBookChanged()));
454 connect(m_comboChapter
, SIGNAL(currentIndexChanged(int)),
455 this, SLOT(slotVerseRange()));
456 connect(m_editRange
, SIGNAL(textChanged(const QString
&)),
457 this, SLOT(slotVerseRange()));
459 KwApplication::self()->mainWindow()->addDockWidget(Qt::LeftDockWidgetArea
, m_docker
);
464 void KwBiblePlugin::_unload()
466 // Clean up the bible managers.
467 /// @todo IMPLEMENT!!!
468 for (int i
= 0; i
< m_managers
.size(); ++i
)
470 BibleManager
& mgr
= m_managers
[i
];
481 /// Fill up the bibles list for a manager.
482 void KwBiblePlugin::fillBiblesList(BibleManager
* mgr
)
485 QStringList languages
= mgr
->manager
->languages(&ok
);
486 mgr
->comboBibles
->setEnabled(false);
487 mgr
->comboBibles
->clear();
488 mgr
->comboBibles
->addItem(i18n("-- select a translation --"));
489 foreach (QString language
, languages
)
491 QStringList modules
= mgr
->manager
->moduleNamesInLanguage(language
);
492 if (!modules
.isEmpty())
494 mgr
->comboBibles
->addItem(language
, QVariant(modules
.first()));
495 foreach (QString module
, modules
)
497 mgr
->comboBibles
->addItem(" " + module
, QVariant(module
));
501 // re-enable or clear
502 if (ok
&& mgr
->comboBibles
->count() > 1) {
503 mgr
->comboBibles
->setEnabled(true);
506 mgr
->comboBibles
->clear();