diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index cb77f45ad..d597fcc66 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -641,7 +641,7 @@ class MediaManagerItem(QtGui.QWidget): if item: self.autoSelectId = item.data(QtCore.Qt.UserRole).toInt()[0] - def search(self, string): + def search(self, string, showError=True): """ Performs a plugin specific search for items containing ``string`` """ diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 9878e1f24..42e140381 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -325,7 +325,10 @@ class ServiceItem(object): if u'media_length' in header: self.media_length = header[u'media_length'] if u'background_audio' in header: - self.background_audio = header[u'background_audio'] + self.background_audio = [] + for filename in header[u'background_audio']: + # Give them real file paths + self.background_audio.append(os.path.join(path, filename)) self.theme_overwritten = header.get(u'theme_overwritten', False) if self.service_item_type == ServiceItemType.Text: for slide in serviceitem[u'serviceitem'][u'data']: diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 33ce2ad84..228809042 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -58,15 +58,15 @@ class MediaController(object): QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.video_state) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_playback_play'), self.video_play) + QtCore.SIGNAL(u'playbackPlay'), self.video_play) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_playback_pause'), self.video_pause) + QtCore.SIGNAL(u'playbackPause'), self.video_pause) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_playback_stop'), self.video_stop) + QtCore.SIGNAL(u'playbackStop'), self.video_stop) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'seek_slider'), self.video_seek) + QtCore.SIGNAL(u'seekSlider'), self.video_seek) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'volume_slider'), self.video_volume) + QtCore.SIGNAL(u'volumeSlider'), self.video_volume) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_hide'), self.video_hide) QtCore.QObject.connect(Receiver.get_receiver(), @@ -160,6 +160,11 @@ class MediaController(object): if self.curDisplayMediaPlayer[display] \ .state == MediaState.Playing: return + # no players are active anymore + for display in self.curDisplayMediaPlayer.keys(): + if self.curDisplayMediaPlayer[display] \ + .state != MediaState.Paused: + display.controller.seekSlider.setSliderPosition(0) self.timer.stop() def get_media_display_css(self): @@ -451,6 +456,7 @@ class MediaController(object): display.frame.evaluateJavaScript(u'show_blank("black");') self.curDisplayMediaPlayer[display].stop(display) self.curDisplayMediaPlayer[display].set_visible(display, False) + controller.seekSlider.setSliderPosition(0) def video_volume(self, msg): """ @@ -577,12 +583,13 @@ class MediaController(object): video_list.append(item) return video_list - def override_player(self, override_player): + def override_player(self, override_player_index): playerSettings = str(QtCore.QSettings().value(u'media/players', QtCore.QVariant(u'webkit')).toString()) usedPlayers = playerSettings.split(u',') - if override_player in usedPlayers: - self.overriddenPlayer = override_player + if override_player_index >= 0 and \ + override_player_index < len(usedPlayers): + self.overridenPlayer = usedPlayers[override_player_index] else: self.overriddenPlayer = '' diff --git a/openlp/core/ui/media/phononplayer.py b/openlp/core/ui/media/phononplayer.py index 5a9a5f67d..c366fe339 100644 --- a/openlp/core/ui/media/phononplayer.py +++ b/openlp/core/ui/media/phononplayer.py @@ -57,12 +57,14 @@ ADDITIONAL_EXT = { class PhononPlayer(MediaPlayer): """ - A specialised version of the MediaPlayer class, which provides a Phonon + A specialised version of the MediaPlayer class, which provides a Phonon display. """ def __init__(self, parent): MediaPlayer.__init__(self, parent, u'phonon') + self.original_name = u'Phonon' + self.display_name = u'&Phonon' self.parent = parent self.additional_extensions = ADDITIONAL_EXT mimetypes.init() @@ -190,6 +192,9 @@ class PhononPlayer(MediaPlayer): display.phononWidget.setVisible(status) def update_ui(self, display): + if display.mediaObject.state() == Phonon.PausedState and \ + self.state != MediaState.Paused: + self.stop(display) controller = display.controller if controller.media_info.end_time > 0: if display.mediaObject.currentTime() > \ diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index 416558b4a..70a5c1cb5 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -83,12 +83,14 @@ VIDEO_EXT = [ class VlcPlayer(MediaPlayer): """ - A specialised version of the MediaPlayer class, which provides a QtWebKit + A specialised version of the MediaPlayer class, which provides a VLC display. """ def __init__(self, parent): MediaPlayer.__init__(self, parent, u'vlc') + self.original_name = u'VLC' + self.display_name = u'&VLC' self.parent = parent self.canFolder = True self.audio_extensions_list = AUDIO_EXT @@ -120,7 +122,7 @@ class VlcPlayer(MediaPlayer): display.vlcMediaPlayer.set_hwnd(int(display.vlcWidget.winId())) elif sys.platform == "darwin": # for MacOS display.vlcMediaPlayer.set_agl(int(display.vlcWidget.winId())) - else: + else: # for Linux using the X Server display.vlcMediaPlayer.set_xwindow(int(display.vlcWidget.winId())) self.hasOwnWidget = True @@ -208,6 +210,8 @@ class VlcPlayer(MediaPlayer): display.vlcWidget.setVisible(status) def update_ui(self, display): + if display.vlcMedia.get_state() == vlc.State.Ended: + self.stop(display) controller = display.controller if controller.media_info.end_time > 0: if display.vlcMediaPlayer.get_time() > \ diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index 53f23b76e..e3713d7ae 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -126,7 +126,7 @@ VIDEO_JS = u""" vid.src = ''; vid2.src = ''; break; - case 'length': + case 'length': return vid.duration; case 'currentTime': return vid.currentTime; @@ -134,6 +134,8 @@ VIDEO_JS = u""" // doesnt work currently vid.currentTime = varVal; break; + case 'isEnded': + return vid.ended; case 'setVisible': vid.style.visibility = varVal; break; @@ -211,6 +213,8 @@ FLASH_JS = u""" case 'seek': // flashMovie.GotoFrame(varVal); break; + case 'isEnded': + return false;//TODO check flash end case 'setVisible': text.style.visibility = varVal; break; @@ -254,12 +258,14 @@ AUDIO_EXT = [ class WebkitPlayer(MediaPlayer): """ - A specialised version of the MediaPlayer class, which provides a QtWebKit + A specialised version of the MediaPlayer class, which provides a QtWebKit display. """ def __init__(self, parent): MediaPlayer.__init__(self, parent, u'webkit') + self.original_name = u'WebKit' + self.display_name = u'&WebKit' self.parent = parent self.canBackground = True self.audio_extensions_list = AUDIO_EXT @@ -354,7 +360,6 @@ class WebkitPlayer(MediaPlayer): display.frame.evaluateJavaScript(u'show_flash("stop");') else: display.frame.evaluateJavaScript(u'show_video("stop");') - controller.seekSlider.setSliderPosition(0) self.state = MediaState.Stopped def volume(self, display, vol): @@ -406,6 +411,9 @@ class WebkitPlayer(MediaPlayer): length = display.frame.evaluateJavaScript( \ u'show_flash("length");').toInt()[0] else: + if display.frame.evaluateJavaScript( \ + u'show_video("isEnded");').toString() == 'true': + self.stop(display) (currentTime, ok) = display.frame.evaluateJavaScript( \ u'show_video("currentTime");').toFloat() # check if conversion was ok and value is not 'NaN' diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 976ff6106..223229fd6 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -1025,12 +1025,13 @@ class BibleMediaItem(MediaManagerItem): return u'{su}[%s]{/su}' % verse_text return u'{su}%s{/su}' % verse_text - def search(self, string): + def search(self, string, showError): """ Search for some Bible verses (by reference). """ bible = unicode(self.quickVersionComboBox.currentText()) - search_results = self.plugin.manager.get_verses(bible, string, False) + search_results = self.plugin.manager.get_verses(bible, string, False, + showError) if search_results: versetext = u' '.join([verse.text for verse in search_results]) return [[string, versetext]] diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 443c95f56..cbb5a9fc4 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -267,7 +267,7 @@ class CustomMediaItem(MediaManagerItem): self.searchTextEdit.clear() self.onSearchTextButtonClick() - def search(self, string): + def search(self, string, showError): search_results = self.manager.get_all_objects(CustomSlide, or_(func.lower(CustomSlide.title).like(u'%' + string.lower() + u'%'), diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 80d6360a8..75ace5d6f 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -234,7 +234,7 @@ class ImageMediaItem(MediaManagerItem): 'There was a problem replacing your background, ' 'the image file "%s" no longer exists.')) % filename) - def search(self, string): + def search(self, string, showError): files = SettingsManager.load_list(self.settingsSection, u'images') results = [] string = string.lower() diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 76dbd0fe9..60518a09e 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -142,8 +142,8 @@ class MediaMediaItem(MediaManagerItem): self.overridePlayerChanged) def overridePlayerChanged(self, index): - Receiver.send_message(u'media_override_player', \ - u'%s' % self.displayTypeComboBox.currentText()) + # index - 1, because the first item is "Automatic". + Receiver.send_message(u'media_override_player', index - 1) def onResetClick(self): """ @@ -249,9 +249,10 @@ class MediaMediaItem(MediaManagerItem): playerSettings = str(QtCore.QSettings().value(u'media/players', QtCore.QVariant(u'webkit')).toString()) usedPlayers = playerSettings.split(u',') - for title in usedPlayers: + mediaPlayers = self.plugin.mediaController.mediaPlayers + for player in usedPlayers: # load the drop down selection - self.displayTypeComboBox.addItem(title) + self.displayTypeComboBox.addItem(mediaPlayers[player].original_name) if self.displayTypeComboBox.count() > 1: self.displayTypeComboBox.insertItem(0, self.automatic) self.displayTypeComboBox.setCurrentIndex(0) @@ -309,7 +310,7 @@ class MediaMediaItem(MediaManagerItem): media = filter(lambda x: os.path.splitext(x)[1] in ext, media) return media - def search(self, string): + def search(self, string, showError): files = SettingsManager.load_list(self.settingsSection, u'media') results = [] string = string.lower() diff --git a/openlp/plugins/media/lib/mediatab.py b/openlp/plugins/media/lib/mediatab.py index c096dada9..a93dcf5a9 100644 --- a/openlp/plugins/media/lib/mediatab.py +++ b/openlp/plugins/media/lib/mediatab.py @@ -30,6 +30,14 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, translate, Receiver from openlp.core.lib.ui import UiStrings, create_up_down_push_button_set +class MediaQCheckBox(QtGui.QCheckBox): + """ + MediaQCheckBox adds an extra property, playerName to the QCheckBox class. + """ + def setPlayerName(self, name): + self.playerName = name + + class MediaTab(SettingsTab): """ MediaTab is the Media settings tab in the settings dialog. @@ -49,7 +57,7 @@ class MediaTab(SettingsTab): self.playerCheckBoxes = {} for key, player in self.mediaPlayers.iteritems(): player = self.mediaPlayers[key] - checkbox = QtGui.QCheckBox(self.mediaPlayerGroupBox) + checkbox = MediaQCheckBox(self.mediaPlayerGroupBox) checkbox.setEnabled(player.available) checkbox.setObjectName(player.name + u'CheckBox') self.playerCheckBoxes[player.name] = checkbox @@ -109,12 +117,13 @@ class MediaTab(SettingsTab): for key in self.mediaPlayers: player = self.mediaPlayers[key] checkbox = self.playerCheckBoxes[player.name] + checkbox.setPlayerName(player.name) if player.available: - checkbox.setText(player.name) + checkbox.setText(player.display_name) else: checkbox.setText( unicode(translate('MediaPlugin.MediaTab', - '%s (unavailable)')) % player.name) + '%s (unavailable)')) % player.display_name) self.playerOrderGroupBox.setTitle( translate('MediaPlugin.MediaTab', 'Player Order')) self.advancedGroupBox.setTitle(UiStrings().Advanced) @@ -123,7 +132,7 @@ class MediaTab(SettingsTab): 'Allow media player to be overridden')) def onPlayerCheckBoxChanged(self, check_state): - player = self.sender().text() + player = self.sender().playerName if check_state == QtCore.Qt.Checked: if player not in self.usedPlayers: self.usedPlayers.append(player) @@ -141,7 +150,8 @@ class MediaTab(SettingsTab): self.playerCheckBoxes[u'%s' % player].setEnabled(False) else: self.playerCheckBoxes[u'%s' % player].setEnabled(True) - self.playerOrderlistWidget.addItem(player) + self.playerOrderlistWidget.addItem( + self.mediaPlayers[unicode(player)].original_name) def onUpButtonClicked(self): row = self.playerOrderlistWidget.currentRow() @@ -162,9 +172,6 @@ class MediaTab(SettingsTab): self.usedPlayers.move(row, row + 1) def load(self): - if self.savedUsedPlayers: - self.usedPlayers = self.savedUsedPlayers - self.savedUsedPlayers = None self.usedPlayers = QtCore.QSettings().value( self.settingsSection + u'/players', QtCore.QVariant(u'webkit')).toString().split(u',') diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 03fdadb1b..3f9c81fc7 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -322,7 +322,7 @@ class PresentationMediaItem(MediaManagerItem): return controller return None - def search(self, string): + def search(self, string, showError): files = SettingsManager.load_list( self.settingsSection, u'presentations') results = [] diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index bdef88720..8daa1c7b0 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -522,7 +522,7 @@ class HttpConnection(object): plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type) if plugin.status == PluginStatus.Active and \ plugin.mediaItem and plugin.mediaItem.hasSearch: - results = plugin.mediaItem.search(text) + results = plugin.mediaItem.search(text, False) else: results = [] return HttpResponse( diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 448e4bc37..6b99f9a16 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -159,6 +159,12 @@ class CCLIFileImport(SongImport): song_author = u'' song_topics = u'' for line in textList: + if line.startswith(u'[S '): + ccli, line = line.split(u']', 1) + if ccli.startswith(u'[S A'): + self.ccliNumber = ccli[4:].strip() + else: + self.ccliNumber = ccli[3:].strip() if line.startswith(u'Title='): self.title = line[6:].strip() elif line.startswith(u'Author='): @@ -166,9 +172,7 @@ class CCLIFileImport(SongImport): elif line.startswith(u'Copyright='): self.copyright = line[10:].strip() elif line.startswith(u'Themes='): - song_topics = line[7:].strip() - elif line.startswith(u'[S A'): - self.ccliNumber = line[4:-3].strip() + song_topics = line[7:].strip().replace(u' | ', u'/t') elif line.startswith(u'Fields='): # Fields contain single line indicating verse, chorus, etc, # /t delimited, same as with words field. store seperately @@ -193,6 +197,7 @@ class CCLIFileImport(SongImport): check_first_verse_line = True verse_text = unicode(words_list[counter]) verse_text = verse_text.replace(u'/n', u'\n') + verse_text = verse_text.replace(u' | ', u'\n') verse_lines = verse_text.split(u'\n', 1) if check_first_verse_line: if verse_lines[0].startswith(u'(PRE-CHORUS'): @@ -243,7 +248,7 @@ class CCLIFileImport(SongImport): Song CCLI number # e.g. CCLI Number (e.g.CCLI-Liednummer: 2672885) - Song copyright + Song copyright (if it begins ©, otherwise after authors) # e.g. © 1999 Integrity's Hosanna! Music | LenSongs Publishing Song authors # e.g. Lenny LeBlanc | Paul Baloche Licencing info @@ -322,11 +327,17 @@ class CCLIFileImport(SongImport): #line_number=2, copyright if line_number == 2: line_number += 1 - self.copyright = clean_line + if clean_line.startswith(u'©'): + self.copyright = clean_line + else: + song_author = clean_line #n=3, authors elif line_number == 3: line_number += 1 - song_author = clean_line + if song_author: + self.copyright = clean_line + else: + song_author = clean_line #line_number=4, comments lines before last line elif line_number == 4 and not clean_line.startswith(u'CCL'): self.comments += clean_line diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 34a54dee4..8ad9b33ab 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -586,7 +586,7 @@ class SongMediaItem(MediaManagerItem): Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (editId, item._uuid, temporary)) - def search(self, string): + def search(self, string, showError): """ Search for some songs """