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 #include "kworshipview.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>
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"
64 #include "UpKpr1Backend.h"
65 #include "UpKpr2Backend.h"
66 #include "UpOoBackend.h"
68 #include <kconfigdialog.h>
69 #include <kstatusbar.h>
71 #include <kactionmenu.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>
85 #include <QDesktopWidget>
87 #include <QToolButton>
89 #include <QSqlDatabase>
90 #include <QHeaderView>
95 , m_view(new kworshipView(this))
98 , m_presentationManager(new UpManager(this))
99 , m_currentPresentation(0)
102 m_playlistModel
= new KwPlaylistModel
;
105 // set up presentation backends
106 m_presentationManager
->registerBackend
<UpOoBackend
>();
107 m_presentationManager
->registerBackend
<UpKpr2Backend
>();
108 m_presentationManager
->registerBackend
<UpKpr1Backend
>();
111 m_previewDisplay
= 0;
114 setAcceptDrops(true);
116 // tell the KXmlGuiWindow that this is indeed the main widget
117 setCentralWidget(m_view
);
119 // then, setup our actions
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.
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
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
);
157 KwDatabaseSetup dbSetup
;
158 bool databaseOk
= dbSetup
.initialiseFromConfig();
161 new KwSongdb(dbSetup
.database());
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
);
218 m_songDbTree
= new KwSongdbTree(m_view
);
219 m_view
->layoutSongsTree
->addWidget(m_songDbTree
);
220 groupByMenu
->addActions(m_songDbTree
->groupByActions()->actions());
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
);
278 connect(m_view
->listSlides
, SIGNAL(doubleClicked(QModelIndex
)), this, SLOT(slide_doubleClicked(QModelIndex
)));
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
);
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);
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();
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
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
);
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()));
402 kworship::~kworship()
404 delete KwSongdb::self();
412 /// Load a specified playlist.
413 void kworship::loadPlaylist(const KUrl
& url
)
416 m_document
->reload();
419 void kworship::setupActions()
422 KStandardAction::quit(qApp
, SLOT(quit()), actionCollection());
423 KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
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());
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()));
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
)
494 if (m_view
->isVisible())
496 currentScreen
= desktop
->screenNumber(m_view
);
500 currentScreen
= desktop
->primaryScreen();
503 if (displayScreen
== currentScreen
&& displayScreen
< screens
-1)
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
)
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();
554 if (0 != m_mainDisplay
)
556 m_mainDisplay
->close();
561 void kworship::mainDisplayClosed()
563 m_mainDisplay
->deleteLater();
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
)
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
:
599 // If the document is still modified, save must have been cancelled
600 if (m_document
->isModified())
606 case KMessageBox::No
:
608 case KMessageBox::Cancel
:
619 void kworship::fileNew()
627 void kworship::fileOpen()
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);
646 void kworship::fileSave()
648 if (m_document
->isSaved())
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);
670 m_document
->saveAs(url
);
674 void kworship::optionsPreferences()
676 //avoid to have 2 dialogs shown
677 if ( KConfigDialog::showDialog( "settings" ) ) {
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
);
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
));
728 m_view
->listSlides
->setModel(model
);
729 m_view
->listSlides
->setRootIndex(index
);
730 setPresentation(presNode
->getItem());
734 m_view
->listSlides
->setModel(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
));
749 presNode
->getItem()->startSlideshow();
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
));
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
));
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
));
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
));
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
));
814 presNode
->getItem()->goToSlide(index
.row());
819 void kworship::setDocument(KUrl url
)
822 m_document
= new KwDocument(url
, this);
824 // Playlist will have changed
828 connect(m_document
, SIGNAL(playlistReset()), this, SLOT(playlistReset()));
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()));
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
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
);
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
);
890 void kworship::changeSlideshowExternal(QString name
)
892 if (m_view
->comboSlideshows
->currentText() != name
)
894 m_view
->comboSlideshows
->setCurrentIndex(m_view
->comboSlideshows
->findText(name
));
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()
910 QModelIndex root
= m_view
->listSlides
->rootIndex();
911 DefaultModelNode
* node
= m_presentationManager
->presentationsModel()->itemFromIndex(root
);
913 node
->clearChildCache();
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
)
938 if (0 != m_mainDisplay
)
940 m_mainDisplay
->hide();
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();
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
)
992 if (Settings::presLivePreview())
994 m_displayManager
->background
.setImage(currentSlide
->preview());
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
);
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);
1035 void kworship::songdbEdit()
1037 /// @todo Ensure the same song isn't open twice
1038 KwSongdbSong
* song
= m_songDbTree
->currentSong();
1041 KwSongdbVersion
* version
= m_songDbTree
->currentSongVersion();
1043 KwSongdbSongEditDialog
* dialog
= new KwSongdbSongEditDialog(song
, version
);
1044 dialog
->setCaption(i18n("Edit Song - %1", song
->name()));
1045 dialog
->setAttribute(Qt::WA_DeleteOnClose
, true);
1050 KMessageBox::information(this, i18n("Please select a song."));
1054 void kworship::songdbEditSongBooks()
1056 KwSongdbSongBooksEditWidget::showDialog();
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"));
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();
1111 KwBibleModule
* module
= 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();
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)
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
);
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();
1168 KwBibleModule
* module
= 0;
1171 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
1172 module
= mgr
.manager
->module(bible
);
1176 // Is a book selected?
1177 int index
= m_view
->comboBibleBook
->currentIndex();
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
));
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();
1203 KwBibleModule
* module
= 0;
1206 QString bible
= mgr
.comboBibles
->itemData(bibleInd
).toString();
1207 module
= mgr
.manager
->module(bible
);
1211 // Is a book selected?
1212 int bookIndex
= m_view
->comboBibleBook
->currentIndex();
1213 int chapterIndex
= -1;
1216 // Is a chapter selected?
1217 chapterIndex
= m_view
->comboBibleChapter
->currentIndex();
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
;
1233 changedPal
.setColor( QPalette::Normal
, QPalette::Base
, QColor(255, 127, 127) );
1235 m_view
->searchBible
->setPalette(changedPal
);
1240 m_view
->textBible
->document()->setPlainText(QString());
1243 #include "kworship.moc"