From 7fdeed6b1a64c2cdef5d8112415db7c89a07c940 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 19 Mar 2010 08:10:00 +0000 Subject: [PATCH 01/18] changes --- openlp/plugins/alerts/forms/alerteditform.py | 2 +- openlp/plugins/songs/forms/editverseform.py | 2 +- .../plugins/songs/forms/songmaintenanceform.py | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/alerts/forms/alerteditform.py b/openlp/plugins/alerts/forms/alerteditform.py index 62c129508..a88eff4f3 100644 --- a/openlp/plugins/alerts/forms/alerteditform.py +++ b/openlp/plugins/alerts/forms/alerteditform.py @@ -85,7 +85,7 @@ class AlertEditForm(QtGui.QDialog, Ui_AlertEditDialog): if self.AlertLineEdit.text(): QtGui.QMessageBox.information(self, self.trUtf8('Item selected to Edit'), - self.trUtf8('Please Save or Clear seletced item')) + self.trUtf8('Please save or clear selected item')) else: self.EditButton.setEnabled(True) self.DeleteButton.setEnabled(True) diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index cee84aae5..99dfd6d69 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -77,7 +77,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): def setVerse(self, text, verseCount=0, single=False, tag=u'Verse:1'): posVerse = 0 posSub = 0 - if len(text) == 0: + if len(text) == 0 and not single: text = u'---[Verse:1]---\n' if single: id = tag.split(u':') diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py index 4d1d39cce..ffef22dd6 100644 --- a/openlp/plugins/songs/forms/songmaintenanceform.py +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -162,7 +162,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): else: QtGui.QMessageBox.critical( self, self.trUtf8('Error'), - self.trUtf8('Couldn\'t add your book!'), + self.trUtf8('Couldn\'t add your book'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) def onAuthorEditButtonClick(self): @@ -182,7 +182,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): else: QtGui.QMessageBox.critical( self, self.trUtf8('Error'), - self.trUtf8('Couldn\'t save your author!'), + self.trUtf8('Couldn\'t save your author'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) def onTopicEditButtonClick(self): @@ -197,7 +197,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): else: QtGui.QMessageBox.critical( self, self.trUtf8('Error'), - self.trUtf8('Couldn\'t save your topic!'), + self.trUtf8('Couldn\'t save your topic'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) def onBookEditButtonClick(self): @@ -214,7 +214,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): else: QtGui.QMessageBox.critical( self, self.trUtf8('Error'), - self.trUtf8('Couldn\'t save your book!'), + self.trUtf8('Couldn\'t save your book'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) def onAuthorDeleteButtonClick(self): @@ -227,7 +227,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.trUtf8('Delete Author'), self.trUtf8('Are you sure you want to delete the selected author?'), self.trUtf8('This author can\'t be deleted, they are currently ' - 'assigned to at least one song!'), + 'assigned to at least one song'), self.trUtf8('No author selected!')) def onTopicDeleteButtonClick(self): @@ -240,7 +240,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.trUtf8('Delete Topic'), self.trUtf8('Are you sure you want to delete the selected topic?'), self.trUtf8('This topic can\'t be deleted, it is currently ' - 'assigned to at least one song!'), + 'assigned to at least one song'), self.trUtf8('No topic selected!')) def onBookDeleteButtonClick(self): @@ -253,5 +253,5 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.trUtf8('Delete Book'), self.trUtf8('Are you sure you want to delete the selected book?'), self.trUtf8('This book can\'t be deleted, it is currently ' - 'assigned to at least one song!'), - self.trUtf8('No book selected!')) \ No newline at end of file + 'assigned to at least one song'), + self.trUtf8('No book selected!')) From 5c90f4944c6b2f470ed8067b70d5e834b5e323fc Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 7 Apr 2010 20:09:13 +0100 Subject: [PATCH 02/18] remove display background --- openlp/core/ui/maindisplay.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index e59ce2060..fbfe5dfb4 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -94,6 +94,8 @@ class MainDisplay(DisplayWidget): DisplayWidget.__init__(self, None) self.parent = parent self.setWindowTitle(u'OpenLP Display') + self.setAttribute(QtCore.Qt.WA_TranslucentBackground) + self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.screens = screens self.mediaObject = Phonon.MediaObject(self) self.video = Phonon.VideoWidget() @@ -226,6 +228,7 @@ class MainDisplay(DisplayWidget): ``frame`` Image frame to be rendered """ + self.display_image.setPixmap(self.transparent) if not self.displayBlank: if transition: if self.frame is not None: From 150eaf7e563ce3ad03bdaac25ea7af902701592c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 8 Apr 2010 08:37:01 +0100 Subject: [PATCH 03/18] Video changes and bug fixes part1 --- openlp/core/ui/maindisplay.py | 111 ++++++++++++++------- openlp/core/ui/slidecontroller.py | 4 +- openlp/plugins/alerts/forms/alertstab.py | 2 + openlp/plugins/alerts/lib/alertsmanager.py | 9 +- 4 files changed, 84 insertions(+), 42 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 397a1f2ad..08cd97b10 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -93,17 +93,12 @@ class MainDisplay(DisplayWidget): """ log.debug(u'Initilisation started') DisplayWidget.__init__(self, None) + self.videoDisplay = VideoDisplay(parent, screens) self.parent = parent self.setWindowTitle(u'OpenLP Display') self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.screens = screens - self.mediaObject = Phonon.MediaObject(self) - self.video = Phonon.VideoWidget() - self.video.setVisible(False) - self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) - Phonon.createPath(self.mediaObject, self.video) - Phonon.createPath(self.mediaObject, self.audio) self.display_image = QtGui.QLabel(self) self.display_image.setScaledContents(True) self.display_text = QtGui.QLabel(self) @@ -122,18 +117,8 @@ class MainDisplay(DisplayWidget): QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_slide_show'), self.showDisplay) - QtCore.QObject.connect(self.mediaObject, - QtCore.SIGNAL(u'finished()'), self.onMediaFinish) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_start'), self.onMediaQueue) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_play'), self.onMediaPlay) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_pause'), self.onMediaPause) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_stop'), self.onMediaStop) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_config'), self.setup) def setup(self): """ @@ -146,7 +131,6 @@ class MainDisplay(DisplayWidget): #Sort out screen locations and sizes self.setGeometry(self.screen[u'size']) self.display_alert.setGeometry(self.screen[u'size']) - self.video.setGeometry(self.screen[u'size']) self.display_image.resize(self.screen[u'size'].width(), self.screen[u'size'].height()) self.display_text.resize(self.screen[u'size'].width(), @@ -179,6 +163,7 @@ class MainDisplay(DisplayWidget): self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) self.display_alert.setPixmap(self.transparent) + self.display_text.setPixmap(self.transparent) self.frameView(self.transparent) # To display or not to display? if not self.screen[u'primary']: @@ -187,8 +172,11 @@ class MainDisplay(DisplayWidget): else: self.setVisible(False) self.primary = True + self.videoDisplay.setup() + self.raise_() def resetDisplay(self): + log.debug(u'resetDisplay') Receiver.send_message(u'stop_display_loop') if self.primary: self.setVisible(False) @@ -196,10 +184,12 @@ class MainDisplay(DisplayWidget): self.showFullScreen() def hideDisplay(self): + log.debug(u'hideDisplay') self.mediaLoaded = True self.setVisible(False) def showDisplay(self): + log.debug(u'showDisplay') self.mediaLoaded = False if not self.primary: self.setVisible(True) @@ -207,17 +197,20 @@ class MainDisplay(DisplayWidget): Receiver.send_message(u'flush_alert') def addImageWithText(self, frame): + log.debug(u'addImageWithText') frame = resize_image(frame, self.screen[u'size'].width(), self.screen[u'size'].height() ) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) def setAlertSize(self, top, height): + log.debug(u'setAlertSize') self.display_alert.setGeometry( QtCore.QRect(0, top, self.screen[u'size'].width(), height)) def addAlertImage(self, frame, blank=False): + log.debug(u'addAlertImage') if blank: self.display_alert.setPixmap(self.transparent) else: @@ -230,7 +223,6 @@ class MainDisplay(DisplayWidget): ``frame`` Image frame to be rendered """ - self.display_image.setPixmap(self.transparent) log.debug(u'frameView %d' % (self.displayBlank)) if not self.displayBlank: if transition: @@ -280,9 +272,63 @@ class MainDisplay(DisplayWidget): def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) - self.display_image.close() - self.display_text.close() - self.display_alert.close() + self.display_image.setPixmap(self.transparent) + self.display_alert.setPixmap(self.transparent) + self.display_text.setPixmap(self.transparent) + +class VideoDisplay(QtGui.QWidget): + """ + This is the form that is used to display videos on the projector. + """ + log.info(u'VideoDisplay Loaded') + + def __init__(self, parent, screens): + """ + The constructor for the display form. + + ``parent`` + The parent widget. + + ``screens`` + The list of screens. + """ + log.debug(u'VideoDisplay Initilisation started') + QtGui.QWidget.__init__(self, None) + self.setWindowTitle(u'OpenLP Video Display') + self.parent = parent + self.screens = screens + self.mediaObject = Phonon.MediaObject(self) + self.video = Phonon.VideoWidget() + self.video.setVisible(False) + self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) + Phonon.createPath(self.mediaObject, self.video) + Phonon.createPath(self.mediaObject, self.audio) + self.firstTime = True + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_start'), self.onMediaQueue) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_play'), self.onMediaPlay) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_pause'), self.onMediaPause) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_stop'), self.onMediaStop) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'update_config'), self.setup) + + def setup(self): + """ + Sets up the screen on a particular screen. + """ + log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens, + self.screens.monitor_number)) + self.setVisible(False) + self.screen = self.screens.current + #Sort out screen locations and sizes + self.setGeometry(self.screen[u'size']) + self.video.setGeometry(self.screen[u'size']) + + def onMediaQueue(self, message): + log.debug(u'VideoDisplay Queue new media message %s' % message) file = os.path.join(message[1], message[2]) if self.firstTime: self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) @@ -292,36 +338,27 @@ class MainDisplay(DisplayWidget): self.onMediaPlay() def onMediaPlay(self): - log.debug(u'Play the new media, Live ') - if not self.mediaLoaded and not self.displayBlank: - self.blankDisplay() - self.display_frame = self.blankFrame + log.debug(u'VideoDisplay Play the new media, Live ') self.firstTime = True - self.mediaLoaded = True - self.display_image.hide() - self.display_text.hide() - self.display_alert.hide() + self.setWindowState(QtCore.Qt.WindowMinimized) self.video.setFullScreen(True) - self.video.setVisible(True) self.mediaObject.play() self.setVisible(True) - self.hide() + self.lower() def onMediaPause(self): - log.debug(u'Media paused by user') + log.debug(u'VideoDisplay Media paused by user') self.mediaObject.pause() def onMediaStop(self): - log.debug(u'Media stopped by user') + log.debug(u'VideoDisplay Media stopped by user') self.mediaObject.stop() self.onMediaFinish() def onMediaFinish(self): - log.debug(u'Reached end of media playlist') + log.debug(u'VideoDisplay Reached end of media playlist') self.mediaObject.stop() self.mediaObject.clearQueue() self.mediaLoaded = False self.video.setVisible(False) - self.display_text.show() - self.display_image.show() - self.blankDisplay(False, False) + self.setVisible(False) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 35f520c9e..9b5e4d319 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -387,7 +387,7 @@ class SlideController(QtGui.QWidget): elif item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) - self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio) + self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) def enablePreviewToolBar(self, item): """ @@ -585,7 +585,7 @@ class SlideController(QtGui.QWidget): """ log.debug(u'onHideDisplay %d' % force) if force: - self.themeButton.setChecked(True) + self.hideButton.setChecked(True) if self.hideButton.isChecked(): self.parent.mainDisplay.hideDisplay() else: diff --git a/openlp/plugins/alerts/forms/alertstab.py b/openlp/plugins/alerts/forms/alertstab.py index 9c45393af..fe1b7cb6d 100644 --- a/openlp/plugins/alerts/forms/alertstab.py +++ b/openlp/plugins/alerts/forms/alertstab.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, str_to_bool from openlp.plugins.alerts.lib.models import AlertItem +from openlp.plugins.alerts.lib import alertsmanager class AlertsTab(SettingsTab): """ @@ -35,6 +36,7 @@ class AlertsTab(SettingsTab): def __init__(self, parent, section=None): self.parent = parent self.manager = parent.manager + self.alertsmanager = parent.alertsmanager SettingsTab.__init__(self, parent.name, section) def setupUi(self): diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 3b61125f4..bd78ad428 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -21,7 +21,7 @@ # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### +##################################################################alertsmanager.py############# import logging @@ -40,6 +40,7 @@ class AlertsManager(QtCore.QObject): def __init__(self, parent): QtCore.QObject.__init__(self) self.parent = parent + self.screen = None self.timer_id = 0 self.alertList = [] QtCore.QObject.connect(Receiver.get_receiver(), @@ -53,8 +54,8 @@ class AlertsManager(QtCore.QObject): def screenChanged(self): log.debug(u'screen changed') - self.screen = self.parent.maindisplay.screen self.alertTab = self.parent.alertsTab + self.screen = self.parent.maindisplay.screens.current self.font = QtGui.QFont() self.font.setFamily(self.alertTab.font_face) self.font.setBold(True) @@ -76,9 +77,11 @@ class AlertsManager(QtCore.QObject): display text """ log.debug(u'display alert called %s' % text) + if not self.screen: + self.screenChanged() self.parent.maindisplay.parent.StatusBar.showMessage(u'') self.alertList.append(text) - if self.timer_id != 0 or self.parent.maindisplay.mediaLoaded: + if self.timer_id != 0: # or self.parent.maindisplay.mediaLoaded: self.parent.maindisplay.parent.StatusBar.showMessage(\ self.trUtf8(u'Alert message created and delayed')) return From bc4f31ef93e72ec9d41a7ae4dd85d47befc996e4 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 8 Apr 2010 10:15:40 +0100 Subject: [PATCH 04/18] More fixes and new features --- openlp/core/lib/serviceitem.py | 1 + openlp/core/ui/maindisplay.py | 47 ++++++++++++++++++++-- openlp/core/ui/slidecontroller.py | 18 ++++++--- openlp/plugins/alerts/lib/alertsmanager.py | 4 ++ 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 7bb58af2b..8601e818e 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -47,6 +47,7 @@ class ItemCapabilities(object): AllowsEdit = 2 AllowsMaintain = 3 RequiresMedia = 4 + AllowsLoop = 5 class ServiceItem(object): diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 08cd97b10..b52d50502 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -276,7 +276,48 @@ class MainDisplay(DisplayWidget): self.display_alert.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent) -class VideoDisplay(QtGui.QWidget): +class VideoWidget(QtGui.QWidget): + """ + Customised version of QTableWidget which can respond to keyboard + events. + """ + log.info(u'MainDisplay loaded') + + def __init__(self, parent=None, name=None): + QtGui.QWidget.__init__(self, None) + self.parent = parent + self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', + QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', + QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', + QtCore.Qt.Key_0: 'servicemanager_next_item', + QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} + + def keyPressEvent(self, event): + if type(event) == QtGui.QKeyEvent: + #here accept the event and do something + if event.key() == QtCore.Qt.Key_Up: + Receiver.send_message(u'live_slidecontroller_previous') + event.accept() + elif event.key() == QtCore.Qt.Key_Down: + Receiver.send_message(u'live_slidecontroller_next') + event.accept() + elif event.key() == QtCore.Qt.Key_PageUp: + Receiver.send_message(u'live_slidecontroller_first') + event.accept() + elif event.key() == QtCore.Qt.Key_PageDown: + Receiver.send_message(u'live_slidecontroller_last') + event.accept() + elif event.key() in self.hotkey_map: + Receiver.send_message(self.hotkey_map[event.key()]) + event.accept() + elif event.key() == QtCore.Qt.Key_Escape: + self.resetDisplay() + event.accept() + event.ignore() + else: + event.ignore() + +class VideoDisplay(VideoWidget): """ This is the form that is used to display videos on the projector. """ @@ -293,7 +334,7 @@ class VideoDisplay(QtGui.QWidget): The list of screens. """ log.debug(u'VideoDisplay Initilisation started') - QtGui.QWidget.__init__(self, None) + VideoWidget.__init__(self, parent) self.setWindowTitle(u'OpenLP Video Display') self.parent = parent self.screens = screens @@ -331,7 +372,7 @@ class VideoDisplay(QtGui.QWidget): log.debug(u'VideoDisplay Queue new media message %s' % message) file = os.path.join(message[1], message[2]) if self.firstTime: - self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self.firstTime = False else: self.mediaObject.enqueue(Phonon.MediaSource(file)) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 9b5e4d319..db4c1a8ec 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -96,7 +96,7 @@ class SlideController(QtGui.QWidget): self.isLive = isLive self.parent = parent self.songsconfig = PluginConfig(u'Songs') - self.image_list = [ + self.loop_list = [ u'Start Loop', u'Stop Loop', u'Loop Separator', @@ -233,6 +233,12 @@ class SlideController(QtGui.QWidget): self.Mediabar.addToolbarButton( u'Media Stop', u':/slides/media_playback_stop.png', self.trUtf8('Start playing media'), self.onMediaStop) + if not self.isLive: + self.seekSlider = Phonon.SeekSlider() + self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) + self.seekSlider.setObjectName(u'seekSlider') + self.Mediabar.addToolbarWidget( + u'Seek Slider', self.seekSlider) self.volumeSlider = Phonon.VolumeSlider() self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) self.volumeSlider.setObjectName(u'volumeSlider') @@ -299,7 +305,7 @@ class SlideController(QtGui.QWidget): QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) Receiver.send_message(u'request_spin_delay') if isLive: - self.Toolbar.makeWidgetsInvisible(self.image_list) + self.Toolbar.makeWidgetsInvisible(self.loop_list) else: self.Toolbar.makeWidgetsInvisible(self.song_edit_list) self.Mediabar.setVisible(False) @@ -374,16 +380,16 @@ class SlideController(QtGui.QWidget): self.Toolbar.setVisible(True) self.Mediabar.setVisible(False) self.Toolbar.makeWidgetsInvisible([u'Song Menu']) - self.Toolbar.makeWidgetsInvisible(self.image_list) + self.Toolbar.makeWidgetsInvisible(self.loop_list) if item.is_text(): - self.Toolbar.makeWidgetsInvisible(self.image_list) + self.Toolbar.makeWidgetsInvisible(self.loop_list) if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \ and len(self.slideList) > 0: self.Toolbar.makeWidgetsVisible([u'Song Menu']) elif item.is_image(): #Not sensible to allow loops with 1 frame if len(item.get_frames()) > 1: - self.Toolbar.makeWidgetsVisible(self.image_list) + self.Toolbar.makeWidgetsVisible(self.loop_list) elif item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) @@ -766,6 +772,8 @@ class SlideController(QtGui.QWidget): self.mediaObject.clearQueue() file = os.path.join(item.get_frame_path(), item.get_frame_title()) self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + self.seekSlider.setMediaObject(self.mediaObject) + self.seekSlider.show() self.onMediaPlay() def onMediaPause(self): diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index bd78ad428..dde8d0d4c 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -82,6 +82,7 @@ class AlertsManager(QtCore.QObject): self.parent.maindisplay.parent.StatusBar.showMessage(u'') self.alertList.append(text) if self.timer_id != 0: # or self.parent.maindisplay.mediaLoaded: + print self.timer_id, self.alertList, len(self.alertList) self.parent.maindisplay.parent.StatusBar.showMessage(\ self.trUtf8(u'Alert message created and delayed')) return @@ -91,7 +92,9 @@ class AlertsManager(QtCore.QObject): log.debug(u'Generate Alert called') if len(self.alertList) == 0: return + print len(self.alertList) text = self.alertList.pop(0) + print text alertTab = self.parent.alertsTab alertframe = \ QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight) @@ -113,6 +116,7 @@ class AlertsManager(QtCore.QObject): self.parent.maindisplay.addAlertImage(alertframe) # check to see if we have a timer running if self.timer_id == 0: + print "timer tripped" self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) def timerEvent(self, event): From b9630907a88d0f72356a475df483fb0fdeb25593 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 8 Apr 2010 17:00:04 +0100 Subject: [PATCH 05/18] Fixes --- openlp/core/ui/maindisplay.py | 15 +++++++-------- openlp/core/ui/slidecontroller.py | 7 +++---- openlp/plugins/alerts/lib/alertsmanager.py | 5 +---- openlp/plugins/bibles/lib/mediaitem.py | 1 + openlp/plugins/custom/lib/mediaitem.py | 3 ++- openlp/plugins/images/lib/mediaitem.py | 3 ++- openlp/plugins/songs/lib/mediaitem.py | 3 ++- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index b52d50502..1a8aa2563 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -110,7 +110,6 @@ class MainDisplay(DisplayWidget): self.blankFrame = None self.frame = None self.firstTime = True - self.mediaLoaded = False self.hasTransition = False self.mediaBackground = False QtCore.QObject.connect(Receiver.get_receiver(), @@ -185,12 +184,12 @@ class MainDisplay(DisplayWidget): def hideDisplay(self): log.debug(u'hideDisplay') - self.mediaLoaded = True - self.setVisible(False) + self.display_image.setPixmap(self.transparent) + self.display_alert.setPixmap(self.transparent) + self.display_text.setPixmap(self.transparent) def showDisplay(self): log.debug(u'showDisplay') - self.mediaLoaded = False if not self.primary: self.setVisible(True) self.showFullScreen() @@ -272,9 +271,8 @@ class MainDisplay(DisplayWidget): def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) - self.display_image.setPixmap(self.transparent) - self.display_alert.setPixmap(self.transparent) - self.display_text.setPixmap(self.transparent) + self.hideDisplay() + self.activateWindow() class VideoWidget(QtGui.QWidget): """ @@ -338,6 +336,8 @@ class VideoDisplay(VideoWidget): self.setWindowTitle(u'OpenLP Video Display') self.parent = parent self.screens = screens + self.setAttribute(QtCore.Qt.WA_TranslucentBackground) + self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.mediaObject = Phonon.MediaObject(self) self.video = Phonon.VideoWidget() self.video.setVisible(False) @@ -400,6 +400,5 @@ class VideoDisplay(VideoWidget): log.debug(u'VideoDisplay Reached end of media playlist') self.mediaObject.stop() self.mediaObject.clearQueue() - self.mediaLoaded = False self.video.setVisible(False) self.setVisible(False) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index db4c1a8ec..1f72ddfe1 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -386,11 +386,10 @@ class SlideController(QtGui.QWidget): if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \ and len(self.slideList) > 0: self.Toolbar.makeWidgetsVisible([u'Song Menu']) - elif item.is_image(): - #Not sensible to allow loops with 1 frame - if len(item.get_frames()) > 1: + if item.is_capable(ItemCapabilities.AllowsLoop) and \ + len(item.get_frames()) > 1: self.Toolbar.makeWidgetsVisible(self.loop_list) - elif item.is_media(): + if item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index dde8d0d4c..6c674f986 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -81,8 +81,7 @@ class AlertsManager(QtCore.QObject): self.screenChanged() self.parent.maindisplay.parent.StatusBar.showMessage(u'') self.alertList.append(text) - if self.timer_id != 0: # or self.parent.maindisplay.mediaLoaded: - print self.timer_id, self.alertList, len(self.alertList) + if self.timer_id != 0: self.parent.maindisplay.parent.StatusBar.showMessage(\ self.trUtf8(u'Alert message created and delayed')) return @@ -92,9 +91,7 @@ class AlertsManager(QtCore.QObject): log.debug(u'Generate Alert called') if len(self.alertList) == 0: return - print len(self.alertList) text = self.alertList.pop(0) - print text alertTab = self.parent.alertsTab alertframe = \ QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 80c81f3e7..764399fab 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -449,6 +449,7 @@ class BibleMediaItem(MediaManagerItem): raw_footer = [] bible_text = u'' service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) #If we want to use a 2nd translation / version bible2 = u'' if self.SearchTabWidget.currentIndex() == 0: diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 3c68b6d3d..3d55db719 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -149,6 +149,7 @@ class CustomMediaItem(MediaManagerItem): item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) customSlide = self.parent.custommanager.get_custom(item_id) title = customSlide.title credit = customSlide.credits @@ -169,4 +170,4 @@ class CustomMediaItem(MediaManagerItem): else: raw_footer.append(u'') service_item.raw_footer = raw_footer - return True \ No newline at end of file + return True diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 4d56a7d32..6fbf66022 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -139,6 +139,7 @@ class ImageMediaItem(MediaManagerItem): service_item.title = self.trUtf8('Image(s)') service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) for item in items: bitem = self.ListView.item(item.row()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) @@ -162,4 +163,4 @@ class ImageMediaItem(MediaManagerItem): self.parent.maindisplay.addImageWithText(frame) def onPreviewClick(self): - MediaManagerItem.onPreviewClick(self) \ No newline at end of file + MediaManagerItem.onPreviewClick(self) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index ad63cd783..9b81540e6 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -306,6 +306,7 @@ class SongMediaItem(MediaManagerItem): item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) song = self.parent.songmanager.get_song(item_id) service_item.theme = song.theme_name service_item.editId = item_id @@ -361,4 +362,4 @@ class SongMediaItem(MediaManagerItem): service_item.audit = [ song.title, author_audit, song.copyright, song.ccli_number ] - return True \ No newline at end of file + return True From 141a9b4358f3a66d320d63f62750e6123a7f9225 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 8 Apr 2010 20:46:50 +0100 Subject: [PATCH 06/18] Clean up custom plugin dialog --- .../plugins/custom/forms/editcustomdialog.py | 37 +++++++----- openlp/plugins/custom/forms/editcustomform.py | 18 +++++- resources/forms/editcustomdialog.ui | 59 ++++++++++++++++--- 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/openlp/plugins/custom/forms/editcustomdialog.py b/openlp/plugins/custom/forms/editcustomdialog.py index 35af9ce8d..5f3fe7614 100644 --- a/openlp/plugins/custom/forms/editcustomdialog.py +++ b/openlp/plugins/custom/forms/editcustomdialog.py @@ -24,13 +24,14 @@ ############################################################################### from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon class Ui_customEditDialog(object): def setupUi(self, customEditDialog): customEditDialog.setObjectName(u'customEditDialog') customEditDialog.resize(590, 541) - icon = build_icon(u':/icon/openlp.org-icon-32.bmp') + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) customEditDialog.setWindowIcon(icon) self.gridLayout = QtGui.QGridLayout(customEditDialog) self.gridLayout.setObjectName(u'gridLayout') @@ -52,15 +53,19 @@ class Ui_customEditDialog(object): self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(u'verticalLayout') self.UpButton = QtGui.QPushButton(customEditDialog) - icon1 = build_icon(u':/services/service_up.png') + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(u':/services/service_up.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) self.UpButton.setIcon(icon1) self.UpButton.setObjectName(u'UpButton') self.verticalLayout.addWidget(self.UpButton) - spacerItem = QtGui.QSpacerItem(20, 128, - QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum, + QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.DownButton = QtGui.QPushButton(customEditDialog) - icon2 = build_icon(u':/services/service_down.png') + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(u':/services/service_down.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) self.DownButton.setIcon(icon2) self.DownButton.setObjectName(u'DownButton') self.verticalLayout.addWidget(self.DownButton) @@ -97,6 +102,9 @@ class Ui_customEditDialog(object): self.ClearButton = QtGui.QPushButton(self.ButtonWidge) self.ClearButton.setObjectName(u'ClearButton') self.verticalLayout_2.addWidget(self.ClearButton) + self.SplitButton = QtGui.QPushButton(self.ButtonWidge) + self.SplitButton.setObjectName(u'SplitButton') + self.verticalLayout_2.addWidget(self.SplitButton) spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem1) @@ -121,16 +129,15 @@ class Ui_customEditDialog(object): self.horizontalLayout_2.addWidget(self.CreditEdit) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save) self.buttonBox.setObjectName(u'buttonBox') self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1) self.retranslateUi(customEditDialog) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), customEditDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), + customEditDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), + customEditDialog.closePressed) QtCore.QMetaObject.connectSlotsByName(customEditDialog) customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit) customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton) @@ -143,12 +150,11 @@ class Ui_customEditDialog(object): customEditDialog.setTabOrder(self.CreditEdit, self.UpButton) customEditDialog.setTabOrder(self.UpButton, self.DownButton) customEditDialog.setTabOrder(self.DownButton, self.ThemeComboBox) - customEditDialog.setTabOrder(self.ThemeComboBox, self.buttonBox) def retranslateUi(self, customEditDialog): + customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides')) self.UpButton.setToolTip(self.trUtf8('Move slide Up 1')) self.DownButton.setToolTip(self.trUtf8('Move slide down 1')) - customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides')) self.TitleLabel.setText(self.trUtf8('Title:')) self.AddButton.setText(self.trUtf8('Add New')) self.AddButton.setToolTip(self.trUtf8('Add new slide at bottom')) @@ -162,6 +168,7 @@ class Ui_customEditDialog(object): self.DeleteButton.setToolTip(self.trUtf8('Delete selected slide')) self.ClearButton.setText(self.trUtf8('Clear')) self.ClearButton.setToolTip(self.trUtf8('Clear edit area')) + self.SplitButton.setText(self.trUtf8('Split Slide')) + self.SplitButton.setToolTip(self.trUtf8('Add slide split')) self.ThemeLabel.setText(self.trUtf8('Theme:')) - self.ThemeComboBox.setToolTip(self.trUtf8('Set Theme for Slides')) self.CreditLabel.setText(self.trUtf8('Credits:')) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 410bd6fed..cbbb023aa 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -68,6 +68,8 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed) QtCore.QObject.connect(self.DownButton, QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed) + QtCore.QObject.connect(self.SplitButton, + QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed) QtCore.QObject.connect(self.VerseListView, QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'), self.onVerseListViewSelected) @@ -94,6 +96,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.EditAllButton.setEnabled(True) self.SaveButton.setEnabled(False) self.ClearButton.setEnabled(False) + self.SplitButton.setEnabled(False) self.TitleEdit.setText(u'') self.CreditEdit.setText(u'') self.VerseTextEdit.clear() @@ -202,12 +205,14 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): def onEditAllButtonPressed(self): self.editAll = True self.AddButton.setEnabled(False) + self.SplitButton.setEnabled(True) if self.VerseListView.count() > 0: verse_list = u'' for row in range(0, self.VerseListView.count()): item = self.VerseListView.item(row) verse_list += item.text() - verse_list += u'\n---\n' + if row != self.VerseListView.count() - 1: + verse_list += u'\n[---]\n' self.editText(verse_list) def editText(self, text): @@ -222,7 +227,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): def onSaveButtonPressed(self): if self.editAll: self.VerseListView.clear() - for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n---\n'): + for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n[---]\n'): self.VerseListView.addItem(row) else: self.VerseListView.currentItem().setText( @@ -241,8 +246,15 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.SaveButton.setEnabled(False) self.EditButton.setEnabled(False) self.EditAllButton.setEnabled(True) + self.SplitButton.setEnabled(False) self.VerseTextEdit.clear() + def onSplitButtonPressed(self): + if self.VerseTextEdit.textCursor().columnNumber() != 0: + self.VerseTextEdit.insertPlainText(u'\n') + self.VerseTextEdit.insertPlainText(u'[---]\n' ) + self.VerseTextEdit.setFocus() + def onDeleteButtonPressed(self): self.VerseListView.takeItem(self.VerseListView.currentRow()) self.EditButton.setEnabled(False) @@ -258,5 +270,5 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): return False, self.trUtf8('You need to enter a slide') if self.VerseTextEdit.toPlainText(): self.VerseTextEdit.setFocus() - return False, self.trUtf8('You have unsaved data') + return False, self.trUtf8('You have unsaved data, please save or clear') return True, u'' diff --git a/resources/forms/editcustomdialog.ui b/resources/forms/editcustomdialog.ui index 98bc1abb0..44ce46ca7 100644 --- a/resources/forms/editcustomdialog.ui +++ b/resources/forms/editcustomdialog.ui @@ -46,7 +46,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -106,7 +106,7 @@ - + Add New @@ -136,7 +136,7 @@ - + Save @@ -163,6 +163,16 @@ + + + + + + + Split Slide + + + @@ -216,8 +226,11 @@ + + + - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Save @@ -236,12 +249,44 @@ UpButton DownButton ThemeComboBox - buttonBox - + + + buttonBox + accepted() + customEditDialog + accept() + + + 294 + 524 + + + 294 + 270 + + + + + buttonBox + rejected() + customEditDialog + close() + + + 294 + 524 + + + 294 + 270 + + + + accept() rejected() From e0be3b57051c4efe86deae69340ac34d247db95b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 10 Apr 2010 11:28:57 +0100 Subject: [PATCH 07/18] refactor video display --- openlp/core/ui/__init__.py | 1 + openlp/core/ui/maindisplay.py | 3 --- openlp/core/ui/mainwindow.py | 11 ++++++++++- openlp/core/ui/slidecontroller.py | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 21f41ae7c..0ba8f8da8 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -28,6 +28,7 @@ from servicenoteform import ServiceNoteForm from serviceitemeditform import ServiceItemEditForm from screen import ScreenList from maindisplay import MainDisplay +from maindisplay import VideoDisplay from amendthemeform import AmendThemeForm from slidecontroller import SlideController from splashscreen import SplashScreen diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 1a8aa2563..4883cd732 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -93,7 +93,6 @@ class MainDisplay(DisplayWidget): """ log.debug(u'Initilisation started') DisplayWidget.__init__(self, None) - self.videoDisplay = VideoDisplay(parent, screens) self.parent = parent self.setWindowTitle(u'OpenLP Display') self.setAttribute(QtCore.Qt.WA_TranslucentBackground) @@ -171,8 +170,6 @@ class MainDisplay(DisplayWidget): else: self.setVisible(False) self.primary = True - self.videoDisplay.setup() - self.raise_() def resetDisplay(self): log.debug(u'resetDisplay') diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 23dbccabe..ae5dc5146 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.ui import AboutForm, SettingsForm, \ ServiceManager, ThemeManager, MainDisplay, SlideController, \ - PluginForm, MediaDockManager + PluginForm, MediaDockManager, VideoDisplay from openlp.core.lib import RenderManager, PluginConfig, build_icon, \ OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool from openlp.core.utils import check_latest_version, AppLocation @@ -443,6 +443,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.serviceNotSaved = False self.settingsmanager = SettingsManager(screens) self.generalConfig = PluginConfig(u'General') + self.videoDisplay = VideoDisplay(self, screens) self.mainDisplay = MainDisplay(self, screens) self.aboutForm = AboutForm(self, applicationVersion) self.settingsForm = SettingsForm(self.screens, self, self) @@ -572,11 +573,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.showMaximized() #screen_number = self.getMonitorNumber() self.mainDisplay.setup() + self.videoDisplay.setup() if self.mainDisplay.isVisible(): self.mainDisplay.setFocus() self.activateWindow() if str_to_bool(self.generalConfig.get_config(u'auto open', False)): self.ServiceManagerContents.onLoadService(True) + self.videoDisplay.lower() + self.mainDisplay.raise_() + + print self.children() def blankCheck(self): if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ @@ -633,16 +639,19 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if ret == QtGui.QMessageBox.Save: self.ServiceManagerContents.onSaveService() self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() elif ret == QtGui.QMessageBox.Discard: self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() else: event.ignore() else: self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 1f72ddfe1..09122dea2 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -392,7 +392,7 @@ class SlideController(QtGui.QWidget): if item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) - self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) + #self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) def enablePreviewToolBar(self, item): """ From 75428653809f3620d3135e744929ba77f7b3d7f7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 10 Apr 2010 16:46:45 +0100 Subject: [PATCH 08/18] Fix indentation --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4657b9b0f..f2e6911fa 100755 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p license='GNU General Public License', packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py', - 'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'], + 'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'], include_package_data=True, zip_safe=False, install_requires=[ From f99b91509c828b766d47ba5a0d4585192a477595 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 10 Apr 2010 19:08:03 +0100 Subject: [PATCH 09/18] remove prints --- openlp/core/ui/mainwindow.py | 2 -- openlp/plugins/alerts/lib/alertsmanager.py | 1 - 2 files changed, 3 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index ae5dc5146..b6cf8412c 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -582,8 +582,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.videoDisplay.lower() self.mainDisplay.raise_() - print self.children() - def blankCheck(self): if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ and str_to_bool(self.generalConfig.get_config(u'blank warning', False)): diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 6c674f986..d33470f0b 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -113,7 +113,6 @@ class AlertsManager(QtCore.QObject): self.parent.maindisplay.addAlertImage(alertframe) # check to see if we have a timer running if self.timer_id == 0: - print "timer tripped" self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) def timerEvent(self, event): From 04b63cb20f6d2ad76c31664400524b9e27e57f33 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 10 Apr 2010 19:11:24 +0100 Subject: [PATCH 10/18] remove weirdness --- openlp/plugins/alerts/lib/alertsmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index d33470f0b..69a6d6f53 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -21,7 +21,7 @@ # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # -##################################################################alertsmanager.py############# +############################################################################### import logging From f8e302116254173a50804789eb8b14d03358468c Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sun, 11 Apr 2010 00:24:22 +0200 Subject: [PATCH 11/18] Once and for all, fix the silly version problem! --- openlp.pyw | 4 +--- openlp/core/utils/__init__.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index f1b627940..528923862 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -78,9 +78,7 @@ class OpenLP(QtGui.QApplication): Run the OpenLP application. """ #Load and store current Application Version - filepath = AppLocation.get_directory(AppLocation.AppDir) - if not hasattr(sys, u'frozen'): - filepath = os.path.join(filepath, u'openlp') + filepath = AppLocation.get_directory(AppLocation.VersionDir) filepath = os.path.join(filepath, u'.version') fversion = None try: diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 4b053d877..12fc4a293 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -43,9 +43,10 @@ class AppLocation(object): ConfigDir = 2 DataDir = 3 PluginsDir = 4 + VersionDir = 5 @staticmethod - def get_directory(dir_type): + def get_directory(dir_type=1): """ Return the appropriate directory according to the directory type. @@ -83,17 +84,18 @@ class AppLocation(object): elif dir_type == AppLocation.PluginsDir: plugin_path = None app_path = os.path.abspath(os.path.split(sys.argv[0])[0]) - if sys.platform == u'win32': - if hasattr(sys, u'frozen') and sys.frozen == 1: - plugin_path = os.path.join(app_path, u'plugins') - else: - plugin_path = os.path.join(app_path, u'openlp', u'plugins') - elif sys.platform == u'darwin': + if hasattr(sys, u'frozen') and sys.frozen == 1: plugin_path = os.path.join(app_path, u'plugins') else: plugin_path = os.path.join( os.path.split(openlp.__file__)[0], u'plugins') return plugin_path + elif dir_type == AppLocation.VersionDir: + if hasattr(sys, u'frozen') and sys.frozen == 1: + plugin_path = os.path.abspath(os.path.split(sys.argv[0])[0]) + else: + plugin_path = os.path.split(openlp.__file__)[0] + return plugin_path def check_latest_version(config, current_version): From 3f5ac846f6374cf4834b43d126638803af4b3689 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sun, 11 Apr 2010 18:47:39 +0100 Subject: [PATCH 12/18] Head r791 --- openlp/plugins/songs/lib/sofimport.py | 496 +++++++++++++------------- 1 file changed, 248 insertions(+), 248 deletions(-) diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index ed5bb095d..f8256408b 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -24,23 +24,23 @@ ############################################################################### # OOo API documentation: -# http://wiki.services.openoffice.org/wiki/Documentation/BASIC_Guide/Structure_of_Text_Documents +# http://wiki.services.openoffice.org/wiki/Documentation/BASIC_Guide/Structure_of_Text_Documents # http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Text/Iterating_over_Text # http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://wiki.services.openoffice.org/wiki/Python import re import os -import time +import time from PyQt4 import QtCore -from songimport import SongImport - +from songimport import SongImport + if os.name == u'nt': from win32com.client import Dispatch BOLD = 150.0 - ITALIC = 2 - PAGE_BEFORE = 4 - PAGE_AFTER = 5 + ITALIC = 2 + PAGE_BEFORE = 4 + PAGE_AFTER = 5 PAGE_BOTH = 6 else: import uno @@ -95,15 +95,15 @@ class SofImport(object): loop = 0 while ctx is None and loop < 5: try: - ctx = resolver.resolve(u'uno:socket,host=localhost,' \ + ctx = resolver.resolve(u'uno:socket,host=localhost,' \ + 'port=2002;urp;StarOffice.ComponentContext') - except: + except: pass self.start_ooo_process() loop += 1 manager = ctx.ServiceManager - self.desktop = manager.createInstanceWithContext( - "com.sun.star.frame.Desktop", ctx ) + self.desktop = manager.createInstanceWithContext( + "com.sun.star.frame.Desktop", ctx ) def start_ooo_process(self): try: @@ -148,16 +148,16 @@ class SofImport(object): def process_doc(self): """ Process the RTF file, a paragraph at a time - """ + """ self.blanklines = 0 - self.new_song() + self.new_song() paragraphs = self.document.getText().createEnumeration() while paragraphs.hasMoreElements(): paragraph = paragraphs.nextElement() if paragraph.supportsService("com.sun.star.text.Paragraph"): - self.process_paragraph(paragraph) - if self.song: - self.song.finish() + self.process_paragraph(paragraph) + if self.song: + self.song.finish() self.song = None def process_paragraph(self, paragraph): @@ -171,71 +171,71 @@ class SofImport(object): In later books, there may not be line breaks, so check for 3 or more newlines """ - text = u'' - textportions = paragraph.createEnumeration() - while textportions.hasMoreElements(): - textportion = textportions.nextElement() - if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH): - self.process_paragraph_text(text) - self.new_song() - text = u'' + text = u'' + textportions = paragraph.createEnumeration() + while textportions.hasMoreElements(): + textportion = textportions.nextElement() + if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH): + self.process_paragraph_text(text) + self.new_song() + text = u'' text += self.process_textportion(textportion) - if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH): - self.process_paragraph_text(text) - self.new_song() - text = u'' - self.process_paragraph_text(text) - + if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH): + self.process_paragraph_text(text) + self.new_song() + text = u'' + self.process_paragraph_text(text) + def process_paragraph_text(self, text): """ Split the paragraph text into multiple lines and process - """ - for line in text.split(u'\n'): - self.process_paragraph_line(line) - if self.blanklines > 2: - self.new_song() - + """ + for line in text.split(u'\n'): + self.process_paragraph_line(line) + if self.blanklines > 2: + self.new_song() + def process_paragraph_line(self, text): """ Process a single line. Throw away that text which isn't relevant, i.e. stuff that appears at the end of the song. Anything that is OK, append to the current verse - """ - text = text.strip() - if text == u'': - self.blanklines += 1 - if self.blanklines > 1: - return - if self.song.get_title() != u'': - self.finish_verse() - return - self.blanklines = 0 - if self.skip_to_close_bracket: - if text.endswith(u')'): - self.skip_to_close_bracket = False - return + """ + text = text.strip() + if text == u'': + self.blanklines += 1 + if self.blanklines > 1: + return + if self.song.get_title() != u'': + self.finish_verse() + return + self.blanklines = 0 + if self.skip_to_close_bracket: + if text.endswith(u')'): + self.skip_to_close_bracket = False + return if text.startswith(u'CCL Licence'): - self.italics = False - return - if text == u'A Songs of Fellowship Worship Resource': - return + self.italics = False + return + if text == u'A Songs of Fellowship Worship Resource': + return if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \ - or text.startswith(u'(From'): - self.skip_to_close_bracket = True - return - if text.startswith(u'Copyright'): - self.song.add_copyright(text) - return - if text == u'(Repeat)': - self.finish_verse() - self.song.repeat_verse() - return + or text.startswith(u'(From'): + self.skip_to_close_bracket = True + return + if text.startswith(u'Copyright'): + self.song.add_copyright(text) + return + if text == u'(Repeat)': + self.finish_verse() + self.song.repeat_verse() + return if self.song.get_title() == u'': - if self.song.get_copyright() == u'': - self.add_author(text) - else: - self.song.add_copyright(text) - return + if self.song.get_copyright() == u'': + self.add_author(text) + else: + self.song.add_copyright(text) + return self.add_verse_line(text) def process_textportion(self, textportion): @@ -244,41 +244,41 @@ class SofImport(object): it's bold or italics. If it's bold then its a song number or song title. Song titles are in all capitals, so we must bring the capitalization into line - """ + """ text = textportion.getString() text = self.tidy_text(text) if text.strip() == u'': - return text - if textportion.CharWeight == BOLD: - boldtext = text.strip() - if boldtext.isdigit() and self.song.get_song_number() == '': - self.add_songnumber(boldtext) - return u'' + return text + if textportion.CharWeight == BOLD: + boldtext = text.strip() + if boldtext.isdigit() and self.song.get_song_number() == '': + self.add_songnumber(boldtext) + return u'' if self.song.get_title() == u'': - text = self.uncap_text(text) - self.add_title(text) + text = self.uncap_text(text) + self.add_title(text) return text if text.strip().startswith(u'('): - return text - self.italics = (textportion.CharPosture == ITALIC) - return text - + return text + self.italics = (textportion.CharPosture == ITALIC) + return text + def new_song(self): """ A change of song. Store the old, create a new ... but only if the last song was complete. If not, stick with it - """ - if self.song: - self.finish_verse() + """ + if self.song: + self.finish_verse() if not self.song.check_complete(): - return - self.song.finish() + return + self.song.finish() self.song = SongImport(self.manager) self.skip_to_close_bracket = False - self.is_chorus = False + self.is_chorus = False self.italics = False self.currentverse = u'' - + def add_songnumber(self, song_no): """ Add a song number, store as alternate title. Also use the song @@ -303,27 +303,27 @@ class SofImport(object): """ Add the title to the song. Strip some leading/trailing punctuation that we don't want in a title - """ - title = text.strip() - if title.startswith(u'\''): - title = title[1:] - if title.endswith(u','): - title = title[:-1] - self.song.set_title(title) - + """ + title = text.strip() + if title.startswith(u'\''): + title = title[1:] + if title.endswith(u','): + title = title[:-1] + self.song.set_title(title) + def add_author(self, text): """ Add the author. OpenLP stores them individually so split by 'and', '&' and comma. However need to check for "Mr and Mrs Smith" and turn it to "Mr Smith" and "Mrs Smith". - """ - text = text.replace(u' and ', u' & ') - for author in text.split(u','): - authors = author.split(u'&') - for i in range(len(authors)): - author2 = authors[i].strip() - if author2.find(u' ') == -1 and i < len(authors) - 1: + """ + text = text.replace(u' and ', u' & ') + for author in text.split(u','): + authors = author.split(u'&') + for i in range(len(authors)): + author2 = authors[i].strip() + if author2.find(u' ') == -1 and i < len(authors) - 1: author2 = author2 + u' ' \ + authors[i + 1].strip().split(u' ')[-1] if author2.endswith(u'.'): @@ -336,14 +336,14 @@ class SofImport(object): Add a line to the current verse. If the formatting has changed and we're beyond the second line of first verse, then this indicates a change of verse. Italics are a chorus - """ - if self.italics != self.is_chorus and ((len(self.song.verses) > 0) or - (self.currentverse.count(u'\n') > 1)): - self.finish_verse() - if self.italics: - self.is_chorus = True - self.currentverse += text + u'\n' - + """ + if self.italics != self.is_chorus and ((len(self.song.verses) > 0) or + (self.currentverse.count(u'\n') > 1)): + self.finish_verse() + if self.italics: + self.is_chorus = True + self.currentverse += text + u'\n' + def finish_verse(self): """ Verse is finished, store it. Note in book 1+2, some songs are formatted @@ -383,18 +383,18 @@ class SofImport(object): """ Get rid of some dodgy unicode and formatting characters we're not interested in. Some can be converted to ascii. - """ - text = text.replace(u'\t', u' ') - text = text.replace(u'\r', u'\n') - text = text.replace(u'\u2018', u'\'') - text = text.replace(u'\u2019', u'\'') - text = text.replace(u'\u201c', u'"') - text = text.replace(u'\u201d', u'"') - text = text.replace(u'\u2026', u'...') - text = text.replace(u'\u2013', u'-') - text = text.replace(u'\u2014', u'-') - return text - + """ + text = text.replace(u'\t', u' ') + text = text.replace(u'\r', u'\n') + text = text.replace(u'\u2018', u'\'') + text = text.replace(u'\u2019', u'\'') + text = text.replace(u'\u201c', u'"') + text = text.replace(u'\u201d', u'"') + text = text.replace(u'\u2026', u'...') + text = text.replace(u'\u2013', u'-') + text = text.replace(u'\u2014', u'-') + return text + def uncap_text(self, text): """ Words in the title are in all capitals, so we lowercase them. @@ -403,128 +403,128 @@ class SofImport(object): There is a complicated word "One", which is sometimes lower and sometimes upper depending on context. Never mind, keep it lower. - """ - textarr = re.split(u'(\W+)', text) - textarr[0] = textarr[0].capitalize() - for i in range(1, len(textarr)): - # Do not translate these. Fixed strings in SOF song file - if textarr[i] in (u'JESUS', u'CHRIST', u'KING', u'ALMIGHTY', - u'REDEEMER', u'SHEPHERD', u'SON', u'GOD', u'LORD', u'FATHER', - u'HOLY', u'SPIRIT', u'LAMB', u'YOU', u'YOUR', u'I', u'I\'VE', - u'I\'M', u'I\'LL', u'SAVIOUR', u'O', u'YOU\'RE', u'HE', u'HIS', - u'HIM', u'ZION', u'EMMANUEL', u'MAJESTY', u'JESUS\'', u'JIREH', - u'JUDAH', u'LION', u'LORD\'S', u'ABRAHAM', u'GOD\'S', - u'FATHER\'S', u'ELIJAH'): - textarr[i] = textarr[i].capitalize() - else: - textarr[i] = textarr[i].lower() - text = u''.join(textarr) - return text - - def verse_splits(self, song_number): - """ - Because someone at Kingsway forgot to check the 1+2 RTF file, - some verses were not formatted correctly. - """ - if song_number == 11: return 8 - if song_number == 18: return 5 - if song_number == 21: return 6 - if song_number == 23: return 4 - if song_number == 24: return 7 - if song_number == 27: return 4 - if song_number == 31: return 6 - if song_number == 49: return 4 - if song_number == 50: return 8 - if song_number == 70: return 4 - if song_number == 75: return 8 - if song_number == 79: return 6 - if song_number == 97: return 7 - if song_number == 107: return 4 - if song_number == 109: return 4 - if song_number == 133: return 4 - if song_number == 155: return 10 - if song_number == 156: return 8 - if song_number == 171: return 4 - if song_number == 188: return 7 - if song_number == 192: return 4 - if song_number == 208: return 8 - if song_number == 215: return 8 - if song_number == 220: return 4 - if song_number == 247: return 6 - if song_number == 248: return 6 - if song_number == 251: return 8 - if song_number == 295: return 8 - if song_number == 307: return 5 - if song_number == 314: return 6 - if song_number == 325: return 8 - if song_number == 386: return 6 - if song_number == 415: return 4 - if song_number == 426: return 4 - if song_number == 434: return 5 - if song_number == 437: return 4 - if song_number == 438: return 6 - if song_number == 456: return 8 - if song_number == 461: return 4 - if song_number == 469: return 4 - if song_number == 470: return 5 - if song_number == 476: return 6 - if song_number == 477: return 7 - if song_number == 480: return 8 - if song_number == 482: return 4 - if song_number == 512: return 4 - if song_number == 513: return 8 - if song_number == 518: return 5 - if song_number == 520: return 4 - if song_number == 523: return 6 - if song_number == 526: return 8 - if song_number == 527: return 4 - if song_number == 529: return 4 - if song_number == 537: return 4 - if song_number == 555: return 6 - if song_number == 581: return 4 - if song_number == 589: return 6 - if song_number == 590: return 4 - if song_number == 593: return 8 - if song_number == 596: return 4 - if song_number == 610: return 6 - if song_number == 611: return 6 - if song_number == 619: return 8 - if song_number == 645: return 5 - if song_number == 653: return 6 - if song_number == 683: return 7 - if song_number == 686: return 4 - if song_number == 697: return 8 - if song_number == 698: return 4 - if song_number == 704: return 6 - if song_number == 716: return 4 - if song_number == 717: return 6 - if song_number == 730: return 4 - if song_number == 731: return 8 - if song_number == 732: return 8 - if song_number == 738: return 4 - if song_number == 756: return 9 - if song_number == 815: return 6 - if song_number == 830: return 8 - if song_number == 831: return 4 - if song_number == 876: return 6 - if song_number == 877: return 6 - if song_number == 892: return 4 - if song_number == 894: return 6 - if song_number == 902: return 8 - if song_number == 905: return 8 - if song_number == 921: return 6 - if song_number == 940: return 7 - if song_number == 955: return 9 - if song_number == 968: return 8 - if song_number == 972: return 7 - if song_number == 974: return 4 - if song_number == 988: return 6 - if song_number == 991: return 5 - if song_number == 1002: return 8 - if song_number == 1024: return 8 - if song_number == 1044: return 9 - if song_number == 1088: return 6 - if song_number == 1117: return 6 - if song_number == 1119: return 7 - return None + """ + textarr = re.split(u'(\W+)', text) + textarr[0] = textarr[0].capitalize() + for i in range(1, len(textarr)): + # Do not translate these. Fixed strings in SOF song file + if textarr[i] in (u'JESUS', u'CHRIST', u'KING', u'ALMIGHTY', + u'REDEEMER', u'SHEPHERD', u'SON', u'GOD', u'LORD', u'FATHER', + u'HOLY', u'SPIRIT', u'LAMB', u'YOU', u'YOUR', u'I', u'I\'VE', + u'I\'M', u'I\'LL', u'SAVIOUR', u'O', u'YOU\'RE', u'HE', u'HIS', + u'HIM', u'ZION', u'EMMANUEL', u'MAJESTY', u'JESUS\'', u'JIREH', + u'JUDAH', u'LION', u'LORD\'S', u'ABRAHAM', u'GOD\'S', + u'FATHER\'S', u'ELIJAH'): + textarr[i] = textarr[i].capitalize() + else: + textarr[i] = textarr[i].lower() + text = u''.join(textarr) + return text + + def verse_splits(self, song_number): + """ + Because someone at Kingsway forgot to check the 1+2 RTF file, + some verses were not formatted correctly. + """ + if song_number == 11: return 8 + if song_number == 18: return 5 + if song_number == 21: return 6 + if song_number == 23: return 4 + if song_number == 24: return 7 + if song_number == 27: return 4 + if song_number == 31: return 6 + if song_number == 49: return 4 + if song_number == 50: return 8 + if song_number == 70: return 4 + if song_number == 75: return 8 + if song_number == 79: return 6 + if song_number == 97: return 7 + if song_number == 107: return 4 + if song_number == 109: return 4 + if song_number == 133: return 4 + if song_number == 155: return 10 + if song_number == 156: return 8 + if song_number == 171: return 4 + if song_number == 188: return 7 + if song_number == 192: return 4 + if song_number == 208: return 8 + if song_number == 215: return 8 + if song_number == 220: return 4 + if song_number == 247: return 6 + if song_number == 248: return 6 + if song_number == 251: return 8 + if song_number == 295: return 8 + if song_number == 307: return 5 + if song_number == 314: return 6 + if song_number == 325: return 8 + if song_number == 386: return 6 + if song_number == 415: return 4 + if song_number == 426: return 4 + if song_number == 434: return 5 + if song_number == 437: return 4 + if song_number == 438: return 6 + if song_number == 456: return 8 + if song_number == 461: return 4 + if song_number == 469: return 4 + if song_number == 470: return 5 + if song_number == 476: return 6 + if song_number == 477: return 7 + if song_number == 480: return 8 + if song_number == 482: return 4 + if song_number == 512: return 4 + if song_number == 513: return 8 + if song_number == 518: return 5 + if song_number == 520: return 4 + if song_number == 523: return 6 + if song_number == 526: return 8 + if song_number == 527: return 4 + if song_number == 529: return 4 + if song_number == 537: return 4 + if song_number == 555: return 6 + if song_number == 581: return 4 + if song_number == 589: return 6 + if song_number == 590: return 4 + if song_number == 593: return 8 + if song_number == 596: return 4 + if song_number == 610: return 6 + if song_number == 611: return 6 + if song_number == 619: return 8 + if song_number == 645: return 5 + if song_number == 653: return 6 + if song_number == 683: return 7 + if song_number == 686: return 4 + if song_number == 697: return 8 + if song_number == 698: return 4 + if song_number == 704: return 6 + if song_number == 716: return 4 + if song_number == 717: return 6 + if song_number == 730: return 4 + if song_number == 731: return 8 + if song_number == 732: return 8 + if song_number == 738: return 4 + if song_number == 756: return 9 + if song_number == 815: return 6 + if song_number == 830: return 8 + if song_number == 831: return 4 + if song_number == 876: return 6 + if song_number == 877: return 6 + if song_number == 892: return 4 + if song_number == 894: return 6 + if song_number == 902: return 8 + if song_number == 905: return 8 + if song_number == 921: return 6 + if song_number == 940: return 7 + if song_number == 955: return 9 + if song_number == 968: return 8 + if song_number == 972: return 7 + if song_number == 974: return 4 + if song_number == 988: return 6 + if song_number == 991: return 5 + if song_number == 1002: return 8 + if song_number == 1024: return 8 + if song_number == 1044: return 9 + if song_number == 1088: return 6 + if song_number == 1117: return 6 + if song_number == 1119: return 7 + return None From cbc93259cb2caa5e30097a0672ff0d9e87e4bafe Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sun, 11 Apr 2010 18:52:51 +0100 Subject: [PATCH 13/18] Import and line ending fixes --- openlp/plugins/alerts/forms/alertstab.py | 1 - openlp/plugins/songs/lib/sofimport.py | 109 ++++++++++++----------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/openlp/plugins/alerts/forms/alertstab.py b/openlp/plugins/alerts/forms/alertstab.py index fe1b7cb6d..33c574de5 100644 --- a/openlp/plugins/alerts/forms/alertstab.py +++ b/openlp/plugins/alerts/forms/alertstab.py @@ -27,7 +27,6 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, str_to_bool from openlp.plugins.alerts.lib.models import AlertItem -from openlp.plugins.alerts.lib import alertsmanager class AlertsTab(SettingsTab): """ diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index f8256408b..c8da5240d 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -29,10 +29,11 @@ # http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://wiki.services.openoffice.org/wiki/Python -import re import os -import time +import re + from PyQt4 import QtCore + from songimport import SongImport if os.name == u'nt': @@ -69,9 +70,9 @@ class SofImport(object): Initialise the class. Requires a songmanager class which is passed to SongImport for writing song to disk """ - self.song = None + self.song = None self.manager = songmanager - self.process_started = False + self.process_started = False def import_sof(self, filename): self.start_ooo() @@ -86,7 +87,7 @@ class SofImport(object): """ if os.name == u'nt': self.start_ooo_process() - self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') + self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') else: context = uno.getComponentContext() resolver = context.ServiceManager.createInstanceWithContext( @@ -110,10 +111,10 @@ class SofImport(object): if os.name == u'nt': self.manager = Dispatch(u'com.sun.star.ServiceManager') self.manager._FlagAsMethod(u'Bridge_GetStruct') - self.manager._FlagAsMethod(u'Bridge_GetValueObject') + self.manager._FlagAsMethod(u'Bridge_GetValueObject') else: - cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \ - + u'-nofirststartwizard ' \ + cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \ + + u'-nofirststartwizard ' \ + '-accept="socket,host=localhost,port=2002;urp;"' process = QtCore.QProcess() process.startDetached(cmd) @@ -283,21 +284,21 @@ class SofImport(object): """ Add a song number, store as alternate title. Also use the song number to work out which songbook we're in - """ + """ self.song.set_song_number(song_no) - self.song.set_alternate_title(song_no + u'.') - if int(song_no) <= 640: - self.song.set_song_book(u'Songs of Fellowship 1', - u'Kingsway Publications') - elif int(song_no) <= 1150: - self.song.set_song_book(u'Songs of Fellowship 2', - u'Kingsway Publications') - elif int(song_no) <= 1690: - self.song.set_song_book(u'Songs of Fellowship 3', - u'Kingsway Publications') - else: - self.song.set_song_book(u'Songs of Fellowship 4', - u'Kingsway Publications') + self.song.set_alternate_title(song_no + u'.') + if int(song_no) <= 640: + self.song.set_song_book(u'Songs of Fellowship 1', + u'Kingsway Publications') + elif int(song_no) <= 1150: + self.song.set_song_book(u'Songs of Fellowship 2', + u'Kingsway Publications') + elif int(song_no) <= 1690: + self.song.set_song_book(u'Songs of Fellowship 3', + u'Kingsway Publications') + else: + self.song.set_song_book(u'Songs of Fellowship 4', + u'Kingsway Publications') def add_title(self, text): """ @@ -328,9 +329,9 @@ class SofImport(object): + authors[i + 1].strip().split(u' ')[-1] if author2.endswith(u'.'): author2 = author2[:-1] - if author2: - self.song.add_author(author2) - + if author2: + self.song.add_author(author2) + def add_verse_line(self, text): """ Add a line to the current verse. If the formatting has changed and @@ -349,36 +350,36 @@ class SofImport(object): Verse is finished, store it. Note in book 1+2, some songs are formatted incorrectly. Here we try and split songs with missing line breaks into the correct number of verses. - """ - if self.currentverse.strip() == u'': - return + """ + if self.currentverse.strip() == u'': + return if self.is_chorus: - versetag = u'C' - splitat = None - else: - versetag = u'V' - splitat = self.verse_splits(self.song.get_song_number()) - if splitat: - ln = 0 - verse = u'' - for line in self.currentverse.split(u'\n'): - ln += 1 - if line == u'' or ln > splitat: - self.song.add_verse(verse, versetag) - ln = 0 - if line: - verse = line + u'\n' - else: - verse = u'' - else: - verse += line + u'\n' - if verse: - self.song.add_verse(verse, versetag) - else: - self.song.add_verse(self.currentverse, versetag) - self.currentverse = u'' - self.is_chorus = False - + versetag = u'C' + splitat = None + else: + versetag = u'V' + splitat = self.verse_splits(self.song.get_song_number()) + if splitat: + ln = 0 + verse = u'' + for line in self.currentverse.split(u'\n'): + ln += 1 + if line == u'' or ln > splitat: + self.song.add_verse(verse, versetag) + ln = 0 + if line: + verse = line + u'\n' + else: + verse = u'' + else: + verse += line + u'\n' + if verse: + self.song.add_verse(verse, versetag) + else: + self.song.add_verse(self.currentverse, versetag) + self.currentverse = u'' + self.is_chorus = False + def tidy_text(self, text): """ Get rid of some dodgy unicode and formatting characters we're not From e4989f422be167f6b66c92fcdfb631a160df2db3 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Mon, 12 Apr 2010 22:49:56 +0100 Subject: [PATCH 14/18] tidyups --- openlp/plugins/songs/lib/songimport.py | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 3008552f8..cb780f987 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -68,12 +68,16 @@ class SongImport(object): @staticmethod def process_songs_text(manager, text): songs = [] - songtexts = SongImport.tidy_text(text).split(u'\n\n\n') + songtexts = SongImport.tidy_text(text).split(u'\f') + song = SongImport(manager) for songtext in songtexts: - if songtext.strip() != u'': - song = SongImport(manager) + if songtext.strip(): song.process_song_text(songtext.strip()) - songs.append(song) + if song.check_complete(): + songs.append(song) + song = SongImport(manager) + if song.check_complete(): + songs.append(song) return songs @staticmethod @@ -83,7 +87,6 @@ class SongImport(object): interested in. Some can be converted to ascii. """ text = text.replace(u'\t', u' ') - text = text.replace(u'\f', u'\n\n\n') text = text.replace(u'\r\n', u'\n') text = text.replace(u'\r', u'\n') text = text.replace(u'\u2018', u'\'') @@ -96,12 +99,13 @@ class SongImport(object): # Remove surplus blank lines, spaces, trailing/leading spaces while text.find(u' ') >= 0: text = text.replace(u' ', u' ') - while text.find(u'\n ') >= 0: - text = text.replace(u'\n ', u'\n') - while text.find(u' \n') >= 0: - text = text.replace(u' \n', u'\n') - while text.find(u'\n\n\n\n') >= 0: - text = text.replace(u'\n\n\n\n', u'\n\n\n') + text = text.replace(u'\n ', u'\n') + text = text.replace(u' \n', u'\n') + text = text.replace(u'\n\n\n\n\n', u'\f') + text = text.replace(u'\f ', u'\f') + text = text.replace(u' \f', u'\f') + while text.find(u'\f\f') >= 0: + text = text.replace(u'\f\f', u'\f') return text def process_song_text(self, text): @@ -190,7 +194,6 @@ class SongImport(object): However need to check for "Mr and Mrs Smith" and turn it to "Mr Smith" and "Mrs Smith". """ - text = text.replace(u' and ', u' & ') for author in text.split(u','): authors = author.split(u'&') for i in range(len(authors)): From 14bb4c2edbf8620cecbba3c540542896d6311d6f Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Mon, 12 Apr 2010 22:55:59 +0100 Subject: [PATCH 15/18] add missing file --- openlp/plugins/songs/lib/oooimport.py | 195 ++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 openlp/plugins/songs/lib/oooimport.py diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py new file mode 100644 index 000000000..cd76617bf --- /dev/null +++ b/openlp/plugins/songs/lib/oooimport.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # +# Thompson, Jon Tibble, Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# 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 # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +import os +from PyQt4 import QtCore +from songimport import SongImport + +if os.name == u'nt': + from win32com.client import Dispatch + PAGE_BEFORE = 4 + PAGE_AFTER = 5 + PAGE_BOTH = 6 +else: + import uno + from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH + +class OooImport(object): + """ + Import songs from Impress/Powerpoint docs using Impress + """ + def __init__(self, songmanager): + """ + Initialise the class. Requires a songmanager class which is passed + to SongImport for writing song to disk + """ + self.song = None + self.manager = songmanager + self.document = None + self.process_started = False + + def import_docs(self, filenames): + self.start_ooo() + for filename in filenames: + filename = unicode(filename) + if os.path.isfile(filename): + self.open_ooo_file(filename) + if self.document: + if self.document.supportsService( + "com.sun.star.presentation.PresentationDocument"): + self.process_pres() + if self.document.supportsService( + "com.sun.star.text.TextDocument"): + self.process_doc() + self.close_ooo_file() + self.close_ooo() + + def start_ooo(self): + """ + Start OpenOffice.org process + TODO: The presentation/Impress plugin may already have it running + """ + if os.name == u'nt': + self.start_ooo_process() + self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') + else: + context = uno.getComponentContext() + resolver = context.ServiceManager.createInstanceWithContext( + u'com.sun.star.bridge.UnoUrlResolver', context) + ctx = None + loop = 0 + while ctx is None and loop < 5: + try: + ctx = resolver.resolve(u'uno:socket,host=localhost,' \ + + 'port=2002;urp;StarOffice.ComponentContext') + except: + pass + self.start_ooo_process() + loop += 1 + manager = ctx.ServiceManager + self.desktop = manager.createInstanceWithContext( + "com.sun.star.frame.Desktop", ctx ) + + def start_ooo_process(self): + try: + if os.name == u'nt': + self.manager = Dispatch(u'com.sun.star.ServiceManager') + self.manager._FlagAsMethod(u'Bridge_GetStruct') + self.manager._FlagAsMethod(u'Bridge_GetValueObject') + else: + cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \ + + u'-nofirststartwizard ' \ + + '-accept="socket,host=localhost,port=2002;urp;"' + process = QtCore.QProcess() + process.startDetached(cmd) + process.waitForStarted() + self.process_started = True + except: + pass + + def open_ooo_file(self, filepath): + """ + Open the passed file in OpenOffice.org Impress + """ + if os.name == u'nt': + url = u'file:///' + filepath.replace(u'\\', u'/') + url = url.replace(u':', u'|').replace(u' ', u'%20') + else: + url = uno.systemPathToFileUrl(filepath) + properties = [] + properties = tuple(properties) + try: + self.document = self.desktop.loadComponentFromURL(url, u'_blank', + 0, properties) + if not self.document.supportsService( + "com.sun.star.presentation.PresentationDocument") \ + and not self.document.supportsService( + "com.sun.star.text.TextDocument"): + self.close_ooo_file() + except: + pass + return + + def close_ooo_file(self): + """ + Close file. + """ + self.document.close(True) + self.document = None + + def close_ooo(self): + """ + Close OOo. But only if we started it and not on windows + """ + if self.process_started: + self.desktop.terminate() + + def process_pres(self): + """ + Process the file + """ + doc = self.document + slides = doc.getDrawPages() + text = u'' + for slide_no in range(slides.getCount()): + slide = slides.getByIndex(slide_no) + slidetext = u'' + for idx in range(slide.getCount()): + shape = slide.getByIndex(idx) + if shape.supportsService("com.sun.star.drawing.Text"): + if shape.getString().strip() != u'': + slidetext += shape.getString().strip() + u'\n\n' + if slidetext.strip() == u'': + slidetext = u'\f' + text += slidetext + song = SongImport(self.manager) + songs = SongImport.process_songs_text(self.manager, text) + for song in songs: + song.finish() + return + + def process_doc(self): + """ + Process the doc file, a paragraph at a time + """ + text = u'' + paragraphs = self.document.getText().createEnumeration() + while paragraphs.hasMoreElements(): + paratext = u'' + paragraph = paragraphs.nextElement() + if paragraph.supportsService("com.sun.star.text.Paragraph"): + textportions = paragraph.createEnumeration() + while textportions.hasMoreElements(): + textportion = textportions.nextElement() + if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH): + paratext += u'\f' + paratext += textportion.getString() + if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH): + paratext += u'\f' + text += paratext + u'\n' + songs = SongImport.process_songs_text(self.manager, text) + for song in songs: + song.finish() + From c7c4def38efab05161765f83617e89ed4e6e6422 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Tue, 13 Apr 2010 08:33:58 +0100 Subject: [PATCH 16/18] error trap if no ooo --- openlp/plugins/songs/lib/oooimport.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index cd76617bf..403738973 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -33,9 +33,11 @@ if os.name == u'nt': PAGE_AFTER = 5 PAGE_BOTH = 6 else: - import uno - from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH - + try: + import uno + from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH + except: + pass class OooImport(object): """ Import songs from Impress/Powerpoint docs using Impress From 57cc60e1bdfe01da7ff8a0fbd4f649e93b32054b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Wed, 14 Apr 2010 19:58:22 +0300 Subject: [PATCH 17/18] Config file unicode encoding fix --- openlp/core/lib/pluginconfig.py | 5 +++-- openlp/core/utils/registry.py | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/openlp/core/lib/pluginconfig.py b/openlp/core/lib/pluginconfig.py index 936a2f3a0..e27b86669 100644 --- a/openlp/core/lib/pluginconfig.py +++ b/openlp/core/lib/pluginconfig.py @@ -139,8 +139,9 @@ class PluginConfig(object): list = [] if list_count > 0: for counter in range(0, list_count): - item = unicode(self.get_config(u'%s %d' % (name, counter))) - list.append(item) + item = self.get_config(u'%s %d' % (name, counter)) + if item: + list.append(item) return list def set_list(self, name, list): diff --git a/openlp/core/utils/registry.py b/openlp/core/utils/registry.py index ba7c72a89..9842474ad 100644 --- a/openlp/core/utils/registry.py +++ b/openlp/core/utils/registry.py @@ -41,15 +41,17 @@ class Registry(object): """ Check if a value exists. """ - return self.config.has_option(section, key) + return self.config.has_option(section.encode('utf-8'), + key.encode('utf-8')) def get_value(self, section, key, default=None): """ Get a single value from the registry. """ try: - if self.config.get(section, key): - return self.config.get(section, key) + if self.config.get(section.encode('utf-8'), key.encode('utf-8')): + return self.config.get(section.encode('utf-8'), + key.encode('utf-8')).decode('utf-8') else: return default except: @@ -60,7 +62,8 @@ class Registry(object): Set a single value in the registry. """ try : - self.config.set(section, key, unicode(value)) + self.config.set(section.encode('utf-8'), key.encode('utf-8'), + unicode(value).encode('utf-8')) return self._save() except: return False @@ -70,7 +73,8 @@ class Registry(object): Delete a single value from the registry. """ try: - self.config.remove_option(section, key) + self.config.remove_option(section.encode('utf-8'), + key.encode('utf-8')) return self._save() except: return False @@ -79,14 +83,14 @@ class Registry(object): """ Check if a section exists. """ - return self.config.has_section(section) + return self.config.has_section(section.encode('utf-8')) def create_section(self, section): """ Create a new section in the registry. """ try: - self.config.add_section(section) + self.config.add_section(section.encode('utf-8')) return self._save() except: return False @@ -96,7 +100,7 @@ class Registry(object): Delete a section (including all values). """ try: - self.config.remove_section(section) + self.config.remove_section(section.encode('utf-8')) return self._save() except: return False From 235748a9e919c34eeed59e1de591b42e4f291f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Wed, 14 Apr 2010 20:12:30 +0300 Subject: [PATCH 18/18] indentation fix --- openlp/core/utils/registry.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/core/utils/registry.py b/openlp/core/utils/registry.py index 9842474ad..3d7137dfd 100644 --- a/openlp/core/utils/registry.py +++ b/openlp/core/utils/registry.py @@ -42,7 +42,7 @@ class Registry(object): Check if a value exists. """ return self.config.has_option(section.encode('utf-8'), - key.encode('utf-8')) + key.encode('utf-8')) def get_value(self, section, key, default=None): """ @@ -51,7 +51,7 @@ class Registry(object): try: if self.config.get(section.encode('utf-8'), key.encode('utf-8')): return self.config.get(section.encode('utf-8'), - key.encode('utf-8')).decode('utf-8') + key.encode('utf-8')).decode('utf-8') else: return default except: @@ -63,7 +63,7 @@ class Registry(object): """ try : self.config.set(section.encode('utf-8'), key.encode('utf-8'), - unicode(value).encode('utf-8')) + unicode(value).encode('utf-8')) return self._save() except: return False @@ -74,7 +74,7 @@ class Registry(object): """ try: self.config.remove_option(section.encode('utf-8'), - key.encode('utf-8')) + key.encode('utf-8')) return self._save() except: return False