Fix bible gateway encoding to read always as utf-8
[kworship.git] / kworship / kworship.cpp
bloba88ba1673b8f306fc7126db6a761855b116e7579
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 #include "kworship.h"
21 #include "kworshipview.h"
22 #include "settings.h"
23 #include "prefsDisplay.h"
24 #include "prefsSongDB.h"
25 #include "KwDatabaseSetup.h"
26 #include "KwDocument.h"
28 #include "KwPlaylistNode.h"
29 #include "KwPlaylistList.h"
30 #include "KwPlaylistNote.h"
31 #include "KwPlaylistText.h"
32 #include "KwPlaylistImage.h"
33 #include "KwPlaylistVideo.h"
34 #include "KwPlaylistModel.h"
36 #include "KwCssStyleSheet.h"
37 #include "KwCssStyleRule.h"
39 #include "KwDisplayManager.h"
40 #include "KwLocalDisplay.h"
41 #include "KwLocalDisplayPreview.h"
43 #include "KwMediaManager.h"
44 #include "KwMediaControlWidget.h"
46 #include <KwBibleManager.h>
47 #include <KwBibleManagerSword.h>
48 #include <KwBibleManagerBibleGateway.h>
49 #include <KwBibleModule.h>
51 #include "KwSongdb.h"
52 #include "KwSongdbModel.h"
53 #include "KwSongdbFilterNode.h"
54 #include "KwSongdbTree.h"
55 #include "KwSongdbSong.h"
56 #include "KwSongdbSongEditDialog.h"
57 #include "KwSongdbSongBooksEditWidget.h"
59 #include "UpManager.h"
60 #include "UpPresentationsModel.h"
61 #include "UpPresentation.h"
62 #include "UpPresentationNode.h"
63 #include "UpSlide.h"
64 #include "UpKpr1Backend.h"
65 #include "UpKpr2Backend.h"
66 #include "UpOoBackend.h"
68 #include <kconfigdialog.h>
69 #include <kstatusbar.h>
70 #include <kaction.h>
71 #include <kactionmenu.h>
72 #include <kmenu.h>
73 #include <ktoggleaction.h>
74 #include <kactioncollection.h>
75 #include <kstandardaction.h>
76 #include <KDE/KLocale>
77 #include <KFileDialog>
78 #include <KMessageBox>
80 #include <phonon/audiooutput.h>
82 #include <QtGui/QDropEvent>
83 #include <QtGui/QPainter>
84 #include <QColor>
85 #include <QDesktopWidget>
86 #include <QToolBar>
87 #include <QToolButton>
88 #include <QComboBox>
89 #include <QSqlDatabase>
90 #include <QHeaderView>
91 #include <QTextEdit>
93 kworship::kworship()
94 : KXmlGuiWindow()
95 , m_view(new kworshipView(this))
96 , m_displayManager(0)
97 , m_document(0)
98 , m_presentationManager(new UpManager(this))
99 , m_currentPresentation(0)
100 , m_printer(0)
102 m_playlistModel = new KwPlaylistModel;
103 setDocument();
105 // set up presentation backends
106 m_presentationManager->registerBackend<UpOoBackend>();
107 m_presentationManager->registerBackend<UpKpr2Backend>();
108 m_presentationManager->registerBackend<UpKpr1Backend>();
110 m_mainDisplay = 0;
111 m_previewDisplay = 0;
113 // accept dnd
114 setAcceptDrops(true);
116 // tell the KXmlGuiWindow that this is indeed the main widget
117 setCentralWidget(m_view);
119 // then, setup our actions
120 setupActions();
122 // add a status bar
123 statusBar()->show();
125 // a call to KXmlGuiWindow::setupGUI() populates the GUI
126 // with actions, using KXMLGUI.
127 // It also applies the saved mainwindow settings, if any, and ask the
128 // mainwindow to automatically save settings if changed: window size,
129 // toolbar position, icon size, etc.
130 setupGUI();
132 // Setup the dockers
133 addDockWidget(Qt::LeftDockWidgetArea, m_view->dockPresentation);
134 tabifyDockWidget(m_view->dockPresentation, m_view->dockBible);
135 tabifyDockWidget(m_view->dockPresentation, m_view->dockSongs);
136 addDockWidget(Qt::RightDockWidgetArea, m_view->dockPreview);
137 addDockWidget(Qt::RightDockWidgetArea, m_view->dockLyrics);
138 addDockWidget(Qt::BottomDockWidgetArea, m_view->dockThemes);
139 addDockWidget(Qt::BottomDockWidgetArea, m_view->dockNowPlaying);
141 // Setup some stuff in the tree
142 #if 0
143 #define TREE_ITEM(name, string, parent) QTreeWidgetItem* name = new QTreeWidgetItem(parent); name->setText(0, tr(string));
145 TREE_ITEM(song1, "Our God is a great big God", m_view->treeWidget);
146 TREE_ITEM(song1_style, "(style)", song1);
147 TREE_ITEM(song1_style_1, "Mode", song1_style);
148 TREE_ITEM(song1_v1, "Our God is a great big God,\nOur God is a great big God,\nOur God is a great big God,\nAnd He holds us in his hands.", song1);
149 TREE_ITEM(song1_v2, "He's higher than a skyscraper\nAnd he's deeper than a submarine.", song1);
150 TREE_ITEM(song1_v3, "He's wider than the universe\nAnd beyond my wildest dreams.", song1);
152 #undef TREE_ITEM
153 #endif
155 // Setup song db
157 KwDatabaseSetup dbSetup;
158 bool databaseOk = dbSetup.initialiseFromConfig();
159 if (databaseOk)
161 new KwSongdb(dbSetup.database());
164 // Playlist
165 m_document->playlist()->addClass("beachy");
167 KwCssStyleSheet* styleRules = new KwCssStyleSheet;
169 KwCssStyleRule beachyTheme;
170 beachyTheme.setCriteriaClasses(QSet<QString>() << "beachy");
171 beachyTheme.setStyle<QBrush>("background.brush", Qt::black);
172 beachyTheme.setStyle<QPixmap>("background.image.pixmap", QPixmap("/home/james/media/images/projector/misc/love-god-light.jpg"));
173 styleRules->addRule(beachyTheme);
175 m_document->playlist()->addStyleSheet(styleRules);
177 m_view->treePlaylist->setModel(m_playlistModel);
178 m_view->treePlaylist->setExpandsOnDoubleClick(false);
179 m_view->treePlaylist->setAcceptDrops(true);
181 connect(m_view->treePlaylist, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(playlist_doubleClicked(QModelIndex)));
183 m_mediaManager = new KwMediaManager();
184 m_mediaManager->linkAudio(new Phonon::AudioOutput(Phonon::MusicCategory));
185 m_displayManager = new KwDisplayManager(&m_displayController, m_mediaManager);
187 m_previewDisplay = new KwLocalDisplayPreview;
188 m_view->layoutPreview->addWidget(m_previewDisplay);
189 m_displayController.attachChild(m_previewDisplay);
191 KwMediaControlWidget* mediaWidget = new KwMediaControlWidget(m_mediaManager, m_view->dockNowPlaying);
192 m_view->layoutNowPlaying->addWidget(mediaWidget);
194 // Small toolbar for group by action
195 QToolBar* songTextToolBar = new QToolBar("Songs");
196 songTextToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
197 songTextToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
198 m_view->layoutSongsToolbar->layout()->addWidget(songTextToolBar);
200 songTextToolBar->addAction(m_groupSongsByAction);
202 // Rest of the toolbar
203 QToolBar* songToolBar = new QToolBar("Songs");
204 songToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
205 m_view->layoutSongsToolbar->layout()->addWidget(songToolBar);
207 songToolBar->addAction(m_addSongAction);
208 songToolBar->addAction(m_editSongAction);
209 songToolBar->addAction(m_editSongBooksAction);
210 KAction* insertIntoPlaylistAction = new KAction(KIcon("player_playlist"), i18n("Insert Into Playlist"), songToolBar);
211 songToolBar->addAction(insertIntoPlaylistAction);
213 KMenu* groupByMenu = new KMenu(songToolBar);
214 m_groupSongsByAction->setMenu(groupByMenu);
216 if (databaseOk)
218 m_songDbTree = new KwSongdbTree(m_view);
219 m_view->layoutSongsTree->addWidget(m_songDbTree);
220 groupByMenu->addActions(m_songDbTree->groupByActions()->actions());
225 * Presentation
228 // Drop down list of presentations
229 QComboBox* selectPresCombo = m_view->comboPresentations;
230 m_selectPresTree = new QTreeView(this);
231 m_selectPresTree->header()->hide();
232 selectPresCombo->setModel(m_presentationManager->presentationsModel());
233 selectPresCombo->setView(m_selectPresTree);
234 presentationComboReset();
235 connect(m_presentationManager->presentationsModel(), SIGNAL(modelReset()), this, SLOT(presentationComboReset()));
236 connect(selectPresCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(presentationSelected(int)));
238 // Custom slideshow selector
239 m_view->slideshows->setVisible(false);
240 connect(m_view->comboSlideshows, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(changeSlideshowCombo(QString)));
242 QToolBar* customSlideshowsToolBar = new QToolBar(i18n("Custom Slideshows"));
243 customSlideshowsToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
244 m_view->slideshows->layout()->addWidget(customSlideshowsToolBar);
245 // Add slideshow to playlist
246 KActionMenu* addSlideshowToPlaylistAction = new KActionMenu(KIcon("list-add"), i18n("Add Slideshow to Playlist"), customSlideshowsToolBar);
247 addSlideshowToPlaylistAction->setDelayed(false);
248 customSlideshowsToolBar->addAction(addSlideshowToPlaylistAction);
250 KAction* asLinkAction = new KAction(KIcon("insert-link"), i18n("Add Link to Slideshow into Playlist"), customSlideshowsToolBar);
251 connect(asLinkAction, SIGNAL(triggered(bool)), this, SLOT(addSlideshowLinkToPlaylist()));
252 addSlideshowToPlaylistAction->addAction(asLinkAction);
255 KAction* asCopyAction = new KAction(KIcon("edit-copy"), i18n("Save Copy of Slideshow into Playlist"), customSlideshowsToolBar);
256 connect(asCopyAction, SIGNAL(triggered(bool)), this, SLOT(addSlideshowCopyToPlaylist()));
257 addSlideshowToPlaylistAction->addAction(asCopyAction);
260 // Presentations toolbar
261 QToolBar* presToolBar = new QToolBar("Presentations");
262 m_view->layoutPresentationsToolbar->layout()->addWidget(presToolBar);
264 KActionMenu* openPresAction = new KActionMenu(KIcon("document-open"), "Open Presentation", presToolBar);
265 openPresAction->setDelayed(true);
266 presToolBar->addAction(openPresAction);
268 KAction* refreshPresAction = new KAction(KIcon("view-refresh"), "Refresh Presentation List", presToolBar);
269 presToolBar->addAction(refreshPresAction);
271 KAction* closePresAction = new KAction(KIcon("fileclose"), "Close Presentation", presToolBar);
272 presToolBar->addAction(closePresAction);
274 KToggleAction* fullscreenPresAction = new KToggleAction(KIcon("view-fullscreen"), "Fullscreen Presentation Mode", presToolBar);
275 presToolBar->addAction(fullscreenPresAction);
277 // Slide list
278 connect(m_view->listSlides, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slide_doubleClicked(QModelIndex)));
280 // Slides toolbar
281 QToolBar* slidesToolBar = new QToolBar("Slides");
282 slidesToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
283 slidesToolBar->setIconSize(QSize(32,32));
284 m_view->layoutSlidesToolbar->layout()->addWidget(slidesToolBar);
286 m_slideshowPrevSlideAction = new KAction(KIcon("media-skip-backward"), i18n("Previous Slide"), slidesToolBar);
287 connect(m_slideshowPrevSlideAction, SIGNAL(triggered(bool)), this, SLOT(presentationPreviousSlide()));
288 slidesToolBar->addAction(m_slideshowPrevSlideAction);
290 m_slideshowPrevStepAction = new KAction(KIcon("media-seek-backward"), i18n("Previous Step"), slidesToolBar);
291 connect(m_slideshowPrevStepAction, SIGNAL(triggered(bool)), this, SLOT(presentationPreviousStep()));
292 slidesToolBar->addAction(m_slideshowPrevStepAction);
294 m_slideshowNextStepAction = new KAction(KIcon("media-seek-forward"), i18n("Next Step"), slidesToolBar);
295 connect(m_slideshowNextStepAction, SIGNAL(triggered(bool)), this, SLOT(presentationNextStep()));
296 slidesToolBar->addAction(m_slideshowNextStepAction);
298 m_slideshowNextSlideAction = new KAction(KIcon("media-skip-forward"), i18n("Next Slide"), slidesToolBar);
299 connect(m_slideshowNextSlideAction, SIGNAL(triggered(bool)), this, SLOT(presentationNextSlide()));
300 slidesToolBar->addAction(m_slideshowNextSlideAction);
302 m_slideshowAction = new KToggleAction(KIcon("view-presentation"), i18n("Start/Stop Slideshow"), slidesToolBar);
303 connect(m_slideshowAction, SIGNAL(toggled(bool)), this, SLOT(presentationToggled(bool)));
304 slidesToolBar->addAction(m_slideshowAction);
306 // Slide notes
307 m_slideNotes = new QTextEdit();
308 m_slideNotes->setReadOnly(true);
309 m_slideNotes->setWindowTitle(i18n("Slide Notes"));
310 m_slideNotes->show();
312 // Ensure the controls are as when slideshow is stopped
313 m_slideshowAction->setEnabled(false);
314 slideshowStopped();
317 * Display startup
320 // Show the display on startup?
321 if (Settings::displayShowStartup())
323 // If there's only one screen, don't bother showing display.
324 QDesktopWidget* desktop = qobject_cast<QApplication*>(QCoreApplication::instance())->desktop();
325 assert(0 != desktop);
326 if (desktop->numScreens() > 1)
328 toggleMainDisplay(true);
329 m_mainDisplayAction->setChecked(true);
333 // Fill list of bibles
334 QList<KwBibleManager*> managers;
335 managers.push_back(new KwBibleManagerSword);
336 managers.push_back(new KwBibleManagerBibleGateway);
338 m_bibleTabs = new QTabWidget();
339 m_bibleTabs->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
340 connect(m_bibleTabs, SIGNAL(currentChanged(int)),
341 this, SLOT(bibleChanged()));
342 m_view->layoutBibleTabs->addWidget(m_bibleTabs);
344 foreach (KwBibleManager* manager, managers)
346 QString name = manager->name();
347 BibleManager mgr;
348 mgr.manager = manager;
350 QWidget* tabWidget = new QWidget();
351 QHBoxLayout* layout = new QHBoxLayout(tabWidget);
353 mgr.comboBibles = new QComboBox();
354 connect(mgr.comboBibles, SIGNAL(currentIndexChanged(int)),
355 this, SLOT(bibleChanged()));
357 // Only fill the module list if the manager is local
358 // Otherwise we should wait until the user requests it
359 if (manager->isRemote())
361 mgr.comboBibles->setEnabled(false);
363 mgr.toolBar = new QToolBar();
364 KAction* connectToBible = new KAction(KIcon("network-connect"), i18n("Connect to %1", name), mgr.toolBar);
365 connect(connectToBible, SIGNAL(triggered(bool)),
366 this, SLOT(bibleConnect()));
367 mgr.toolBar->addAction(connectToBible);
368 layout->addWidget(mgr.toolBar);
370 // Toolbar should be as small as possible
371 QSizePolicy policy;
373 policy = mgr.toolBar->sizePolicy();
374 policy.setHorizontalStretch(1);
375 mgr.toolBar->setSizePolicy(policy);
377 policy = mgr.comboBibles->sizePolicy();
378 policy.setHorizontalStretch(10);
379 mgr.comboBibles->setSizePolicy(policy);
381 else
383 mgr.toolBar = 0;
384 fillBiblesList(&mgr);
387 layout->addWidget(mgr.comboBibles);
389 m_bibleTabs->addTab(tabWidget, name);
390 m_bibles.push_back(mgr);
392 // Ensure widgets are apropriately modified
393 connect(m_view->comboBibleBook, SIGNAL(currentIndexChanged(int)),
394 this, SLOT(bibleBookChanged()));
395 connect(m_view->comboBibleChapter, SIGNAL(currentIndexChanged(int)),
396 this, SLOT(bibleSearch()));
397 connect(m_view->searchBible, SIGNAL(textChanged(const QString&)),
398 this, SLOT(bibleSearch()));
399 bibleChanged();
402 kworship::~kworship()
404 delete KwSongdb::self();
405 delete m_slideNotes;
409 * Public interface
412 /// Load a specified playlist.
413 void kworship::loadPlaylist(const KUrl& url)
415 setDocument(url);
416 m_document->reload();
419 void kworship::setupActions()
421 // Application
422 KStandardAction::quit(qApp, SLOT(quit()), actionCollection());
423 KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
425 // File management
426 KStandardAction::openNew(this, SLOT(fileNew()), actionCollection());
427 KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
428 KStandardAction::save(this, SLOT(fileSave()), actionCollection());
429 KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
431 // Display
432 KStandardAction::fullScreen(this, SLOT(toggleFullscreen(bool)), this, actionCollection());
434 m_mainDisplayAction = new KToggleAction(KIcon("video-projector"), i18n("Show Main Display"), this);
435 actionCollection()->addAction( QLatin1String("show_main_display"), m_mainDisplayAction );
436 connect(m_mainDisplayAction, SIGNAL(triggered(bool)), this, SLOT(toggleMainDisplay(bool)));
438 KAction* clearDisplayAction = new KAction(KIcon("clear"), i18n("Clear display"), this);
439 actionCollection()->addAction( QLatin1String("display_clear"), clearDisplayAction);
440 connect(clearDisplayAction, SIGNAL(triggered()), this, SLOT(displayClear()));
442 // Song database
443 m_unlockSongDbAction = new KAction(KIcon("document-decrypt"), i18n("Unlock Song Database"), this);
444 actionCollection()->addAction( QLatin1String("unlock_song_database"), m_unlockSongDbAction);
445 connect(m_unlockSongDbAction, SIGNAL(triggered(bool)), this, SLOT(songdbUnlock()));
447 m_lockSongDbAction = new KAction(KIcon("document-encrypt"), i18n("Lock Song Database"), this);
448 m_lockSongDbAction->setVisible(false);
449 actionCollection()->addAction( QLatin1String("lock_song_database"), m_lockSongDbAction);
450 connect(m_lockSongDbAction, SIGNAL(triggered(bool)), this, SLOT(songdbLock()));
452 m_groupSongsByAction = new KActionMenu(KIcon("view-filter"), i18n("Group By"), this);
453 m_groupSongsByAction->setDelayed(false);
454 actionCollection()->addAction( QLatin1String("group_songs_by"), m_groupSongsByAction);
456 m_addSongAction = new KAction(KIcon("list-add"), i18n("Add Song"), this);
457 actionCollection()->addAction( QLatin1String("add_song"), m_addSongAction);
458 connect(m_addSongAction, SIGNAL(triggered(bool)), this, SLOT(songdbAdd()));
460 m_editSongAction = new KAction(KIcon("view-media-lyrics"), i18n("Edit Song"), this);
461 actionCollection()->addAction( QLatin1String("edit_song"), m_editSongAction);
462 connect(m_editSongAction, SIGNAL(triggered(bool)), this, SLOT(songdbEdit()));
464 m_editSongBooksAction = new KAction(KIcon("format-list-ordered"), i18n("Edit Song Books"), this);
465 actionCollection()->addAction( QLatin1String("edit_song_books"), m_editSongBooksAction);
466 connect(m_editSongBooksAction, SIGNAL(triggered(bool)), this, SLOT(songdbEditSongBooks()));
469 void kworship::settingsChanged()
471 // If the main display is on and screen has changed, move it now
472 if (0 != m_mainDisplay && getCorrectDisplayScreen() != getCurrentDisplayScreen())
474 toggleMainDisplay(false);
475 toggleMainDisplay(true);
476 m_mainDisplayAction->setChecked(true);
480 int kworship::getCorrectDisplayScreen()
482 QDesktopWidget* desktop = qobject_cast<QApplication*>(QCoreApplication::instance())->desktop();
483 assert(0 != desktop);
485 int screens = desktop->numScreens();
486 int displayScreen = -1;
487 if (Settings::displayScreenChoose())
489 displayScreen = Settings::displayScreen();
491 if (-1 == displayScreen)
493 int currentScreen;
494 if (m_view->isVisible())
496 currentScreen = desktop->screenNumber(m_view);
498 else
500 currentScreen = desktop->primaryScreen();
502 displayScreen = 0;
503 if (displayScreen == currentScreen && displayScreen < screens-1)
505 ++displayScreen;
509 return displayScreen;
512 int kworship::getCurrentDisplayScreen()
514 QDesktopWidget* desktop = qobject_cast<QApplication*>(QCoreApplication::instance())->desktop();
515 assert(0 != desktop);
517 int previousScreen = desktop->screenNumber(m_mainDisplay);
519 return previousScreen;
522 void kworship::toggleMainDisplay(bool checked)
524 if (checked)
526 // Ensure the display exists
527 if (0 == m_mainDisplay)
529 m_mainDisplay = new KwLocalDisplay;
530 m_mainDisplay->setPrimary(true);
531 m_mainDisplay->setWindowTitle("kworship display");
532 m_displayController.attachChild(m_mainDisplay);
533 connect(m_mainDisplay, SIGNAL(closed()), this, SLOT(mainDisplayClosed()));
536 QDesktopWidget* desktop = qobject_cast<QApplication*>(QCoreApplication::instance())->desktop();
537 assert(0 != desktop);
539 int screens = desktop->numScreens();
540 int displayScreen = getCorrectDisplayScreen();
542 if (displayScreen >= 0 && displayScreen < screens)
544 m_mainDisplay->move(desktop->screenGeometry(displayScreen).topLeft());
547 if (!m_slideshowAction->isChecked())
549 m_mainDisplay->showFullScreen();
552 else
554 if (0 != m_mainDisplay)
556 m_mainDisplay->close();
561 void kworship::mainDisplayClosed()
563 m_mainDisplay->deleteLater();
564 m_mainDisplay = 0;
565 m_mainDisplayAction->setChecked(false);
568 void kworship::displayClear()
570 m_displayManager->background.clear();
571 m_displayManager->text.clear();
574 void kworship::toggleFullscreen(bool checked)
576 if (checked)
578 showFullScreen();
580 else
582 showNormal();
586 bool kworship::askToSave()
588 if (m_document->isModified())
590 switch (KMessageBox::questionYesNoCancel(this,
591 i18n("The current playlist has been modified. "
592 "These modifications will be lost if you continue without saving. "
593 "Would you like to save now?"),
594 i18n("Playlist is modified")))
596 case KMessageBox::Yes:
598 fileSave();
599 // If the document is still modified, save must have been cancelled
600 if (m_document->isModified())
602 return false;
605 break;
606 case KMessageBox::No:
607 break;
608 case KMessageBox::Cancel:
609 default:
611 return false;
613 break;
616 return true;
619 void kworship::fileNew()
621 if (askToSave())
623 setDocument();
627 void kworship::fileOpen()
629 if (askToSave())
631 // Do the open operation
632 QString filter = "*.kwz *.kw|" + i18n("All KWorship playlists");
633 KUrl defaultUrl("kfiledialog:///playlist");
634 if (m_document->isSaved())
636 defaultUrl = m_document->url();
638 KUrl url = KFileDialog::getOpenUrl(defaultUrl, filter, this);
639 if (!url.isEmpty())
641 loadPlaylist(url);
646 void kworship::fileSave()
648 if (m_document->isSaved())
650 m_document->save();
652 else
654 fileSaveAs();
658 void kworship::fileSaveAs()
660 QString filter = "*.kwz|" + i18n("KWorship playlists") + "\n"
661 "*.kw|" + i18n("KWorship uncompressed playlists");
662 KUrl defaultUrl("kfiledialog:///playlist");
663 if (m_document->isSaved())
665 defaultUrl = m_document->url();
667 KUrl url = KFileDialog::getSaveUrl(defaultUrl, filter, this);
668 if (!url.isEmpty())
670 m_document->saveAs(url);
674 void kworship::optionsPreferences()
676 //avoid to have 2 dialogs shown
677 if ( KConfigDialog::showDialog( "settings" ) ) {
678 return;
680 KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self());
682 QWidget *generalSettingsDlg = new QWidget(dialog);
683 ui_prefs_base.setupUi(generalSettingsDlg);
684 dialog->addPage(generalSettingsDlg, i18n("General"), "preferences-other", i18n("General"));
686 prefsDisplay *displaySettingsDlg = new prefsDisplay(dialog);
687 dialog->addPage(displaySettingsDlg, i18n("Display"), "video-projector", i18n("Display and Screen"));
689 prefsSongDB *songdbSettingsDlg = new prefsSongDB(dialog);
690 dialog->addPage(songdbSettingsDlg, i18n("Song DB"), "applications-multimedia", i18n("Song Database"));
692 QWidget *presentationSettingsDlg = new QWidget(dialog);
693 ui_prefsPresentations_base.setupUi(presentationSettingsDlg);
694 dialog->addPage(presentationSettingsDlg, i18n("Presentations"), "view-presentation", i18n("Presentations and Slideshows"));
696 connect(dialog, SIGNAL(settingsChanged(QString)), m_view, SLOT(settingsChanged()));
697 connect(dialog, SIGNAL(settingsChanged(QString)), this, SLOT(settingsChanged()));
698 dialog->setAttribute( Qt::WA_DeleteOnClose );
699 dialog->show();
702 void kworship::playlist_doubleClicked(QModelIndex index)
704 KwPlaylistNode* node = m_playlistModel->itemFromIndex(index);
705 node->activate(m_displayManager);
708 void kworship::playlistReset()
710 // Connect up the new document
711 m_playlistModel->setRootNode(m_document->playlist()->getNode(0));
714 void kworship::presentationDelete()
716 setPresentation(0, true);
717 presentationSelected(0);
720 void kworship::presentationSelected(int)
722 // Find the treeviews current index
723 QModelIndex index = m_selectPresTree->currentIndex();
724 UpPresentationsModel* model = m_presentationManager->presentationsModel();
725 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
726 if (0 != presNode)
728 m_view->listSlides->setModel(model);
729 m_view->listSlides->setRootIndex(index);
730 setPresentation(presNode->getItem());
732 else
734 m_view->listSlides->setModel(0);
735 setPresentation(0);
739 void kworship::presentationToggled(bool checked)
741 // Find the treeviews current index
742 QModelIndex index = m_selectPresTree->currentIndex();
743 UpPresentationsModel* model = m_presentationManager->presentationsModel();
744 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
745 if (0 != presNode)
747 if (checked)
749 presNode->getItem()->startSlideshow();
751 else
753 presNode->getItem()->stopSlideshow();
758 void kworship::presentationPreviousSlide()
760 // Find the treeviews current index
761 QModelIndex index = m_selectPresTree->currentIndex();
762 UpPresentationsModel* model = m_presentationManager->presentationsModel();
763 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
764 if (0 != presNode)
766 presNode->getItem()->previousSlide();
770 void kworship::presentationNextSlide()
772 // Find the treeviews current index
773 QModelIndex index = m_selectPresTree->currentIndex();
774 UpPresentationsModel* model = m_presentationManager->presentationsModel();
775 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
776 if (0 != presNode)
778 presNode->getItem()->nextSlide();
782 void kworship::presentationPreviousStep()
784 // Find the treeviews current index
785 QModelIndex index = m_selectPresTree->currentIndex();
786 UpPresentationsModel* model = m_presentationManager->presentationsModel();
787 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
788 if (0 != presNode)
790 presNode->getItem()->previousStep();
794 void kworship::presentationNextStep()
796 // Find the treeviews current index
797 QModelIndex index = m_selectPresTree->currentIndex();
798 UpPresentationsModel* model = m_presentationManager->presentationsModel();
799 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(index));
800 if (0 != presNode)
802 presNode->getItem()->nextStep();
806 void kworship::slide_doubleClicked(QModelIndex index)
808 // Find the listviews current index
809 UpPresentationsModel* model = m_presentationManager->presentationsModel();
810 QModelIndex parentIndex = model->parent(index);
811 UpPresentationNode* presNode = dynamic_cast<UpPresentationNode*>(model->itemFromIndex(parentIndex));
812 if (0 != presNode)
814 presNode->getItem()->goToSlide(index.row());
818 // Documents
819 void kworship::setDocument(KUrl url)
821 delete m_document;
822 m_document = new KwDocument(url, this);
824 // Playlist will have changed
825 playlistReset();
827 // Wire up signals
828 connect(m_document, SIGNAL(playlistReset()), this, SLOT(playlistReset()));
831 // Presentations
832 void kworship::setPresentation(UpPresentation* presentation, bool alreadyDestroyed)
834 if (0 != m_currentPresentation)
836 // Stop the slideshow if its running
837 m_view->slideshows->setVisible(false);
838 if (!alreadyDestroyed)
840 m_currentPresentation->stopSlideshow();
841 disconnect(m_currentPresentation, SIGNAL(currentSlideshowChanged(QString)), this, SLOT(changeSlideshowExternal(QString)));
842 disconnect(m_currentPresentation, SIGNAL(customSlideshowsModified()), this, SLOT(refreshSlideshows()));
843 disconnect(m_currentPresentation, SIGNAL(slideshowStarted(int)), this, SLOT(slideshowStarted(int)));
844 disconnect(m_currentPresentation, SIGNAL(slideshowStopped()), this, SLOT(slideshowStopped()));
845 disconnect(m_currentPresentation, SIGNAL(slideshowSlideChanged(int, int)), this, SLOT(slideshowSlideChanged(int, int)));
846 disconnect(m_currentPresentation, SIGNAL(slideshowStepChanged(int)), this, SLOT(slideshowStepChanged(int)));
847 disconnect(m_currentPresentation, SIGNAL(destroyed(QObject*)), this, SLOT(presentationDelete()));
849 slideshowStopped();
851 m_currentPresentation = presentation;
852 if (0 != m_currentPresentation)
854 connect(m_currentPresentation, SIGNAL(currentSlideshowChanged(QString)), this, SLOT(changeSlideshowExternal(QString)));
855 connect(m_currentPresentation, SIGNAL(customSlideshowsModified()), this, SLOT(refreshSlideshows()));
856 connect(m_currentPresentation, SIGNAL(slideshowStarted(int)), this, SLOT(slideshowStarted(int)));
857 connect(m_currentPresentation, SIGNAL(slideshowStopped()), this, SLOT(slideshowStopped()));
858 connect(m_currentPresentation, SIGNAL(slideshowSlideChanged(int, int)), this, SLOT(slideshowSlideChanged(int, int)));
859 connect(m_currentPresentation, SIGNAL(slideshowStepChanged(int)), this, SLOT(slideshowStepChanged(int)));
860 connect(m_currentPresentation, SIGNAL(destroyed(QObject*)), this, SLOT(presentationDelete()));
861 // update slideshows list
862 refreshSlideshows();
863 m_view->slideshows->setVisible(true);
865 if (m_currentPresentation->isSlideshowRunning())
867 slideshowStarted(m_currentPresentation->numSlidesInSlideshow());
868 slideshowSlideChanged(m_currentPresentation->currentSlideshowSlide(), m_currentPresentation->stepsInCurrentSlideshowSlide());
869 slideshowStepChanged(m_currentPresentation->currentSlideshowStep());
872 m_slideshowAction->setEnabled(0 != m_currentPresentation);
875 // Custom slideshows
877 void kworship::presentationComboReset()
879 m_selectPresTree->expandToDepth(0);
880 m_selectPresTree->setItemsExpandable(false);
883 void kworship::changeSlideshowCombo(QString name)
885 Q_ASSERT(0 != m_currentPresentation);
886 m_currentPresentation->setSlideshow(name);
887 refreshSlides();
890 void kworship::changeSlideshowExternal(QString name)
892 if (m_view->comboSlideshows->currentText() != name)
894 m_view->comboSlideshows->setCurrentIndex(m_view->comboSlideshows->findText(name));
895 refreshSlides();
899 void kworship::refreshSlideshows()
901 Q_ASSERT(0 != m_currentPresentation);
902 m_view->comboSlideshows->clear();
903 m_view->comboSlideshows->insertItems(0, m_currentPresentation->slideshows());
904 m_view->comboSlideshows->setCurrentIndex(m_view->comboSlideshows->findText(m_currentPresentation->currentSlideshow()));
907 void kworship::refreshSlides()
909 // Clear child cache
910 QModelIndex root = m_view->listSlides->rootIndex();
911 DefaultModelNode* node = m_presentationManager->presentationsModel()->itemFromIndex(root);
912 Q_ASSERT(0 != node);
913 node->clearChildCache();
915 // Force a refresh
916 m_view->listSlides->setRootIndex(root);
919 void kworship::addSlideshowLinkToPlaylist()
921 Q_ASSERT(0 != m_currentPresentation);
922 QUrl url = m_currentPresentation->url();
923 QString slideshow = m_currentPresentation->currentSlideshow();
924 /// @todo Implement me
926 void kworship::addSlideshowCopyToPlaylist()
928 Q_ASSERT(0 != m_currentPresentation);
929 QString slideshow = m_currentPresentation->currentSlideshow();
930 /// @todo Implement me
933 // From current presentation
935 void kworship::slideshowStarted(int numSlides)
937 // Hide the screen
938 if (0 != m_mainDisplay)
940 m_mainDisplay->hide();
943 // Clear the display
944 m_displayManager->background.clear();
945 m_displayManager->text.clear();
947 m_view->slideshows->setEnabled(false);
948 m_view->progressPresSlides->setMaximum(numSlides);
949 m_view->progressPresSlides->setVisible(true);
950 m_slideshowAction->setChecked(true);
953 void kworship::slideshowStopped()
955 m_view->slideshows->setEnabled(true);
956 m_view->progressPresSlides->setVisible(false);
957 m_view->progressPresSteps->setVisible(false);
958 m_slideshowAction->setChecked(false);
959 m_slideshowPrevSlideAction->setEnabled(false);
960 m_slideshowPrevStepAction->setEnabled(false);
961 m_slideshowNextStepAction->setEnabled(false);
962 m_slideshowNextSlideAction->setEnabled(false);
964 // Clear any preview left from the slideshow
965 m_displayManager->background.clear();
966 // Clear slide notes
967 m_slideNotes->document()->clear();
969 // Show the screen again
970 if (0 != m_mainDisplay)
972 m_mainDisplay->showFullScreen();
976 void kworship::slideshowSlideChanged(int slide, int numSteps)
978 m_view->progressPresSlides->setValue(slide + 1);
979 m_view->progressPresSteps->setMaximum(numSteps);
980 m_view->progressPresSteps->setVisible(numSteps > 1);
982 m_slideshowPrevSlideAction->setEnabled(slide > 0);
983 m_slideshowNextSlideAction->setEnabled(slide < m_view->progressPresSlides->maximum()-1);
985 // live preview and notes
986 m_slideNotes->document()->clear();
987 assert(0 != m_currentPresentation);
988 UpSlide* currentSlide = m_currentPresentation->slide(slide);
989 if (0 != currentSlide)
991 // live preview
992 if (Settings::presLivePreview())
994 m_displayManager->background.setImage(currentSlide->preview());
996 // notes
997 currentSlide->writeNotes(m_slideNotes->document());
1001 void kworship::slideshowStepChanged(int step)
1003 m_view->progressPresSteps->setValue(step + 1);
1005 bool firstSlide = (m_view->progressPresSlides->value() <= 1);
1006 bool lastSlide = (m_view->progressPresSlides->value() >= m_view->progressPresSlides->maximum());
1007 bool firstStep = firstSlide && (step <= 0);
1008 bool lastStep = lastSlide && (step >= m_view->progressPresSteps->maximum() - 1);
1009 m_slideshowPrevStepAction->setEnabled(!firstStep);
1010 m_slideshowNextStepAction->setEnabled(!lastStep);
1013 // Song DB
1015 void kworship::songdbUnlock()
1017 m_unlockSongDbAction->setVisible(false);
1018 m_lockSongDbAction->setVisible(true);
1021 void kworship::songdbLock()
1023 m_unlockSongDbAction->setVisible(true);
1024 m_lockSongDbAction->setVisible(false);
1027 void kworship::songdbAdd()
1029 KwSongdbSongEditDialog* dialog = new KwSongdbSongEditDialog(0);
1030 dialog->setCaption(i18n("Add Song"));
1031 dialog->setAttribute(Qt::WA_DeleteOnClose, true);
1032 dialog->show();
1035 void kworship::songdbEdit()
1037 /// @todo Ensure the same song isn't open twice
1038 KwSongdbSong* song = m_songDbTree->currentSong();
1039 if (0 != song)
1041 KwSongdbVersion* version = m_songDbTree->currentSongVersion();
1042 // version may be 0
1043 KwSongdbSongEditDialog* dialog = new KwSongdbSongEditDialog(song, version);
1044 dialog->setCaption(i18n("Edit Song - %1", song->name()));
1045 dialog->setAttribute(Qt::WA_DeleteOnClose, true);
1046 dialog->show();
1048 else
1050 KMessageBox::information(this, i18n("Please select a song."));
1054 void kworship::songdbEditSongBooks()
1056 KwSongdbSongBooksEditWidget::showDialog();
1059 // Bibles
1061 void kworship::fillBiblesList(BibleManager* mgr)
1063 QStringList languages = mgr->manager->languages();
1064 mgr->comboBibles->clear();
1065 mgr->comboBibles->addItem(i18n("-- select a translation --"));
1066 foreach (QString language, languages)
1068 QStringList modules = mgr->manager->moduleNamesInLanguage(language);
1069 if (!modules.isEmpty())
1071 mgr->comboBibles->addItem(language, QVariant(modules.first()));
1072 foreach (QString module, modules)
1074 mgr->comboBibles->addItem(" " + module, QVariant(module));
1080 void kworship::bibleConnect()
1082 // Get the current bible manager
1083 int tab = m_bibleTabs->currentIndex();
1084 Q_ASSERT(tab >= 0 && tab < m_bibles.size());
1085 BibleManager* mgr = &m_bibles[tab];
1087 // This will force the connection
1088 fillBiblesList(mgr);
1089 if (mgr->comboBibles->count() == 0)
1091 KMessageBox::information(this, i18n("No bibles found"));
1093 else
1095 mgr->comboBibles->setEnabled(true);
1099 void kworship::bibleChanged()
1101 // Get the current bible manager
1102 int tab = m_bibleTabs->currentIndex();
1103 if (tab >= 0 && tab < m_bibles.size())
1105 BibleManager& mgr = m_bibles[tab];
1106 bool enabled = mgr.comboBibles->isEnabled();
1108 // Is a bible selected?
1109 int bibleInd = mgr.comboBibles->currentIndex();
1110 QString bible;
1111 KwBibleModule* module = 0;
1112 if (bibleInd >= 0)
1114 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
1115 module = mgr.manager->module(bible);
1118 // Update the list of books
1119 QString book = m_view->comboBibleBook->currentText();
1120 int chapter = m_view->comboBibleChapter->currentIndex();
1121 m_view->comboBibleBook->clear();
1122 if (0 != module)
1124 QStringList bookNames = module->books();
1125 for (int i = 0; i < bookNames.size(); ++i)
1127 const QString& bookName = bookNames[i];
1128 m_view->comboBibleBook->addItem(bookName, QVariant(i));
1130 int index = m_view->comboBibleBook->findText(book);
1131 bool canPreserveBook = (index >= 0);
1132 if (!canPreserveBook && bookNames.size() > 0)
1134 index = 0;
1136 m_view->comboBibleBook->setCurrentIndex(index);
1137 if (canPreserveBook && chapter >= 0)
1139 // If we can restore book, also restore chapter
1140 m_view->comboBibleChapter->setCurrentIndex(chapter);
1143 else
1145 enabled = false;
1148 m_view->comboBibleBook->setEnabled(enabled);
1149 m_view->comboBibleChapter->setEnabled(enabled);
1150 m_view->searchBible->setEnabled(enabled);
1151 m_view->textBible->setEnabled(enabled);
1155 void kworship::bibleBookChanged()
1157 m_view->comboBibleChapter->clear();
1159 // Get the current bible manager
1160 int tab = m_bibleTabs->currentIndex();
1161 if (tab >= 0 && tab < m_bibles.size())
1163 BibleManager& mgr = m_bibles[tab];
1165 // Is a bible selected?
1166 int bibleInd = mgr.comboBibles->currentIndex();
1167 QString bible;
1168 KwBibleModule* module = 0;
1169 if (bibleInd >= 0)
1171 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
1172 module = mgr.manager->module(bible);
1174 if (0 != module)
1176 // Is a book selected?
1177 int index = m_view->comboBibleBook->currentIndex();
1178 if (index >= 0)
1180 int bookIndex = m_view->comboBibleBook->itemData(index).toInt();
1181 int numChapters = module->numChapters(bookIndex);
1182 for (int i = 0; i < numChapters; ++i)
1184 m_view->comboBibleChapter->addItem(QString("%1").arg(i+1), QVariant(i));
1189 bibleSearch();
1192 void kworship::bibleSearch()
1194 // Get the current bible manager
1195 int tab = m_bibleTabs->currentIndex();
1196 if (tab >= 0 && tab < m_bibles.size())
1198 BibleManager& mgr = m_bibles[tab];
1200 // Is a bible selected?
1201 int bibleInd = mgr.comboBibles->currentIndex();
1202 QString bible;
1203 KwBibleModule* module = 0;
1204 if (bibleInd >= 0)
1206 QString bible = mgr.comboBibles->itemData(bibleInd).toString();
1207 module = mgr.manager->module(bible);
1209 if (0 != module)
1211 // Is a book selected?
1212 int bookIndex = m_view->comboBibleBook->currentIndex();
1213 int chapterIndex = -1;
1214 if (bookIndex >= 0)
1216 // Is a chapter selected?
1217 chapterIndex = m_view->comboBibleChapter->currentIndex();
1220 bool valid;
1221 KwBibleModule::Key relativeKey = module->createKey(bookIndex, chapterIndex);
1222 KwBibleModule::Key key = module->createKey(relativeKey, m_view->searchBible->text(), &valid);
1223 // Update book and chapter
1224 m_view->comboBibleBook->setCurrentIndex(key.start.book);
1225 m_view->comboBibleChapter->setCurrentIndex(key.start.chapter);
1226 m_view->textBible->document()->setHtml(module->renderText(key));
1228 // Update color of search box
1229 static QPalette p = m_view->searchBible->palette();
1230 QPalette changedPal = p;
1231 if (!valid)
1233 changedPal.setColor( QPalette::Normal, QPalette::Base, QColor(255, 127, 127) );
1235 m_view->searchBible->setPalette(changedPal);
1237 return;
1240 m_view->textBible->document()->setPlainText(QString());
1243 #include "kworship.moc"