diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index d7ca10f0f..436ea82de 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -199,6 +199,10 @@ class Manager(object): urlquote(unicode(settings.value(u'db password').toString())), urlquote(unicode(settings.value(u'db hostname').toString())), urlquote(unicode(settings.value(u'db database').toString()))) + if db_type == u'mysql': + db_encoding = unicode( + settings.value(u'db encoding', u'utf8').toString()) + self.db_url += u'?charset=%s' % urlquote(db_encoding) settings.endGroup() if upgrade_mod: db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 347946337..63fc04153 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -93,6 +93,7 @@ class UiStrings(object): self.New = translate('OpenLP.Ui', 'New') self.NewService = translate('OpenLP.Ui', 'New Service') self.NewTheme = translate('OpenLP.Ui', 'New Theme') + self.NextTrack = translate('OpenLP.Ui', 'Next Track') self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') @@ -322,8 +323,7 @@ def create_action(parent, name, **kwargs): A QList (or a list of strings) which are set as shortcuts. ``context`` - A context for the shortcut execution (only will be set together with - ``shortcuts``). + A context for the shortcut execution. ``category`` A category the action should be listed in the shortcut dialog. @@ -354,8 +354,8 @@ def create_action(parent, name, **kwargs): action.setData(QtCore.QVariant(kwargs.pop(u'data'))) if kwargs.get(u'shortcuts'): action.setShortcuts(kwargs.pop(u'shortcuts')) - if kwargs.get(u'context') is not None: - action.setShortcutContext(kwargs.pop(u'context')) + if u'context' in kwargs: + action.setShortcutContext(kwargs.pop(u'context')) if kwargs.get(u'category'): action_list = ActionList.get_instance() action_list.add_action(action, unicode(kwargs.pop(u'category'))) @@ -364,7 +364,7 @@ def create_action(parent, name, **kwargs): kwargs.pop(u'triggers')) for key in kwargs.keys(): if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked', - u'shortcuts', u'context', u'category', u'triggers']: + u'shortcuts', u'category', u'triggers']: log.warn(u'Parameter %s was not consumed in create_action().', key) return action diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index d515fc501..b1d44b3dd 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -175,6 +175,9 @@ class GeneralTab(SettingsTab): self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox) self.startPausedCheckBox.setObjectName(u'startPausedCheckBox') self.audioLayout.addWidget(self.startPausedCheckBox) + self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox) + self.repeatListCheckBox.setObjectName(u'repeatListCheckBox') + self.audioLayout.addWidget(self.repeatListCheckBox) self.rightLayout.addWidget(self.audioGroupBox) self.rightLayout.addStretch() # Signals and slots @@ -251,6 +254,8 @@ class GeneralTab(SettingsTab): translate('OpenLP.GeneralTab', 'Background Audio')) self.startPausedCheckBox.setText( translate('OpenLP.GeneralTab', 'Start background audio paused')) + self.repeatListCheckBox.setText( + translate('OpenLP.GeneralTab', 'Repeat track list')) def load(self): """ @@ -298,6 +303,8 @@ class GeneralTab(SettingsTab): QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0]) self.startPausedCheckBox.setChecked(settings.value( u'audio start paused', QtCore.QVariant(True)).toBool()) + self.repeatListCheckBox.setChecked(settings.value( + u'audio repeat list', QtCore.QVariant(False)).toBool()) settings.endGroup() self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked()) @@ -350,7 +357,9 @@ class GeneralTab(SettingsTab): QtCore.QVariant(self.overrideCheckBox.isChecked())) settings.setValue(u'audio start paused', QtCore.QVariant(self.startPausedCheckBox.isChecked())) - settings.endGroup() + settings.setValue(u'audio repeat list', + QtCore.QVariant(self.repeatListCheckBox.isChecked())) + settings.endGroup() # On save update the screens as well self.postSetUp(True) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 971a9903f..b0a18537b 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -30,7 +30,6 @@ and play multimedia within OpenLP. """ import cgi import logging -import os import sys from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL @@ -136,12 +135,12 @@ class MainDisplay(Display): QtCore.Qt.WindowStaysOnTopHint if QtCore.QSettings().value(u'advanced/x11 bypass wm', QtCore.QVariant(True)).toBool(): - windowFlags = windowFlags | QtCore.Qt.X11BypassWindowManagerHint + windowFlags |= QtCore.Qt.X11BypassWindowManagerHint # FIXME: QtCore.Qt.SplashScreen is workaround to make display screen # stay always on top on Mac OS X. For details see bug 906926. # It needs more investigation to fix it properly. if sys.platform == 'darwin': - windowFlags = windowFlags | QtCore.Qt.SplashScreen + windowFlags |= QtCore.Qt.SplashScreen self.setWindowFlags(windowFlags) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setTransparency(True) @@ -493,11 +492,15 @@ class AudioPlayer(QtCore.QObject): QtCore.QObject.__init__(self, parent) self.currentIndex = -1 self.playlist = [] + self.repeat = False self.mediaObject = Phonon.MediaObject() + self.mediaObject.setTickInterval(100) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) Phonon.createPath(self.mediaObject, self.audioObject) QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish) + QtCore.QObject.connect(self.mediaObject, + QtCore.SIGNAL(u'finished()'), self.onFinished) def __del__(self): """ @@ -516,6 +519,14 @@ class AudioPlayer(QtCore.QObject): if len(self.playlist) > self.currentIndex: self.mediaObject.enqueue(self.playlist[self.currentIndex]) + def onFinished(self): + if self.repeat: + log.debug(u'Repeat is enabled... here we go again!') + self.mediaObject.clearQueue() + self.mediaObject.clear() + self.currentIndex = -1 + self.play() + def connectVolumeSlider(self, slider): slider.setAudioOutput(self.audioObject) @@ -563,3 +574,27 @@ class AudioPlayer(QtCore.QObject): for filename in filenames: self.playlist.append(Phonon.MediaSource(filename)) + def next(self): + if not self.repeat and self.currentIndex + 1 == len(self.playlist): + return + isPlaying = self.mediaObject.state() == Phonon.PlayingState + self.currentIndex += 1 + if self.repeat and self.currentIndex == len(self.playlist): + self.currentIndex = 0 + self.mediaObject.clearQueue() + self.mediaObject.clear() + self.mediaObject.enqueue(self.playlist[self.currentIndex]) + if isPlaying: + self.mediaObject.play() + + def goTo(self, index): + isPlaying = self.mediaObject.state() == Phonon.PlayingState + self.mediaObject.clearQueue() + self.mediaObject.clear() + self.currentIndex = index + self.mediaObject.enqueue(self.playlist[self.currentIndex]) + if isPlaying: + self.mediaObject.play() + + def connectSlot(self, signal, slot): + QtCore.QObject.connect(self.mediaObject, signal, slot) diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index b28497906..71a3d8a7a 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -100,8 +100,7 @@ class MediaController(object): Register each media Player controller (Webkit, Phonon, etc) and store for later use """ - if controller.check_available(): - self.mediaPlayers[controller.name] = controller + self.mediaPlayers[controller.name] = controller def check_available_media_players(self): """ @@ -134,7 +133,8 @@ class MediaController(object): QtCore.QVariant(u'webkit')).toString()) savedPlayers = playerSettings.split(u',') invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers \ - if not mediaPlayer in self.mediaPlayers] + if not mediaPlayer in self.mediaPlayers or \ + not self.mediaPlayers[mediaPlayer].check_available()] if len(invalidMediaPlayers) > 0: for invalidPlayer in invalidMediaPlayers: savedPlayers.remove(invalidPlayer) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 002ab0eb6..420c3c6f2 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -33,7 +33,7 @@ from collections import deque from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \ - translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem + translate, build_icon, build_html, PluginManager, ServiceItem from openlp.core.lib.ui import UiStrings, create_action from openlp.core.lib import SlideLimits, ServiceItemAction from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList @@ -46,9 +46,10 @@ class SlideList(QtGui.QTableWidget): Customised version of QTableWidget which can respond to keyboard events. """ - def __init__(self, parent=None, name=None): + def __init__(self, parent=None): QtGui.QTableWidget.__init__(self, parent.controller) + class Controller(QtGui.QWidget): """ Controller is a general controller widget. @@ -95,8 +96,10 @@ class SlideController(Controller): u'loopSeparator', u'delaySpinBox' ] - self.songEditList = [ - u'editSong', + self.audioList = [ + u'songMenu', + u'audioPauseItem', + u'audioTimeLabel' ] self.timer_id = 0 self.songEdit = False @@ -273,14 +276,44 @@ class SlideController(Controller): self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup) self.songMenu.setMenu(QtGui.QMenu( translate('OpenLP.SlideController', 'Go To'), self.toolbar)) - self.songMenu.hide() self.toolbar.addToolbarWidget(self.songMenu) # Stuff for items with background audio. - self.audioPauseItem = self.toolbar.addToolbarAction(u'audioPause', - text=u'Pause Audio', icon=u':/slides/media_playback_pause.png', + self.audioPauseItem = self.toolbar.addToolbarAction( + u'audioPauseItem', icon=u':/slides/media_playback_pause.png', + text=translate('OpenLP.SlideController', 'Pause Audio'), tooltip=translate('OpenLP.SlideController', 'Pause audio.'), - checked=False, visible=False, + checked=False, visible=False, category=self.category, triggers=self.onAudioPauseClicked) + self.audioMenu = QtGui.QMenu( + translate('OpenLP.SlideController', 'Background Audio'), self) + self.audioPauseItem.setMenu(self.audioMenu) + self.audioPauseItem.setParent(self) + self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode( + QtGui.QToolButton.MenuButtonPopup) + self.nextTrackItem = create_action(self, u'nextTrackItem', + text=translate('OpenLP.SlideController', 'Next Track'), + icon=u':/slides/media_playback_next.png', tooltip=translate( + 'OpenLP.SlideController', 'Go to next audio track.'), + category=self.category, context=QtCore.Qt.WindowShortcut, + triggers=self.onNextTrackClicked) + self.audioMenu.addAction(self.nextTrackItem) + self.trackMenu = self.audioMenu.addMenu( + translate('OpenLP.SlideController', 'Tracks')) + self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar) + self.audioTimeLabel.setAlignment( + QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter) + self.audioTimeLabel.setStyleSheet( + u'background-color: palette(background); ' + u'border-top-color: palette(shadow); ' + u'border-left-color: palette(shadow); ' + u'border-bottom-color: palette(light); ' + u'border-right-color: palette(light); ' + u'border-radius: 3px; border-style: inset; ' + u'border-width: 1; font-family: monospace; margin: 2px;' + ) + self.audioTimeLabel.setObjectName(u'audioTimeLabel') + self.toolbar.addToolbarWidget(self.audioTimeLabel) + self.toolbar.setWidgetVisible(self.audioList, False) # Screen preview area self.previewFrame = QtGui.QFrame(self.splitter) self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio)) @@ -365,7 +398,7 @@ class SlideController(Controller): QtCore.QObject.connect(self.previewListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLiveClick) - self.toolbar.setWidgetVisible(self.songEditList, False) + self.toolbar.setWidgetVisible([u'editSong'], False) if self.isLive: self.setLiveHotkeys(self) self.__addActionsToWidget(self.previewListWidget) @@ -527,7 +560,7 @@ class SlideController(Controller): self.keypress_loop = True keypressCommand = self.keypress_queue.popleft() if keypressCommand == ServiceItemAction.Previous: - Receiver.send_message('servicemanager_previous_item', None) + Receiver.send_message('servicemanager_previous_item') elif keypressCommand == ServiceItemAction.PreviousLastSlide: # Go to the last slide of the previous item Receiver.send_message('servicemanager_previous_item', u'last slide') @@ -548,6 +581,8 @@ class SlideController(Controller): self.display.setup() if self.isLive: self.__addActionsToWidget(self.display) + self.display.audioPlayer.connectSlot( + QtCore.SIGNAL(u'tick(qint64)'), self.onAudioTimeRemaining) # The SlidePreview's ratio. try: self.ratio = float(self.screens.current[u'size'].width()) / \ @@ -559,7 +594,7 @@ class SlideController(Controller): self.previewDisplay.setup() serviceItem = ServiceItem() self.previewDisplay.webView.setHtml(build_html(serviceItem, - self.previewDisplay.screen, None, self.isLive, None, + self.previewDisplay.screen, None, self.isLive, plugins=PluginManager.get_instance().plugins)) self.mediaController.setup_display(self.previewDisplay) if self.serviceItem: @@ -621,7 +656,7 @@ class SlideController(Controller): Adjusts the value of the ``delaySpinBox`` to the given one. """ self.delaySpinBox.setValue(int(value)) - + def updateSlideLimits(self): """ Updates the Slide Limits variable from the settings. @@ -679,9 +714,9 @@ class SlideController(Controller): # See bug #791050 self.toolbar.hide() self.mediabar.hide() - self.toolbar.setWidgetVisible(self.songEditList, False) + self.toolbar.setWidgetVisible([u'editSong'], False) if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin: - self.toolbar.setWidgetVisible(self.songEditList) + self.toolbar.setWidgetVisible([u'editSong']) elif item.is_media(): self.mediabar.show() self.previousItem.setVisible(not item.is_media()) @@ -764,10 +799,23 @@ class SlideController(Controller): self.display.audioPlayer.reset() self.setAudioItemsVisibility(False) self.audioPauseItem.setChecked(False) + # If the current item has background audio if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio): log.debug(u'Starting to play...') self.display.audioPlayer.addToPlaylist( self.serviceItem.background_audio) + self.trackMenu.clear() + for counter in range(len(self.serviceItem.background_audio)): + action = self.trackMenu.addAction(os.path.basename( + self.serviceItem.background_audio[counter])) + action.setData(counter) + QtCore.QObject.connect(action, + QtCore.SIGNAL(u'triggered(bool)'), + self.onTrackTriggered) + self.display.audioPlayer.repeat = QtCore.QSettings().value( + self.parent().generalSettingsSection + \ + u'/audio repeat list', + QtCore.QVariant(False)).toBool() if QtCore.QSettings().value( self.parent().generalSettingsSection + \ u'/audio start paused', @@ -1021,7 +1069,7 @@ class SlideController(Controller): else: Receiver.send_message(u'live_display_show') - def onSlideSelected(self, start=False): + def onSlideSelected(self): """ Slide selected in controller """ @@ -1217,7 +1265,7 @@ class SlideController(Controller): self.onToggleLoop() def setAudioItemsVisibility(self, visible): - self.audioPauseItem.setVisible(visible) + self.toolbar.setWidgetVisible(self.audioList, visible) def onAudioPauseClicked(self, checked): if not self.audioPauseItem.isVisible(): @@ -1328,3 +1376,17 @@ class SlideController(Controller): return HideMode.Screen else: return None + + def onNextTrackClicked(self): + self.display.audioPlayer.next() + + def onAudioTimeRemaining(self, time): + seconds = self.display.audioPlayer.mediaObject.remainingTime() // 1000 + minutes = seconds // 60 + seconds %= 60 + self.audioTimeLabel.setText(u' %02d:%02d ' % (minutes, seconds)) + + def onTrackTriggered(self): + action = self.sender() + index = action.data().toInt()[0] + self.display.audioPlayer.goTo(index) diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html index fb88ee0dc..7a2da3bea 100644 --- a/openlp/plugins/remotes/html/index.html +++ b/openlp/plugins/remotes/html/index.html @@ -27,6 +27,7 @@ --> + ${app_title} diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index eeaace513..34a54dee4 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -42,7 +42,7 @@ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ SongImportForm, SongExportForm from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ clean_string -from openlp.plugins.songs.lib.db import Author, Song, MediaFile +from openlp.plugins.songs.lib.db import Author, Song, Book, MediaFile from openlp.plugins.songs.lib.ui import SongStrings log = logging.getLogger(__name__) @@ -55,7 +55,8 @@ class SongSearch(object): Titles = 2 Lyrics = 3 Authors = 4 - Themes = 5 + Books = 5 + Themes = 6 class SongMediaItem(MediaManagerItem): @@ -157,6 +158,8 @@ class SongMediaItem(MediaManagerItem): translate('SongsPlugin.MediaItem', 'Lyrics')), (SongSearch.Authors, u':/songs/song_search_author.png', SongStrings.Authors), + (SongSearch.Books, u':/songs/song_book_edit.png', + SongStrings.SongBooks), (SongSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes) ]) self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value( @@ -195,6 +198,19 @@ class SongMediaItem(MediaManagerItem): Author.display_name.like(u'%' + search_keywords + u'%'), Author.display_name.asc()) self.displayResultsAuthor(search_results) + elif search_type == SongSearch.Books: + log.debug(u'Books Search') + search_results = self.plugin.manager.get_all_objects(Book, + Book.name.like(u'%' + search_keywords + u'%'), + Book.name.asc()) + song_number = False + if not search_results: + search_keywords = search_keywords.rpartition(' ') + search_results = self.plugin.manager.get_all_objects(Book, + Book.name.like(u'%' + search_keywords[0] + u'%'), + Book.name.asc()) + song_number = re.sub(r'[^0-9]', u'', search_keywords[2]) + self.displayResultsBook(search_results, song_number) elif search_type == SongSearch.Themes: log.debug(u'Theme Search') search_results = self.plugin.manager.get_all_objects(Song, @@ -269,6 +285,25 @@ class SongMediaItem(MediaManagerItem): song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) self.listView.addItem(song_name) + def displayResultsBook(self, searchresults, song_number=False): + log.debug(u'display results Book') + self.listView.clear() + for book in searchresults: + songs = sorted(book.songs, key=lambda song: int( + re.sub(r'[^0-9]', u' ', song.song_number).partition(' ')[0]) + if len(re.sub(r'[^\w]', ' ', song.song_number)) else 0) + for song in songs: + # Do not display temporary songs + if song.temporary: + continue + if song_number and not song_number in song.song_number: + continue + song_detail = u'%s - %s (%s)' % (book.name, song.song_number, + song.title) + song_name = QtGui.QListWidgetItem(song_detail) + song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) + self.listView.addItem(song_name) + def onClearTextButtonClick(self): """ Clear the search text. diff --git a/openlp/plugins/songs/lib/songstab.py b/openlp/plugins/songs/lib/songstab.py index e662cee78..5da2a2a3c 100644 --- a/openlp/plugins/songs/lib/songstab.py +++ b/openlp/plugins/songs/lib/songstab.py @@ -33,56 +33,56 @@ class SongsTab(SettingsTab): """ SongsTab is the Songs settings tab in the settings dialog. """ - def __init__(self, parent, title, visible_title, icon_path): - SettingsTab.__init__(self, parent, title, visible_title, icon_path) - def setupUi(self): + """ + Set up the configuration tab UI. + """ self.setObjectName(u'SongsTab') SettingsTab.setupUi(self) - self.SongsModeGroupBox = QtGui.QGroupBox(self.leftColumn) - self.SongsModeGroupBox.setObjectName(u'SongsModeGroupBox') - self.SongsModeLayout = QtGui.QVBoxLayout(self.SongsModeGroupBox) - self.SongsModeLayout.setObjectName(u'SongsModeLayout') - self.SearchAsTypeCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) - self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox') - self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox) - self.SongBarActiveCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) - self.SongBarActiveCheckBox.setObjectName(u'SongBarActiveCheckBox') - self.SongsModeLayout.addWidget(self.SongBarActiveCheckBox) - self.SongUpdateOnEditCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) - self.SongUpdateOnEditCheckBox.setObjectName(u'SongUpdateOnEditCheckBox') - self.SongsModeLayout.addWidget(self.SongUpdateOnEditCheckBox) - self.SongAddFromServiceCheckBox = QtGui.QCheckBox( - self.SongsModeGroupBox) - self.SongAddFromServiceCheckBox.setObjectName( - u'SongAddFromServiceCheckBox') - self.SongsModeLayout.addWidget(self.SongAddFromServiceCheckBox) - self.leftLayout.addWidget(self.SongsModeGroupBox) + self.modeGroupBox = QtGui.QGroupBox(self.leftColumn) + self.modeGroupBox.setObjectName(u'modeGroupBox') + self.modeLayout = QtGui.QVBoxLayout(self.modeGroupBox) + self.modeLayout.setObjectName(u'modeLayout') + self.searchAsTypeCheckBox = QtGui.QCheckBox(self.modeGroupBox) + self.searchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox') + self.modeLayout.addWidget(self.searchAsTypeCheckBox) + self.toolBarActiveCheckBox = QtGui.QCheckBox(self.modeGroupBox) + self.toolBarActiveCheckBox.setObjectName(u'toolBarActiveCheckBox') + self.modeLayout.addWidget(self.toolBarActiveCheckBox) + self.updateOnEditCheckBox = QtGui.QCheckBox(self.modeGroupBox) + self.updateOnEditCheckBox.setObjectName(u'updateOnEditCheckBox') + self.modeLayout.addWidget(self.updateOnEditCheckBox) + self.addFromServiceCheckBox = QtGui.QCheckBox( + self.modeGroupBox) + self.addFromServiceCheckBox.setObjectName( + u'addFromServiceCheckBox') + self.modeLayout.addWidget(self.addFromServiceCheckBox) + self.leftLayout.addWidget(self.modeGroupBox) self.leftLayout.addStretch() self.rightLayout.addStretch() - QtCore.QObject.connect(self.SearchAsTypeCheckBox, + QtCore.QObject.connect(self.searchAsTypeCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onSearchAsTypeCheckBoxChanged) - QtCore.QObject.connect(self.SongBarActiveCheckBox, + QtCore.QObject.connect(self.toolBarActiveCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), - self.onSongBarActiveCheckBoxChanged) - QtCore.QObject.connect(self.SongUpdateOnEditCheckBox, + self.onToolBarActiveCheckBoxChanged) + QtCore.QObject.connect(self.updateOnEditCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), - self.onSongUpdateOnEditCheckBoxChanged) - QtCore.QObject.connect(self.SongAddFromServiceCheckBox, + self.onUpdateOnEditCheckBoxChanged) + QtCore.QObject.connect(self.addFromServiceCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), - self.onSongAddFromServiceCheckBoxChanged) + self.onAddFromServiceCheckBoxChanged) def retranslateUi(self): - self.SongsModeGroupBox.setTitle( + self.modeGroupBox.setTitle( translate('SongsPlugin.SongsTab', 'Songs Mode')) - self.SearchAsTypeCheckBox.setText( + self.searchAsTypeCheckBox.setText( translate('SongsPlugin.SongsTab', 'Enable search as you type')) - self.SongBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab', + self.toolBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab', 'Display verses on live tool bar')) - self.SongUpdateOnEditCheckBox.setText( + self.updateOnEditCheckBox.setText( translate('SongsPlugin.SongsTab', 'Update service from song edit')) - self.SongAddFromServiceCheckBox.setText( + self.addFromServiceCheckBox.setText( translate('SongsPlugin.SongsTab', 'Add missing songs when opening service')) @@ -92,19 +92,19 @@ class SongsTab(SettingsTab): if check_state == QtCore.Qt.Checked: self.song_search = True - def onSongBarActiveCheckBoxChanged(self, check_state): - self.song_bar = False + def onToolBarActiveCheckBoxChanged(self, check_state): + self.tool_bar = False # we have a set value convert to True/False if check_state == QtCore.Qt.Checked: - self.song_bar = True + self.tool_bar = True - def onSongUpdateOnEditCheckBoxChanged(self, check_state): + def onUpdateOnEditCheckBoxChanged(self, check_state): self.update_edit = False # we have a set value convert to True/False if check_state == QtCore.Qt.Checked: self.update_edit = True - def onSongAddFromServiceCheckBoxChanged(self, check_state): + def onAddFromServiceCheckBoxChanged(self, check_state): self.update_load = False # we have a set value convert to True/False if check_state == QtCore.Qt.Checked: @@ -115,23 +115,23 @@ class SongsTab(SettingsTab): settings.beginGroup(self.settingsSection) self.song_search = settings.value( u'search as type', QtCore.QVariant(False)).toBool() - self.song_bar = settings.value( + self.tool_bar = settings.value( u'display songbar', QtCore.QVariant(True)).toBool() self.update_edit = settings.value( u'update service on edit', QtCore.QVariant(False)).toBool() self.update_load = settings.value( u'add song from service', QtCore.QVariant(True)).toBool() - self.SearchAsTypeCheckBox.setChecked(self.song_search) - self.SongBarActiveCheckBox.setChecked(self.song_bar) - self.SongUpdateOnEditCheckBox.setChecked(self.update_edit) - self.SongAddFromServiceCheckBox.setChecked(self.update_load) + self.searchAsTypeCheckBox.setChecked(self.song_search) + self.toolBarActiveCheckBox.setChecked(self.tool_bar) + self.updateOnEditCheckBox.setChecked(self.update_edit) + self.addFromServiceCheckBox.setChecked(self.update_load) settings.endGroup() def save(self): settings = QtCore.QSettings() settings.beginGroup(self.settingsSection) settings.setValue(u'search as type', QtCore.QVariant(self.song_search)) - settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar)) + settings.setValue(u'display songbar', QtCore.QVariant(self.tool_bar)) settings.setValue(u'update service on edit', QtCore.QVariant(self.update_edit)) settings.setValue(u'add song from service', diff --git a/resources/images/media_playback_next.png b/resources/images/media_playback_next.png new file mode 100644 index 000000000..0d22924ee Binary files /dev/null and b/resources/images/media_playback_next.png differ diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index dc444d445..1b833a4db 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -68,6 +68,7 @@ media_playback_start.png media_playback_stop.png media_playback_pause.png + media_playback_next.png openlp-logo-16x16.png diff --git a/scripts/resources.patch b/scripts/resources.patch index 3697a705a..8fa2edbe1 100644 --- a/scripts/resources.patch +++ b/scripts/resources.patch @@ -12,12 +12,12 @@ +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # -+# Copyright (c) 2008-2011 Raoul Snyman # -+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # -+# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # -+# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # -+# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # -+# Woldsund # ++# Copyright (c) 2008-2012 Raoul Snyman # ++# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan # ++# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # ++# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # ++# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # ++# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # diff --git a/scripts/translation_utils.py b/scripts/translation_utils.py index 812258fe2..b60d7d425 100755 --- a/scripts/translation_utils.py +++ b/scripts/translation_utils.py @@ -5,12 +5,12 @@ ############################################################################### # OpenLP - Open Source Lyrics Projection # # --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # -# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # -# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # -# Woldsund # +# Copyright (c) 2008-2012 Raoul Snyman # +# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # # --------------------------------------------------------------------------- # # This program is free software; you can redistribute it and/or modify it # # under the terms of the GNU General Public License as published by the Free #