diff --git a/openlp/core/lib/baselistwithdnd.py b/openlp/core/lib/baselistwithdnd.py index bc043082c..d34eada98 100644 --- a/openlp/core/lib/baselistwithdnd.py +++ b/openlp/core/lib/baselistwithdnd.py @@ -48,5 +48,4 @@ class BaseListWithDnD(QtGui.QListWidget): mimeData = QtCore.QMimeData() drag.setMimeData(mimeData) mimeData.setText(self.PluginName) - dropAction = drag.start(QtCore.Qt.CopyAction) - + drag.start(QtCore.Qt.CopyAction) diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 6443a4795..d21e3f167 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -65,11 +65,29 @@ class EventReceiver(QtCore.QObject): ``slidecontroller_{live|preview}_last`` Moves to the last slide + ``slidecontroller_{live|preview}_set`` + Moves to a specific slide, by index + ``slidecontroller_{live|preview}_started`` Broadcasts that an item has been made live/previewed ``slidecontroller_{live|preview}_change`` - Informs the slidecontroller that a slide change has occurred + Informs the slidecontroller that a slide change has occurred and to + update itself + + ``slidecontroller_{live|preview}_changed`` + Broadcasts that the slidecontroller has changed the current slide + + ``slidecontroller_{live|preview}_text_request`` + Request the text for the current item in the controller + Returns a slidecontroller_{live|preview}_text_response with an + array of dictionaries with the tag and verse text + + ``slidecontroller_{live|preview}_blank`` + Request that the output screen is blanked + + ``slidecontroller_{live|preview}_unblank`` + Request that the output screen is unblanked ``slidecontroller_live_spin_delay`` Pushes out the loop delay @@ -77,9 +95,19 @@ class EventReceiver(QtCore.QObject): ``slidecontroller_live_stop_loop`` Stop the loop on the main display - ``servicecontroller_next_item`` + ``servicemanager_previous_item`` + Display the previous item in the service + + ``servicemanager_next_item`` Display the next item in the service + ``servicemanager_set_item`` + Go live on a specific item, by index + + ``servicemanager_list_request`` + Request the service list. Responds with servicemanager_list_response + containing a array of dictionaries + ``maindisplay_blank`` Blank the maindisplay window @@ -110,6 +138,9 @@ class EventReceiver(QtCore.QObject): ``videodisplay_stop`` Stop playing a media item + ``videodisplay_background`` + Replace the background video + ``theme_update_list`` send out message with new themes @@ -174,6 +205,10 @@ class EventReceiver(QtCore.QObject): ``bibles_stop_import`` Stops the Bible Import + ``remotes_poll_request`` + Waits for openlp to do something "interesting" and sends a + remotes_poll_response signal when it does + """ def __init__(self): """ diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 83937160e..36cc738b8 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -98,7 +98,7 @@ class MediaManagerItem(QtGui.QWidget): """ QtGui.QWidget.__init__(self) self.parent = parent - self.settings_section = title.lower() + self.settingsSection = title.lower() if type(icon) is QtGui.QIcon: self.icon = icon elif type(icon) is types.StringType: @@ -331,15 +331,15 @@ class MediaManagerItem(QtGui.QWidget): def onFileClick(self): files = QtGui.QFileDialog.getOpenFileNames( self, self.OnNewPrompt, - SettingsManager.get_last_dir(self.settings_section), + SettingsManager.get_last_dir(self.settingsSection), self.OnNewFileMasks) log.info(u'New files(s) %s', unicode(files)) if files: self.loadList(files) dir = os.path.split(unicode(files[0]))[0] - SettingsManager.set_last_dir(self.settings_section, dir) - SettingsManager.set_list(self.settings_section, - self.settings_section, self.getFileList()) + SettingsManager.set_last_dir(self.settingsSection, dir) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def getFileList(self): count = 0 @@ -429,7 +429,7 @@ class MediaManagerItem(QtGui.QWidget): service_item = self.buildServiceItem() if service_item: service_item.from_plugin = False - self.parent.service_manager.addServiceItem(service_item, + self.parent.service_manager.addServiceItem(service_item, replace=self.remoteTriggered) else: items = self.ListView.selectedIndexes() @@ -454,7 +454,7 @@ class MediaManagerItem(QtGui.QWidget): 'You must select an existing service item to add to.')) elif self.title.lower() == service_item.name.lower(): self.generateSlideData(service_item) - self.parent.service_manager.addServiceItem(service_item, + self.parent.service_manager.addServiceItem(service_item, replace=True) else: #Turn off the remote edit update message indicator diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index c7a257700..ebb38615d 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -51,7 +51,7 @@ class Plugin(QtCore.QObject): ``version`` The version number of this iteration of the plugin. - ``settings_section`` + ``settingsSection`` The namespace to store settings for the plugin. ``icon`` @@ -116,7 +116,7 @@ class Plugin(QtCore.QObject): self.name = name if version: self.version = version - self.settings_section = self.name.lower() + self.settingsSection = self.name.lower() self.icon = None self.weight = 0 self.status = PluginStatus.Inactive @@ -147,7 +147,7 @@ class Plugin(QtCore.QObject): Sets the status of the plugin """ self.status = QtCore.QSettings().value( - self.settings_section + u'/status', + self.settingsSection + u'/status', QtCore.QVariant(PluginStatus.Inactive)).toInt()[0] def toggle_status(self, new_status): @@ -156,7 +156,7 @@ class Plugin(QtCore.QObject): """ self.status = new_status QtCore.QSettings().setValue( - self.settings_section + u'/status', QtCore.QVariant(self.status)) + self.settingsSection + u'/status', QtCore.QVariant(self.status)) def is_active(self): """ @@ -215,13 +215,16 @@ class Plugin(QtCore.QObject): """ pass - def process_add_service_event(self): + def process_add_service_event(self, replace=False): """ Generic Drag and drop handler triggered from service_manager. """ log.debug(u'process_add_service_event event called for plugin %s' % self.name) - self.media_item.onAddClick() + if replace: + self.media_item.onAddEditClick() + else: + self.media_item.onAddClick() def about(self): """ diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 43db25d64..cfb0e2bc2 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -48,8 +48,8 @@ class Renderer(object): self.theme_name = None self._theme = None self._bg_image_filename = None - self._frame = None - self._frameOp = None + self.frame = None + self.frame_opaque = None self.bg_frame = None self.bg_image = None @@ -89,10 +89,10 @@ class Renderer(object): """ log.debug(u'set bg image %s', filename) self._bg_image_filename = unicode(filename) - if self._frame: + if self.frame: self.bg_image = resize_image(self._bg_image_filename, - self._frame.width(), - self._frame.height()) + self.frame.width(), + self.frame.height()) def set_frame_dest(self, frame_width, frame_height, preview=False): """ @@ -111,14 +111,13 @@ class Renderer(object): self.bg_frame = None log.debug(u'set frame dest (frame) w %d h %d', frame_width, frame_height) - self._frame = QtGui.QImage(frame_width, frame_height, + self.frame = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) - self._frameOp = QtGui.QImage(frame_width, frame_height, + self.frame_opaque = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) if self._bg_image_filename and not self.bg_image: self.bg_image = resize_image(self._bg_image_filename, - self._frame.width(), - self._frame.height()) + self.frame.width(), self.frame.height()) if self.bg_frame is None: self._generate_background_frame() @@ -223,7 +222,7 @@ class Renderer(object): ``rect_footer`` The footer text block. """ - log.debug(u'set_text_rectangle %s , %s' %(rect_main, rect_footer) ) + log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer)) self._rect = rect_main self._rect_footer = rect_footer @@ -243,9 +242,9 @@ class Renderer(object): if footer_lines: bbox1 = self._render_lines_unaligned(footer_lines, True) # reset the frame. first time do not worry about what you paint on. - self._frame = QtGui.QImage(self.bg_frame) + self.frame = QtGui.QImage(self.bg_frame) if self._theme.display_slideTransition: - self._frameOp = QtGui.QImage(self.bg_frame) + self.frame_opaque = QtGui.QImage(self.bg_frame) x, y = self._correctAlignment(self._rect, bbox) bbox = self._render_lines_unaligned(lines, False, (x, y), True) if footer_lines: @@ -253,9 +252,9 @@ class Renderer(object): (self._rect_footer.left(), self._rect_footer.top()), True) log.debug(u'generate_frame_from_lines - Finish') if self._theme.display_slideTransition: - return {u'main':self._frame, u'trans':self._frameOp} + return {u'main':self.frame, u'trans':self.frame_opaque} else: - return {u'main':self._frame, u'trans':None} + return {u'main':self.frame, u'trans':None} def _generate_background_frame(self): """ @@ -265,36 +264,36 @@ class Renderer(object): assert(self._theme) if self._theme.background_mode == u'transparent': self.bg_frame = \ - QtGui.QPixmap(self._frame.width(), self._frame.height()) + QtGui.QPixmap(self.frame.width(), self.frame.height()) self.bg_frame.fill(QtCore.Qt.transparent) else: - self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + self.bg_frame = QtGui.QImage(self.frame.width(), + self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied) log.debug(u'render background %s start', self._theme.background_type) painter = QtGui.QPainter() painter.begin(self.bg_frame) if self._theme.background_mode == u'transparent': - painter.fillRect(self._frame.rect(), QtCore.Qt.transparent) + painter.fillRect(self.frame.rect(), QtCore.Qt.transparent) else: if self._theme.background_type == u'solid': - painter.fillRect(self._frame.rect(), + painter.fillRect(self.frame.rect(), QtGui.QColor(self._theme.background_color)) elif self._theme.background_type == u'gradient': # gradient gradient = None if self._theme.background_direction == u'horizontal': - w = int(self._frame.width()) / 2 + w = int(self.frame.width()) / 2 # vertical gradient = QtGui.QLinearGradient(w, 0, w, - self._frame.height()) + self.frame.height()) elif self._theme.background_direction == u'vertical': - h = int(self._frame.height()) / 2 + h = int(self.frame.height()) / 2 # Horizontal - gradient = QtGui.QLinearGradient(0, h, self._frame.width(), + gradient = QtGui.QLinearGradient(0, h, self.frame.width(), h) else: - w = int(self._frame.width()) / 2 - h = int(self._frame.height()) / 2 + w = int(self.frame.width()) / 2 + h = int(self.frame.height()) / 2 # Circular gradient = QtGui.QRadialGradient(w, h, w) gradient.setColorAt(0, @@ -303,8 +302,8 @@ class Renderer(object): QtGui.QColor(self._theme.background_endColor)) painter.setBrush(QtGui.QBrush(gradient)) rectPath = QtGui.QPainterPath() - max_x = self._frame.width() - max_y = self._frame.height() + max_x = self.frame.width() + max_y = self.frame.height() rectPath.moveTo(0, 0) rectPath.lineTo(0, max_y) rectPath.lineTo(max_x, max_y) @@ -313,7 +312,7 @@ class Renderer(object): painter.drawPath(rectPath) elif self._theme.background_type == u'image': # image - painter.fillRect(self._frame.rect(), QtCore.Qt.black) + painter.fillRect(self.frame.rect(), QtCore.Qt.black) if self.bg_image: painter.drawImage(0, 0, self.bg_image) painter.end() @@ -379,7 +378,7 @@ class Renderer(object): retval = QtCore.QRect(x, y, brx - x, bry - y) if self._debug: painter = QtGui.QPainter() - painter.begin(self._frame) + painter.begin(self.frame) painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255))) painter.drawRect(retval) painter.end() @@ -415,11 +414,11 @@ class Renderer(object): starty = y rightextent = None self.painter = QtGui.QPainter() - self.painter.begin(self._frame) + self.painter.begin(self.frame) self.painter.setRenderHint(QtGui.QPainter.Antialiasing) if self._theme.display_slideTransition: self.painter2 = QtGui.QPainter() - self.painter2.begin(self._frameOp) + self.painter2.begin(self.frame_opaque) self.painter2.setRenderHint(QtGui.QPainter.Antialiasing) self.painter2.setOpacity(0.7) # dont allow alignment messing with footers @@ -550,8 +549,8 @@ class Renderer(object): path = QtGui.QPainterPath() path.addText(QtCore.QPointF(x, rowpos), font, line) self.painter.setBrush(self.painter.pen().brush()) - self.painter.setPen(QtGui.QPen( - QtGui.QColor(self._theme.display_outline_color), outline_size)) + self.painter.setPen(QtGui.QPen(QtGui.QColor( + self._theme.display_outline_color), outline_size)) self.painter.drawPath(path) self.painter.setPen(pen) self.painter.drawText(x, rowpos, line) @@ -582,4 +581,4 @@ class Renderer(object): """ image.save(u'renderer.png', u'png') if image2: - image2.save(u'renderer2.png', u'png') + image2.save(u'renderer2.png', u'png') \ No newline at end of file diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 25f08717f..2f6d973e2 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -48,6 +48,7 @@ class ItemCapabilities(object): AllowsMaintain = 3 RequiresMedia = 4 AllowsLoop = 5 + AllowsAdditions = 6 class ServiceItem(object): """ diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index 8b9cc4261..0b862d9f8 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -40,7 +40,7 @@ class SettingsTab(QtGui.QWidget): QtGui.QWidget.__init__(self) self.tabTitle = title self.tabTitleVisible = None - self.settings_section = self.tabTitle.lower() + self.settingsSection = self.tabTitle.lower() self.setupUi() self.retranslateUi() self.initialise() diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index c43d27cb5..fab72c312 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -133,7 +133,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.SIGNAL(u'editingFinished()'), self.onOutlineSpinBoxChanged) QtCore.QObject.connect(self.SlideTransitionCheckedBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckedBoxChanged) + QtCore.SIGNAL(u'stateChanged(int)'), + self.onSlideTransitionCheckedBoxChanged) def accept(self): new_theme = ThemeXML() @@ -145,10 +146,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): new_theme.add_background_transparent() else: if self.theme.background_type == u'solid': - new_theme.add_background_solid( \ + new_theme.add_background_solid( unicode(self.theme.background_color)) elif self.theme.background_type == u'gradient': - new_theme.add_background_gradient( \ + new_theme.add_background_gradient( unicode(self.theme.background_startColor), unicode(self.theme.background_endColor), self.theme.background_direction) @@ -158,7 +159,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): new_theme.add_background_image(filename) save_to = os.path.join(self.path, theme_name, filename) save_from = self.theme.background_filename - new_theme.add_font(unicode(self.theme.font_main_name), unicode(self.theme.font_main_color), unicode(self.theme.font_main_proportion), @@ -182,7 +182,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): unicode(self.theme.font_footer_x), unicode(self.theme.font_footer_y), unicode(self.theme.font_footer_width), - unicode(self.theme.font_footer_height) ) + unicode(self.theme.font_footer_height)) new_theme.add_display(unicode(self.theme.display_shadow), unicode(self.theme.display_shadow_color), unicode(self.theme.display_outline), diff --git a/openlp/core/ui/displaytab.py b/openlp/core/ui/displaytab.py index b38ff0842..38a0baa91 100644 --- a/openlp/core/ui/displaytab.py +++ b/openlp/core/ui/displaytab.py @@ -178,7 +178,7 @@ class DisplayTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.Xpos.setText(unicode(self.screens.current[u'size'].x())) self.Ypos.setText(unicode(self.screens.current[u'size'].y())) self.Height.setText(unicode(self.screens.current[u'size'].height())) @@ -208,7 +208,7 @@ class DisplayTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) settings.setValue('x position', QtCore.QVariant(self.XposEdit.text())) settings.setValue('y position', diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 4616a62ba..ac4f92336 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -42,7 +42,7 @@ class GeneralTab(SettingsTab): If not set before default to last screen. """ settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.MonitorNumber = settings.value(u'monitor', QtCore.QVariant(self.screens.monitor_number)).toInt()[0] self.screens.set_current_display(self.MonitorNumber) @@ -229,7 +229,7 @@ class GeneralTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) for screen in self.screens.screen_list: screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1) @@ -268,7 +268,7 @@ class GeneralTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) settings.setValue(u'monitor', QtCore.QVariant(self.MonitorNumber)) settings.setValue(u'display on monitor', QtCore.QVariant(self.DisplayOnMonitor)) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 1907a55b0..af52e5ffd 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -34,7 +34,6 @@ from openlp.core.ui import HideMode log = logging.getLogger(__name__) - class DisplayManager(QtGui.QWidget): """ Wrapper class to hold the display widgets. @@ -144,16 +143,16 @@ class MainDisplay(DisplayWidget): """ Sets up the screen on a particular screen. """ - log.debug(u'Setup %s for %s ' %(self.screens, - self.screens.monitor_number)) + log.debug(u'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.display_alert.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(), - self.screen[u'size'].height()) + self.display_image.resize( + self.screen[u'size'].width(), self.screen[u'size'].height()) + self.display_text.resize( + self.screen[u'size'].width(), self.screen[u'size'].height()) self.setGeometry(self.screen[u'size']) #Build a custom splash screen self.InitialFrame = QtGui.QImage( @@ -179,8 +178,8 @@ class MainDisplay(DisplayWidget): painter.begin(self.blankFrame) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) #build a blank transparent image - self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), - self.screen[u'size'].height()) + self.transparent = QtGui.QPixmap( + self.screen[u'size'].width(), self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) self.display_alert.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent) @@ -220,19 +219,21 @@ class MainDisplay(DisplayWidget): if mode == HideMode.Screen: self.display_image.setPixmap(self.transparent) elif mode == HideMode.Blank: - self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) + self.display_image.setPixmap( + QtGui.QPixmap.fromImage(self.blankFrame)) else: if self.parent.renderManager.renderer.bg_frame: - self.display_image.setPixmap(QtGui.QPixmap.fromImage(\ + self.display_image.setPixmap(QtGui.QPixmap.fromImage( self.parent.renderManager.renderer.bg_frame)) else: - self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) + self.display_image.setPixmap( + QtGui.QPixmap.fromImage(self.blankFrame)) self.moveToTop() def moveToTop(self): log.debug(u'moveToTop') - self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint \ - | QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) + self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | + QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) self.show() def showDisplay(self): @@ -254,9 +255,8 @@ class MainDisplay(DisplayWidget): def addImageWithText(self, frame): log.debug(u'addImageWithText') - frame = resize_image(frame, - self.screen[u'size'].width(), - self.screen[u'size'].height() ) + frame = resize_image( + frame, self.screen[u'size'].width(), self.screen[u'size'].height()) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) self.moveToTop() @@ -334,14 +334,14 @@ class VideoDisplay(Phonon.VideoWidget): self.parent = parent self.screens = screens self.hidden = False - self.background = False + self.message = None self.mediaObject = Phonon.MediaObject() self.setAspectRatio(aspect) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) Phonon.createPath(self.mediaObject, self) Phonon.createPath(self.mediaObject, self.audioObject) - self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint \ - | QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) + self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint | + QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'maindisplay_hide'), self.mediaHide) QtCore.QObject.connect(Receiver.get_receiver(), @@ -376,7 +376,7 @@ class VideoDisplay(Phonon.VideoWidget): """ Sets up the screen on a particular screen. """ - log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens, + log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens, self.screens.monitor_number)) self.screen = self.screens.current #Sort out screen locations and sizes @@ -389,57 +389,88 @@ class VideoDisplay(Phonon.VideoWidget): self.setVisible(False) self.primary = True - def onMediaBackground(self, message): + def onMediaBackground(self, message=None): + """ + Play a video triggered from the video plugin with the + file name passed in on the event. + Also triggered from the Finish event so the video will loop + if it is triggered from the plugin + """ + log.debug(u'VideoDisplay Queue new media message %s' % message) + #If not file take the stored one if not message: message = self.message - log.debug(u'VideoDisplay Queue new media message %s' % message) - source = self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) - self.message = message - self.background = True - self._play() + # still no file name then stop as it was a normal video stopping + if message: + self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) + self.message = message + self._play() def onMediaQueue(self, message): + """ + Set up a video to play from the serviceitem. + """ log.debug(u'VideoDisplay Queue new media message %s' % message) file = os.path.join(message[0].get_frame_path(), message[0].get_frame_title()) - source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self._play() def onMediaPlay(self): + """ + Respond to the Play button on the slide controller unless the display + has been hidden by the slidecontroller + """ if not self.hidden: log.debug(u'VideoDisplay Play the new media, Live ') self._play() def _play(self): + """ + We want to play the video so start it and display the screen + """ log.debug(u'VideoDisplay _play called') self.mediaObject.play() self.setVisible(True) self.showFullScreen() def onMediaPause(self): + """ + Pause the video and refresh the screen + """ log.debug(u'VideoDisplay Media paused by user') self.mediaObject.pause() self.show() def onMediaStop(self): + """ + Stop the video and clean up + """ log.debug(u'VideoDisplay Media stopped by user') - self.background = False self.message = None self.mediaObject.stop() self.onMediaFinish() def onMediaFinish(self): + """ + Clean up the Object queue + """ log.debug(u'VideoDisplay Reached end of media playlist') self.mediaObject.clearQueue() self.setVisible(False) def mediaHide(self): + """ + Hide the video display + """ self.mediaObject.pause() self.hidden = True self.setVisible(False) def mediaShow(self): + """ + Show the video disaply if it was already hidden + """ if self.hidden: self.hidden = False self._play() - diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 385369b04..de8da9b66 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -444,10 +444,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.applicationVersion = applicationVersion # Set up settings sections for the main application # (not for use by plugins) - self.ui_settings_section = u'user interface' - self.general_settings_section = u'general' - self.service_settings_section = u'servicemanager' - self.songs_settings_section = u'songs' + self.uiSettingsSection = u'user interface' + self.generalSettingsSection = u'general' + self.serviceSettingsSection = u'servicemanager' + self.songsSettingsSection = u'songs' self.serviceNotSaved = False self.settingsmanager = SettingsManager(screens) self.displayManager = DisplayManager(screens) @@ -606,7 +606,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.displayManager.mainDisplay.setFocus() self.activateWindow() if QtCore.QSettings().value( - self.general_settings_section + u'/auto open', + self.generalSettingsSection + u'/auto open', QtCore.QVariant(False)).toBool(): self.ServiceManagerContents.onLoadService(True) @@ -616,7 +616,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Triggered by delay thread. """ settings = QtCore.QSettings() - settings.beginGroup(self.general_settings_section) + settings.beginGroup(self.generalSettingsSection) if settings.value(u'screen blank', QtCore.QVariant(False)).toBool() \ and settings.value(u'blank warning', QtCore.QVariant(False)).toBool(): self.LiveController.onBlankDisplay(True) @@ -761,10 +761,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def loadSettings(self): log.debug(u'Loading QSettings') settings = QtCore.QSettings() - settings.beginGroup(self.general_settings_section) + settings.beginGroup(self.generalSettingsSection) self.recentFiles = settings.value(u'recent files').toStringList() settings.endGroup() - settings.beginGroup(self.ui_settings_section) + settings.beginGroup(self.uiSettingsSection) self.move(settings.value(u'main window position', QtCore.QVariant(QtCore.QPoint(0, 0))).toPoint()) self.restoreGeometry( @@ -775,12 +775,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def saveSettings(self): log.debug(u'Saving QSettings') settings = QtCore.QSettings() - settings.beginGroup(self.general_settings_section) + settings.beginGroup(self.generalSettingsSection) recentFiles = QtCore.QVariant(self.recentFiles) \ if self.recentFiles else QtCore.QVariant() settings.setValue(u'recent files', recentFiles) settings.endGroup() - settings.beginGroup(self.ui_settings_section) + settings.beginGroup(self.uiSettingsSection) settings.setValue(u'main window position', QtCore.QVariant(self.pos())) settings.setValue(u'main window state', @@ -810,7 +810,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def addRecentFile(self, filename): recentFileCount = QtCore.QSettings().value( - self.general_settings_section + u'/max recent files', + self.generalSettingsSection + u'/max recent files', QtCore.QVariant(4)).toInt()[0] if filename and not self.recentFiles.contains(filename): self.recentFiles.prepend(QtCore.QString(filename)) diff --git a/openlp/core/ui/mediadockmanager.py b/openlp/core/ui/mediadockmanager.py index aece0729e..782383cd4 100644 --- a/openlp/core/ui/mediadockmanager.py +++ b/openlp/core/ui/mediadockmanager.py @@ -45,7 +45,7 @@ class MediaDockManager(object): log.debug(u'Inserting %s dock' % media_item.title) match = False for dock_index in range(0, self.media_dock.count()): - if self.media_dock.widget(dock_index).settings_section == \ + if self.media_dock.widget(dock_index).settingsSection == \ media_item.title.lower(): match = True break @@ -56,6 +56,6 @@ class MediaDockManager(object): log.debug(u'remove %s dock' % name) for dock_index in range(0, self.media_dock.count()): if self.media_dock.widget(dock_index): - if self.media_dock.widget(dock_index).settings_section == name: + if self.media_dock.widget(dock_index).settingsSection == name: self.media_dock.widget(dock_index).hide() self.media_dock.removeItem(dock_index) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 56ac3e8b4..03cdbcecc 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1,4 +1,3 @@ -import os.path # -*- coding: utf-8 -*- # vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 @@ -85,7 +84,7 @@ class ServiceManagerList(QtGui.QTreeWidget): mimeData = QtCore.QMimeData() drag.setMimeData(mimeData) mimeData.setText(u'ServiceManager') - dropAction = drag.start(QtCore.Qt.CopyAction) + drag.start(QtCore.Qt.CopyAction) class ServiceManager(QtGui.QWidget): """ @@ -188,19 +187,31 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'servicemanager_previous_item'), self.previousItem) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'servicemanager_set_item'), self.onSetItem) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems) # Last little bits of setting up self.service_theme = unicode(QtCore.QSettings().value( - self.parent.service_settings_section + u'/service theme', + self.parent.serviceSettingsSection + u'/service theme', QtCore.QVariant(u'')).toString()) self.servicePath = AppLocation.get_section_data_path(u'servicemanager') + #build the drag and drop context menu + self.dndMenu = QtGui.QMenu() + self.newAction = self.dndMenu.addAction(self.trUtf8('&Add New Item')) + self.newAction.setIcon(build_icon(u':/general/general_edit.png')) + self.addToAction = self.dndMenu.addAction(self.trUtf8('&Add to Selected Item')) + self.addToAction.setIcon(build_icon(u':/general/general_edit.png')) #build the context menu self.menu = QtGui.QMenu() self.editAction = self.menu.addAction(self.trUtf8('&Edit Item')) self.editAction.setIcon(build_icon(u':/general/general_edit.png')) self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item')) - self.editAction.setIcon(build_icon(u':/general/general_edit.png')) + self.maintainAction.setIcon(build_icon(u':/general/general_edit.png')) self.notesAction = self.menu.addAction(self.trUtf8('&Notes')) self.notesAction.setIcon(build_icon(u':/services/service_notes.png')) self.deleteAction = self.menu.addAction( @@ -290,6 +301,41 @@ class ServiceManager(QtGui.QWidget): lookFor = 1 serviceIterator += 1 + def previousItem(self): + """ + Called by the SlideController to select the + previous service item + """ + if len(self.ServiceManagerList.selectedItems()) == 0: + return + selected = self.ServiceManagerList.selectedItems()[0] + prevItem = None + serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList) + while serviceIterator.value(): + if serviceIterator.value() == selected: + if prevItem: + self.ServiceManagerList.setCurrentItem(prevItem) + self.makeLive() + return + if serviceIterator.value().parent() is None: + prevItem = serviceIterator.value() + serviceIterator += 1 + + def onSetItem(self, message): + """ + Called by a signal to select a specific item + """ + self.setItem(int(message[0])) + + def setItem(self, index): + """ + Makes a specific item in the service live + """ + if index >= 0 and index < self.ServiceManagerList.topLevelItemCount: + item = self.ServiceManagerList.topLevelItem(index) + self.ServiceManagerList.setCurrentItem(item) + self.makeLive() + def onMoveSelectionUp(self): """ Moves the selection up the window @@ -405,7 +451,7 @@ class ServiceManager(QtGui.QWidget): Clear the list to create a new service """ if self.parent.serviceNotSaved and QtCore.QSettings().value( - self.parent.general_settings_section + u'/save prompt', + self.parent.generalSettingsSection + u'/save prompt', QtCore.QVariant(False)).toBool(): ret = QtGui.QMessageBox.question(self, self.trUtf8('Save Changes to Service?'), @@ -490,11 +536,11 @@ class ServiceManager(QtGui.QWidget): if not quick or self.isNew: filename = QtGui.QFileDialog.getSaveFileName(self, self.trUtf8(u'Save Service'), - SettingsManager.get_last_dir(self.parent.service_settings_section), + SettingsManager.get_last_dir(self.parent.serviceSettingsSection), self.trUtf8(u'OpenLP Service Files (*.osz)')) else: filename = SettingsManager.get_last_dir( - self.parent.service_settings_section) + self.parent.serviceSettingsSection) if filename: splittedFile = filename.split(u'.') if splittedFile[-1] != u'osz': @@ -502,7 +548,7 @@ class ServiceManager(QtGui.QWidget): filename = unicode(filename) self.isNew = False SettingsManager.set_last_dir( - self.parent.service_settings_section, + self.parent.serviceSettingsSection, os.path.split(filename)[0]) service = [] servicefile = filename + u'.osd' @@ -545,12 +591,12 @@ class ServiceManager(QtGui.QWidget): def onLoadService(self, lastService=False): if lastService: filename = SettingsManager.get_last_dir( - self.parent.service_settings_section) + self.parent.serviceSettingsSection) else: filename = QtGui.QFileDialog.getOpenFileName( self, self.trUtf8('Open Service'), SettingsManager.get_last_dir( - self.parent.service_settings_section), u'Services (*.osz)') + self.parent.serviceSettingsSection), u'Services (*.osz)') self.loadService(filename) def loadService(self, filename=None): @@ -580,7 +626,7 @@ class ServiceManager(QtGui.QWidget): name = filename.split(os.path.sep) if filename: SettingsManager.set_last_dir( - self.parent.service_settings_section, + self.parent.serviceSettingsSection, os.path.split(filename)[0]) zip = None f = None @@ -651,7 +697,7 @@ class ServiceManager(QtGui.QWidget): self.service_theme = unicode(self.ThemeComboBox.currentText()) self.parent.RenderManager.set_service_theme(self.service_theme) QtCore.QSettings().setValue( - self.parent.service_settings_section + u'/service theme', + self.parent.serviceSettingsSection + u'/service theme', QtCore.QVariant(self.service_theme)) self.regenerateServiceItems() @@ -735,7 +781,7 @@ class ServiceManager(QtGui.QWidget): self.parent.LiveController.addServiceManagerItem( self.serviceItems[item][u'service_item'], count) if QtCore.QSettings().value( - self.parent.general_settings_section + u'/auto preview', + self.parent.generalSettingsSection + u'/auto preview', QtCore.QVariant(False)).toBool(): item += 1 if self.serviceItems and item < len(self.serviceItems) and \ @@ -796,8 +842,9 @@ class ServiceManager(QtGui.QWidget): if link.hasText(): plugin = event.mimeData().text() item = self.ServiceManagerList.itemAt(event.pos()) + #ServiceManager started the drag and drop if plugin == u'ServiceManager': - startpos, startCount = self.findServiceItem() + startpos, startCount = self.findServiceItem() if item is None: endpos = len(self.serviceItems) else: @@ -811,11 +858,28 @@ class ServiceManager(QtGui.QWidget): self.serviceItems.insert(newpos, serviceItem) self.repaintServiceList(endpos, startCount) else: + #we are not over anything so drop + replace = False if item == None: self.droppos = len(self.serviceItems) else: - self.droppos = self._getParentItemData(item) - Receiver.send_message(u'%s_add_service_item' % plugin) + #we are over somthing so lets investigate + pos = self._getParentItemData(item) - 1 + serviceItem = self.serviceItems[pos] + if plugin == serviceItem[u'service_item'].name \ + and serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsAdditions): + action = self.dndMenu.exec_(QtGui.QCursor.pos()) + #New action required + if action == self.newAction: + self.droppos = self._getParentItemData(item) + #Append to existing action + if action == self.addToAction: + self.droppos = self._getParentItemData(item) + item.setSelected(True) + replace = True + else: + self.droppos = self._getParentItemData(item) + Receiver.send_message(u'%s_add_service_item' % plugin, replace) def updateThemeList(self, theme_list): """ @@ -856,3 +920,20 @@ class ServiceManager(QtGui.QWidget): return item.data(0, QtCore.Qt.UserRole).toInt()[0] else: return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] + + def listRequest(self, message=None): + data = [] + curindex, count = self.findServiceItem() + if curindex >= 0 and curindex < len(self.serviceItems): + curitem = self.serviceItems[curindex] + else: + curitem = None + for item in self.serviceItems: + service_item = item[u'service_item'] + data_item = {} + data_item[u'title'] = unicode(service_item.title) + data_item[u'plugin'] = unicode(service_item.name) + data_item[u'notes'] = unicode(service_item.notes) + data_item[u'selected'] = (item == curitem) + data.append(data_item) + Receiver.send_message(u'servicemanager_list_response', data) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index a35257f75..c0d0d915f 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -200,7 +200,7 @@ class SlideController(QtGui.QWidget): if isLive: self.Toolbar.addToolbarSeparator(u'Loop Separator') self.Toolbar.addToolbarButton( - u'Start Loop', u':/media/media_time.png', + u'Start Loop', u':/media/media_time.png', self.trUtf8('Start continuous loop'), self.onStartLoop) self.Toolbar.addToolbarButton( u'Stop Loop', u':/media/media_stop.png', @@ -217,13 +217,13 @@ class SlideController(QtGui.QWidget): #Build a Media ToolBar self.Mediabar = OpenLPToolbar(self) self.Mediabar.addToolbarButton( - u'Media Start', u':/slides/media_playback_start.png', + u'Media Start', u':/slides/media_playback_start.png', self.trUtf8('Start playing media'), self.onMediaPlay) self.Mediabar.addToolbarButton( - u'Media Pause', u':/slides/media_playback_pause.png', + u'Media Pause', u':/slides/media_playback_pause.png', self.trUtf8('Start playing media'), self.onMediaPause) self.Mediabar.addToolbarButton( - u'Media Stop', u':/slides/media_playback_stop.png', + u'Media Stop', u':/slides/media_playback_stop.png', self.trUtf8('Start playing media'), self.onMediaStop) if self.isLive: self.blankButton = self.Mediabar.addToolbarButton( @@ -338,6 +338,18 @@ class SlideController(QtGui.QWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_%s_change' % self.type_prefix), self.onSlideChange) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_set' % self.type_prefix), + self.onSlideSelectedIndex) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_blank' % self.type_prefix), + self.onSlideBlank) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.type_prefix), + self.onSlideUnblank) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.type_prefix), + self.onTextRequest) QtCore.QObject.connect(self.Splitter, QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter) QtCore.QObject.connect(Receiver.get_receiver(), @@ -396,7 +408,7 @@ class SlideController(QtGui.QWidget): if item.is_text(): self.Toolbar.makeWidgetsInvisible(self.loop_list) if QtCore.QSettings().value( - self.parent.songs_settings_section + u'/show songbar', + self.parent.songsSettingsSection + u'/show songbar', QtCore.QVariant(True)).toBool() and len(self.slideList) > 0: self.Toolbar.makeWidgetsVisible([u'Song Menu']) if item.is_capable(ItemCapabilities.AllowsLoop) and \ @@ -556,12 +568,30 @@ class SlideController(QtGui.QWidget): self.enableToolBar(serviceItem) self.onSlideSelected() self.PreviewListWidget.setFocus() - Receiver.send_message(u'%s_%s_started' % - (self.serviceItem.name.lower(), - 'live' if self.isLive else 'preview'), + Receiver.send_message(u'slidecontroller_%s_started' % self.type_prefix, [serviceItem]) log.log(15, u'Display Rendering took %4s' % (time.time() - before)) + def onTextRequest(self): + """ + Return the text for the current item in controller + """ + data = [] + if self.serviceItem: + for framenumber, frame in enumerate(self.serviceItem.get_frames()): + data_item = {} + if self.serviceItem.is_text(): + data_item[u'tag'] = unicode(frame[u'verseTag']) + data_item[u'text'] = unicode(frame[u'text']) + else: + data_item[u'tag'] = unicode(framenumber) + data_item[u'text'] = u'' + data_item[u'selected'] = \ + (self.PreviewListWidget.currentRow() == framenumber) + data.append(data_item) + Receiver.send_message(u'slidecontroller_%s_text_response' + % self.type_prefix, data) + #Screen event methods def onSlideSelectedFirst(self): """ @@ -577,6 +607,33 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.selectRow(0) self.onSlideSelected() + def onSlideSelectedIndex(self, message): + """ + Go to the requested slide + """ + index = int(message[0]) + if not self.serviceItem: + return + Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive, index]) + if self.serviceItem.is_command(): + self.updatePreview() + else: + self.PreviewListWidget.selectRow(index) + self.onSlideSelected() + + def onSlideBlank(self): + """ + Handle the slidecontroller blank event + """ + self.onBlankDisplay(True) + + def onSlideUnblank(self): + """ + Handle the slidecontroller unblank event + """ + self.onBlankDisplay(False) + def onBlankDisplay(self, checked): """ Handle the blank screen button @@ -585,7 +642,7 @@ class SlideController(QtGui.QWidget): self.hideButton.setChecked(False) self.themeButton.setChecked(False) QtCore.QSettings().setValue( - self.parent.general_settings_section + u'/screen blank', + self.parent.generalSettingsSection + u'/screen blank', QtCore.QVariant(checked)) if checked: Receiver.send_message(u'maindisplay_hide', HideMode.Blank) @@ -636,7 +693,6 @@ class SlideController(QtGui.QWidget): % self.serviceItem.name.lower(), [self.serviceItem, self.isLive]) - def onSlideSelected(self): """ Generate the preview when you click on a slide. @@ -666,6 +722,8 @@ class SlideController(QtGui.QWidget): if self.isLive: self.mainDisplay.frameView(frame, True) self.selectedRow = row + Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix, + row) def onSlideChange(self, row): """ @@ -673,6 +731,8 @@ class SlideController(QtGui.QWidget): """ self.PreviewListWidget.selectRow(row) self.updatePreview() + Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix, + row) def updatePreview(self): rm = self.parent.RenderManager @@ -727,7 +787,7 @@ class SlideController(QtGui.QWidget): if not self.serviceItem: return Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(), - [self.serviceItem, self.isLive]) + [self.serviceItem, self.isLive]) if self.serviceItem.is_command(): self.updatePreview() else: diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index b6ed2366d..4b356f758 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -47,7 +47,7 @@ class ThemeManager(QtGui.QWidget): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) self.parent = parent - self.settings_section = u'themes' + self.settingsSection = u'themes' self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) self.Layout.setMargin(0) @@ -106,14 +106,14 @@ class ThemeManager(QtGui.QWidget): QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab) #Variables self.themelist = [] - self.path = AppLocation.get_section_data_path(self.settings_section) + self.path = AppLocation.get_section_data_path(self.settingsSection) self.checkThemesExists(self.path) self.thumbPath = os.path.join(self.path, u'thumbnails') self.checkThemesExists(self.thumbPath) self.amendThemeForm.path = self.path # Last little bits of setting up self.global_theme = unicode(QtCore.QSettings().value( - self.settings_section + u'/global theme', + self.settingsSection + u'/global theme', QtCore.QVariant(u'')).toString()) def changeGlobalFromTab(self, themeName): @@ -147,7 +147,7 @@ class ThemeManager(QtGui.QWidget): name = u'%s (%s)' % (self.global_theme, self.trUtf8('default')) self.ThemeListWidget.item(count).setText(name) QtCore.QSettings().setValue( - self.settings_section + u'/global theme', + self.settingsSection + u'/global theme', QtCore.QVariant(self.global_theme)) Receiver.send_message(u'theme_update_global', self.global_theme) self.pushThemes() @@ -170,7 +170,7 @@ class ThemeManager(QtGui.QWidget): def onDeleteTheme(self): self.global_theme = unicode(QtCore.QSettings().value( - self.settings_section + u'/global theme', + self.settingsSection + u'/global theme', QtCore.QVariant(u'')).toString()) item = self.ThemeListWidget.currentItem() if item: @@ -224,10 +224,10 @@ class ThemeManager(QtGui.QWidget): theme = unicode(item.data(QtCore.Qt.UserRole).toString()) path = QtGui.QFileDialog.getExistingDirectory(self, unicode(self.trUtf8('Save Theme - (%s)')) % theme, - SettingsManager.get_last_dir(self.settings_section, 1)) + SettingsManager.get_last_dir(self.settingsSection, 1)) path = unicode(path) if path: - SettingsManager.set_last_dir(self.settings_section, path, 1) + SettingsManager.set_last_dir(self.settingsSection, path, 1) themePath = os.path.join(path, theme + u'.theme') zip = None try: @@ -247,12 +247,12 @@ class ThemeManager(QtGui.QWidget): def onImportTheme(self): files = QtGui.QFileDialog.getOpenFileNames( self, self.trUtf8('Select Theme Import File'), - SettingsManager.get_last_dir(self.settings_section), u'Theme (*.*)') + SettingsManager.get_last_dir(self.settingsSection), u'Theme (*.*)') log.info(u'New Themes %s', unicode(files)) if files: for file in files: SettingsManager.set_last_dir( - self.settings_section, unicode(file)) + self.settingsSection, unicode(file)) self.unzipTheme(file, self.path) self.loadThemes() @@ -295,7 +295,7 @@ class ThemeManager(QtGui.QWidget): self.pushThemes() def pushThemes(self): - Receiver.send_message(u'theme_update_list', self.getThemes() ) + Receiver.send_message(u'theme_update_list', self.getThemes()) def getThemes(self): return self.themelist diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 09e6cadaa..dba07eb6d 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -124,7 +124,7 @@ class ThemesTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.theme_level = settings.value( u'theme level', QtCore.QVariant(ThemeLevel.Global)).toInt()[0] self.global_theme = unicode(settings.value( @@ -139,7 +139,7 @@ class ThemesTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) settings.setValue(u'theme level', QtCore.QVariant(self.theme_level)) settings.setValue(u'global theme', @@ -179,7 +179,7 @@ class ThemesTab(SettingsTab): """ #reload as may have been triggered by the ThemeManager self.global_theme = unicode(QtCore.QSettings().value( - self.settings_section + u'/global theme', + self.settingsSection + u'/global theme', QtCore.QVariant(u'')).toString()) self.DefaultComboBox.clear() for theme in theme_list: diff --git a/openlp/migration/migratesongs.py b/openlp/migration/migratesongs.py index a46f50a54..b43b1e68a 100644 --- a/openlp/migration/migratesongs.py +++ b/openlp/migration/migratesongs.py @@ -47,7 +47,7 @@ def init_models(url): mapper(TAuthor, temp_authors_table) mapper(Book, song_books_table) mapper(Song, songs_table, - properties={'authors': relation(Author, backref='songs', + properties={'authors': relation(Author, backref='songs', secondary=authors_songs_table), 'book': relation(Book, backref='songs'), 'topics': relation(Topic, backref='songs', @@ -156,13 +156,13 @@ class MigrateSongs(): print songs_temp.songtitle aa = self.session.execute( u'select * from songauthors_temp where songid =' + \ - unicode(songs_temp.songid) ) + unicode(songs_temp.songid)) for row in aa: a = row['authorid'] authors_temp = self.session.query(TAuthor).get(a) bb = self.session.execute( u'select * from authors where display_name = \"%s\"' % \ - unicode(authors_temp.authorname) ).fetchone() + unicode(authors_temp.authorname)).fetchone() if bb is None: author = Author() author.display_name = authors_temp.authorname diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index b3c72cc3f..f97540029 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -84,7 +84,7 @@ class alertsPlugin(Plugin): def togglealertsState(self): self.alertsActive = not self.alertsActive QtCore.QSettings().setValue( - self.settings_section + u'/active', + self.settingsSection + u'/active', QtCore.QVariant(self.alertsActive)) def onAlertsTrigger(self): diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index a933d49fd..35be3b7c2 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -46,7 +46,7 @@ class AlertsManager(QtCore.QObject): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'alerts_text'), self.displayAlert) + QtCore.SIGNAL(u'alerts_text'), self.onAlertText) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged) @@ -70,6 +70,16 @@ class AlertsManager(QtCore.QObject): self.parent.maindisplay.setAlertSize(self.alertScreenPosition,\ self.alertHeight) + def onAlertText(self, message): + """ + Called via a alerts_text event. Message is single element array + containing text + """ + if message: + self.displayAlert(message[0]) + else: + self.displayAlert(u'') + def displayAlert(self, text=u''): """ Called from the Alert Tab to display an alert diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index 53b8d2a7a..7cda09488 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -229,7 +229,7 @@ class AlertsTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.timeout = settings.value(u'timeout', QtCore.QVariant(5)).toInt()[0] self.font_color = unicode(settings.value( u'font color', QtCore.QVariant(u'#ffffff')).toString()) @@ -260,7 +260,7 @@ class AlertsTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.font_face = self.FontComboBox.currentFont().family() settings.setValue(u'background color', QtCore.QVariant(self.bg_color)) settings.setValue(u'font color', QtCore.QVariant(self.font_color)) diff --git a/openlp/plugins/bibles/forms/importwizardform.py b/openlp/plugins/bibles/forms/importwizardform.py index d3e8acd73..f5dbc8ee0 100644 --- a/openlp/plugins/bibles/forms/importwizardform.py +++ b/openlp/plugins/bibles/forms/importwizardform.py @@ -274,7 +274,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): def setDefaults(self): settings = QtCore.QSettings() - settings.beginGroup(self.bibleplugin.settings_section) + settings.beginGroup(self.bibleplugin.settingsSection) self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'csv_booksfile', QtCore.QVariant('')) @@ -345,11 +345,11 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): def getFileName(self, title, editbox): filename = QtGui.QFileDialog.getOpenFileName(self, title, - SettingsManager.get_last_dir(self.bibleplugin.settings_section, 1)) + SettingsManager.get_last_dir(self.bibleplugin.settingsSection, 1)) if filename: editbox.setText(filename) SettingsManager.set_last_dir( - self.bibleplugin.settings_section, filename, 1) + self.bibleplugin.settingsSection, filename, 1) def incrementProgressBar(self, status_text): log.debug(u'IncrementBar %s', status_text) diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index 7d3b7eb8c..80e0cef5e 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -189,7 +189,7 @@ class BiblesTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.show_new_chapters = settings.value( u'display new chapter', QtCore.QVariant(False)).toBool() self.display_style = settings.value( @@ -208,7 +208,7 @@ class BiblesTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) settings.setValue(u'display new chapter', QtCore.QVariant(self.show_new_chapters)) settings.setValue(u'display brackets', diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index c95884693..79a650541 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -111,7 +111,7 @@ class BibleDB(QtCore.QObject): ``old_filename`` The "dirty" file name or version name. """ - if not isinstance(old_filename, unicode): + if not isinstance(old_filename, unicode): old_filename = unicode(old_filename, u'utf-8') old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') return old_filename + u'.sqlite' diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index d8fe3e156..8a87288f3 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -109,12 +109,12 @@ class BibleManager(object): """ log.debug(u'Bible Initialising') self.parent = parent - self.settings_section = u'bibles' + self.settingsSection = u'bibles' self.web = u'Web' self.db_cache = None - self.path = AppLocation.get_section_data_path(self.settings_section) + self.path = AppLocation.get_section_data_path(self.settingsSection) self.proxy_name = unicode( - QtCore.QSettings().value(self.settings_section + u'/proxy name', + QtCore.QSettings().value(self.settingsSection + u'/proxy name', QtCore.QVariant(u'')).toString()) self.suffix = u'.sqlite' self.import_wizard = None @@ -128,7 +128,7 @@ class BibleManager(object): BibleDB class. """ log.debug(u'Reload bibles') - files = SettingsManager.get_files(self.settings_section, self.suffix) + files = SettingsManager.get_files(self.settingsSection, self.suffix) log.debug(u'Bible Files %s', files) self.db_cache = {} for filename in files: diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 228e39d5a..d6aadd09f 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -275,7 +275,7 @@ class BibleMediaItem(MediaManagerItem): self.SearchProgress.setObjectName(u'SearchProgress') def configUpdated(self): - if QtCore.QSettings().value(self.settings_section + u'/dual bibles', + if QtCore.QSettings().value(self.settingsSection + u'/dual bibles', QtCore.QVariant(False)).toBool(): self.AdvancedSecondBibleLabel.setVisible(True) self.AdvancedSecondBibleComboBox.setVisible(True) @@ -449,6 +449,7 @@ class BibleMediaItem(MediaManagerItem): bible_text = u'' service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) + service_item.add_capability(ItemCapabilities.AllowsAdditions) #If we want to use a 2nd translation / version bible2 = u'' if self.SearchTabWidget.currentIndex() == 0: diff --git a/openlp/plugins/bibles/lib/osis.py b/openlp/plugins/bibles/lib/osis.py index bddf04a5a..104e2adb8 100644 --- a/openlp/plugins/bibles/lib/osis.py +++ b/openlp/plugins/bibles/lib/osis.py @@ -165,7 +165,7 @@ class OSISBible(BibleDB): verse_text = verse_text.replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ - .replace(u'', u'').replace(u'', u'') + .replace(u'', u'').replace(u'', u'') verse_text = self.spaces_regex.sub(u' ', verse_text) self.create_verse(db_book.id, chapter, verse, verse_text) Receiver.send_message(u'openlp_process_events') diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index eff6bc835..373c29794 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -271,4 +271,4 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): if self.VerseTextEdit.toPlainText(): self.VerseTextEdit.setFocus() return False, self.trUtf8('You have unsaved data, please save or clear') - return True, u'' + return True, u'' diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index 2917487ff..2b6cedfbf 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -67,10 +67,10 @@ class CustomTab(SettingsTab): def load(self): self.displayFooter = QtCore.QSettings().value( - self.settings_section + u'/display footer', + self.settingsSection + u'/display footer', QtCore.QVariant(True)).toBool() self.DisplayFooterCheckBox.setChecked(self.displayFooter) def save(self): - QtCore.QSettings().setValue(self.settings_section + u'/display footer', + QtCore.QSettings().setValue(self.settingsSection + u'/display footer', QtCore.QVariant(self.displayFooter)) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 171317e1b..599d73625 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -163,7 +163,7 @@ class CustomMediaItem(MediaManagerItem): service_item.title = title for slide in raw_slides: service_item.add_from_text(slide[:30], slide) - if QtCore.QSettings().value(self.settings_section + u'/display footer', + if QtCore.QSettings().value(self.settingsSection + u'/display footer', QtCore.QVariant(True)).toBool() or credit: raw_footer.append(title + u' ' + credit) else: diff --git a/openlp/plugins/images/lib/imagetab.py b/openlp/plugins/images/lib/imagetab.py index 0cc531c0c..346d28b16 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -72,12 +72,12 @@ class ImageTab(SettingsTab): def load(self): self.loop_delay = QtCore.QSettings().value( - self.settings_section + u'/loop delay', + self.settingsSection + u'/loop delay', QtCore.QVariant(5)).toInt()[0] self.TimeoutSpinBox.setValue(self.loop_delay) def save(self): - QtCore.QSettings().setValue(self.settings_section + u'/loop delay', + QtCore.QSettings().setValue(self.settingsSection + u'/loop delay', QtCore.QVariant(self.loop_delay)) Receiver.send_message(u'slidecontroller_live_spin_delay', self.loop_delay) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index c230b15f7..306664fe3 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -77,12 +77,12 @@ class ImageMediaItem(MediaManagerItem): QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setIconSize(QtCore.QSize(88,50)) self.servicePath = os.path.join( - AppLocation.get_section_data_path(self.settings_section), + AppLocation.get_section_data_path(self.settingsSection), u'thumbnails') if not os.path.exists(self.servicePath): os.mkdir(self.servicePath) self.loadList(SettingsManager.load_list( - self.settings_section, self.settings_section)) + self.settingsSection, self.settingsSection)) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) @@ -121,8 +121,8 @@ class ImageMediaItem(MediaManagerItem): #if not present do not worry pass self.ListView.takeItem(item.row()) - SettingsManager.set_list(self.settings_section, - self.settings_section, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def loadList(self, list): for file in list: @@ -147,6 +147,7 @@ class ImageMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) + service_item.add_capability(ItemCapabilities.AllowsAdditions) for item in items: bitem = self.ListView.item(item.row()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 7afe52cae..3ba632239 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -113,7 +113,6 @@ class MediaMediaItem(MediaManagerItem): filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) Receiver.send_message(u'videodisplay_background', filename) - def generateSlideData(self, service_item, item=None): if item is None: item = self.ListView.currentItem() @@ -132,15 +131,15 @@ class MediaMediaItem(MediaManagerItem): QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setIconSize(QtCore.QSize(88,50)) self.loadList(SettingsManager.load_list( - self.settings_section, self.settings_section)) + self.settingsSection, self.settingsSection)) def onDeleteClick(self): item = self.ListView.currentItem() if item: row = self.ListView.row(item) self.ListView.takeItem(row) - SettingsManager.set_list(self.settings_section, - self.settings_section, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def loadList(self, list): for file in list: diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 92717b6d7..a1a025c02 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -47,7 +47,7 @@ else: from PyQt4 import QtCore -from presentationcontroller import PresentationController, PresentationDocument +from presentationcontroller import PresentationController, PresentationDocument log = logging.getLogger(__name__) @@ -171,13 +171,13 @@ class ImpressController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc OpenOffice') - doc = ImpressDocument(self, name) + doc = ImpressDocument(self, name) self.docs.append(doc) return doc class ImpressDocument(PresentationDocument): - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation OpenOffice') self.controller = controller self.document = None diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 62f81e5d5..9c654b198 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -106,13 +106,13 @@ class PresentationMediaItem(MediaManagerItem): def initialise(self): self.servicePath = os.path.join( - AppLocation.get_section_data_path(self.settings_section), + AppLocation.get_section_data_path(self.settingsSection), u'thumbnails') self.ListView.setIconSize(QtCore.QSize(88,50)) if not os.path.exists(self.servicePath): os.mkdir(self.servicePath) list = SettingsManager.load_list( - self.settings_section, u'presentations') + self.settingsSection, u'presentations') self.loadList(list) for item in self.controllers: #load the drop down selection @@ -141,12 +141,12 @@ class PresentationMediaItem(MediaManagerItem): for controller in self.controllers: thumbPath = os.path.join( AppLocation.get_section_data_path( - self.settings_section), + self.settingsSection), u'thumbnails', controller, filename) thumb = os.path.join(thumbPath, u'slide1.png') preview = os.path.join( AppLocation.get_section_data_path( - self.settings_section), + self.settingsSection), controller, u'thumbnails', filename, u'slide1.png') if os.path.exists(preview): if os.path.exists(thumb): @@ -170,8 +170,8 @@ class PresentationMediaItem(MediaManagerItem): if item: row = self.ListView.row(item) self.ListView.takeItem(row) - SettingsManager.set_list(self.settings_section, - self.settings_section, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) filepath = unicode((item.data(QtCore.Qt.UserRole)).toString()) #not sure of this has errors #John please can you look at . @@ -187,26 +187,29 @@ class PresentationMediaItem(MediaManagerItem): service_item.title = unicode(self.DisplayTypeComboBox.currentText()) service_item.shortname = unicode(self.DisplayTypeComboBox.currentText()) shortname = service_item.shortname - for item in items: - bitem = self.ListView.item(item.row()) - filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) - if shortname == self.Automatic: - service_item.shortname = self.findControllerByType(filename) - if not service_item.shortname: - return False - controller = self.controllers[service_item.shortname] - (path, name) = os.path.split(filename) - doc = controller.add_doc(filename) - if doc.get_slide_preview_file(1) is None: - doc.load_presentation() - i = 1 - img = doc.get_slide_preview_file(i) - while img: - service_item.add_from_command(path, name, img) - i = i + 1 + if shortname: + for item in items: + bitem = self.ListView.item(item.row()) + filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) + if shortname == self.Automatic: + service_item.shortname = self.findControllerByType(filename) + if not service_item.shortname: + return False + controller = self.controllers[service_item.shortname] + (path, name) = os.path.split(filename) + doc = controller.add_doc(filename) + if doc.get_slide_preview_file(1) is None: + doc.load_presentation() + i = 1 img = doc.get_slide_preview_file(i) - doc.close_presentation() - return True + while img: + service_item.add_from_command(path, name, img) + i = i + 1 + img = doc.get_slide_preview_file(i) + doc.close_presentation() + return True + else: + return False def findControllerByType(self, filename): filetype = os.path.splitext(filename)[1] diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index eb31660f0..b15f25642 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -44,7 +44,7 @@ class Controller(object): self.doc = None log.info(u'%s controller loaded' % live) - def addHandler(self, controller, file, isBlank): + def addHandler(self, controller, file, isBlank): log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) self.controller = controller if self.doc is not None: diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 67870574d..3ea95f509 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -31,7 +31,7 @@ if os.name == u'nt': import _winreg import win32ui -from presentationcontroller import PresentationController, PresentationDocument +from presentationcontroller import PresentationController, PresentationDocument log = logging.getLogger(__name__) @@ -62,7 +62,8 @@ class PowerpointController(PresentationController): log.debug(u'check_available') if os.name == u'nt': try: - _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close() + _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + u'PowerPoint.Application').Close() return True except: pass @@ -96,13 +97,13 @@ class PowerpointController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc PowerPoint') - doc = PowerpointDocument(self, name) + doc = PowerpointDocument(self, name) self.docs.append(doc) return doc class PowerpointDocument(PresentationDocument): - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation Powerpoint') self.presentation = None self.controller = controller diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 455e1c601..e45fac45f 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -82,7 +82,8 @@ class PptviewController(PresentationController): if self.process: return log.debug(u'start PPTView') - self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') + self.process = cdll.LoadLibrary( + r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') def kill(self): """ @@ -94,13 +95,12 @@ class PptviewController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc PPTView') - doc = PptviewDocument(self, name) + doc = PptviewDocument(self, name) self.docs.append(doc) return doc class PptviewDocument(PresentationDocument): - - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation PowerPoint') self.presentation = None self.pptid = None diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index fa6e9474d..84a3d83a2 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -100,16 +100,16 @@ class PresentationController(object): self.docs = [] self.plugin = plugin self.name = name - self.settings_section = self.plugin.settings_section + self.settingsSection = self.plugin.settingsSection self.available = self.check_available() if self.available: self.enabled = QtCore.QSettings().value( - self.settings_section + u'/' + name, + self.settingsSection + u'/' + name, QtCore.Qt.Unchecked).toInt()[0] == QtCore.Qt.Checked else: self.enabled = False self.thumbnailroot = os.path.join( - AppLocation.get_section_data_path(self.settings_section), + AppLocation.get_section_data_path(self.settingsSection), name, u'thumbnails') self.thumbnailprefix = u'slide' if not os.path.isdir(self.thumbnailroot): @@ -210,7 +210,7 @@ class PresentationDocument(object): Returns a path to an image containing a preview for the requested slide """ - def __init__(self, controller, name): + def __init__(self, controller, name): self.slidenumber = 0 self.controller = controller self.store_filename(name) @@ -243,10 +243,10 @@ class PresentationDocument(object): if not os.path.isdir(self.thumbnailpath): os.mkdir(self.thumbnailpath) - def get_file_name(self, presentation): + def get_file_name(self, presentation): return os.path.split(presentation)[1] - def get_thumbnail_path(self, presentation): + def get_thumbnail_path(self, presentation): return os.path.join( self.controller.thumbnailroot, self.get_file_name(presentation)) diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index 998753a59..ebcbb3d7b 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -101,7 +101,7 @@ class PresentationTab(SettingsTab): if controller.available: checkbox = self.PresenterCheckboxes[controller.name] checkbox.setChecked(QtCore.QSettings().value( - self.settings_section + u'/' + controller.name, + self.settingsSection + u'/' + controller.name, QtCore.QVariant(0)).toInt()[0]) def save(self): @@ -109,5 +109,5 @@ class PresentationTab(SettingsTab): controller = self.controllers[key] checkbox = self.PresenterCheckboxes[controller.name] QtCore.QSettings().setValue( - self.settings_section + u'/' + controller.name, + self.settingsSection + u'/' + controller.name, QtCore.QVariant(checkbox.checkState())) diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html new file mode 100644 index 000000000..25b08fd43 --- /dev/null +++ b/openlp/plugins/remotes/html/index.html @@ -0,0 +1,117 @@ + + +OpenLP Controller + + + +

OpenLP Controller

+ + +
+ + +
+ + +
+ + +
+ +
+
+ +
+
+ OpenLP website + + + diff --git a/openlp/plugins/remotes/lib/__init__.py b/openlp/plugins/remotes/lib/__init__.py index bb613fb53..9307a0f51 100644 --- a/openlp/plugins/remotes/lib/__init__.py +++ b/openlp/plugins/remotes/lib/__init__.py @@ -24,3 +24,4 @@ ############################################################################### from remotetab import RemoteTab +from httpserver import HttpServer diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py new file mode 100644 index 000000000..2c4105dab --- /dev/null +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -0,0 +1,319 @@ +# -*- 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 logging +import os +import json +import urlparse + +from PyQt4 import QtCore, QtNetwork + +from openlp.core.lib import Receiver +from openlp.core.utils import AppLocation + +log = logging.getLogger(__name__) + +class HttpServer(object): + """ + Ability to control OpenLP via a webbrowser + e.g. http://localhost:4316/send/slidecontroller_live_next + http://localhost:4316/send/alerts_text?q=your%20alert%20text + """ + def __init__(self, parent): + """ + Initialise the httpserver, and start the server + """ + log.debug(u'Initialise httpserver') + self.parent = parent + self.html_dir = os.path.join( + AppLocation.get_directory(AppLocation.PluginsDir), + u'remotes', u'html') + self.connections = [] + self.current_item = None + self.current_slide = None + self.start_tcp() + + def start_tcp(self): + """ + Start the http server, use the port in the settings default to 4316 + Listen out for slide and song changes so they can be broadcast to + clients. Listen out for socket connections + """ + log.debug(u'Start TCP server') + port = QtCore.QSettings().value( + self.parent.settingsSection + u'/remote port', + QtCore.QVariant(4316)).toInt()[0] + self.server = QtNetwork.QTcpServer() + self.server.listen(QtNetwork.QHostAddress(QtNetwork.QHostAddress.Any), + port) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_live_changed'), + self.slide_change) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_live_started'), + self.item_change) + QtCore.QObject.connect(self.server, + QtCore.SIGNAL(u'newConnection()'), self.new_connection) + log.debug(u'TCP listening on port %d' % port) + + def slide_change(self, row): + """ + Slide change listener. Store the item and tell the clients + """ + self.current_slide = row + self.send_poll() + + def item_change(self, items): + """ + Item (song) change listener. Store the slide and tell the clients + """ + self.current_item = items[0].title + self.send_poll() + + def send_poll(self): + """ + Tell the clients something has changed + """ + Receiver.send_message(u'remotes_poll_response', + {'slide': self.current_slide, + 'item': self.current_item}) + + def new_connection(self): + """ + A new http connection has been made. Create a client object to handle + communication + """ + log.debug(u'new http connection') + socket = self.server.nextPendingConnection() + if socket: + self.connections.append(HttpConnection(self, socket)) + + def close_connection(self, connection): + """ + The connection has been closed. Clean up + """ + log.debug(u'close http connection') + self.connections.remove(connection) + + def close(self): + """ + Close down the http server + """ + log.debug(u'close http server') + self.server.close() + +class HttpConnection(object): + """ + A single connection, this handles communication between the server + and the client + """ + def __init__(self, parent, socket): + """ + Initialise the http connection. Listen out for socket signals + """ + log.debug(u'Initialise HttpConnection: %s' % + socket.peerAddress().toString()) + self.socket = socket + self.parent = parent + QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'), + self.ready_read) + QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'), + self.disconnected) + + def ready_read(self): + """ + Data has been sent from the client. Respond to it + """ + log.debug(u'ready to read socket') + if self.socket.canReadLine(): + data = unicode(self.socket.readLine()) + log.debug(u'received: ' + data) + words = data.split(u' ') + html = None + if words[0] == u'GET': + url = urlparse.urlparse(words[1]) + params = self.load_params(url.query) + folders = url.path.split(u'/') + if folders[1] == u'': + html = self.serve_file(u'') + elif folders[1] == u'files': + html = self.serve_file(folders[2]) + elif folders[1] == u'send': + html = self.process_event(folders[2], params) + elif folders[1] == u'request': + if self.process_request(folders[2], params): + return + if html: + html = self.get_200_ok() + html + u'\n' + else: + html = self.get_404_not_found() + self.socket.write(html) + self.close() + + def serve_file(self, filename): + """ + Send a file to the socket. For now, just .html files + and must be top level inside the html folder. + If subfolders requested return 404, easier for security for the present. + + Ultimately for i18n, this could first look for xx/file.html before + falling back to file.html... where xx is the language, e.g. 'en' + """ + log.debug(u'serve file request %s' % filename) + if not filename: + filename = u'index.html' + if os.path.basename(filename) != filename: + return None + (fileroot, ext) = os.path.splitext(filename) + if ext != u'.html': + return None + path = os.path.join(self.parent.html_dir, filename) + try: + f = open(path, u'rb') + except: + log.exception(u'Failed to open %s' % path) + return None + log.debug(u'Opened %s' % path) + html = f.read() + f.close() + return html + + def load_params(self, query): + """ + Decode the query string parameters sent from the browser + """ + params = urlparse.parse_qs(query) + if not params: + return None + else: + return params['q'] + + def process_event(self, event, params): + """ + Send a signal to openlp to perform an action. + Currently lets anything through. Later we should restrict and perform + basic parameter checking, otherwise rogue clients could crash openlp + """ + if params: + Receiver.send_message(event, params) + else: + Receiver.send_message(event) + return u'OK' + + def process_request(self, event, params): + """ + Client has requested data. Send the signal and parameters for openlp + to handle, then listen out for a corresponding _request signal + which will have the data to return. + For most event timeout after 10 seconds (i.e. incase the signal + recipient isn't listening) + remotes_poll_request is a special case, this is a ajax long poll which + is just waiting for slide change/song change activity. This can wait + longer (one minute) + """ + if not event.endswith(u'_request'): + return False + self.event = event + response = event.replace(u'_request', u'_response') + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(response), self.process_response) + self.timer = QtCore.QTimer() + self.timer.setSingleShot(True) + QtCore.QObject.connect(self.timer, + QtCore.SIGNAL(u'timeout()'), self.timeout) + if event == 'remotes_poll_request': + self.timer.start(60000) + else: + self.timer.start(10000) + if params: + Receiver.send_message(event, params) + else: + Receiver.send_message(event) + return True + + def process_response(self, data): + """ + The recipient of a _request signal has sent data. Convert this to + json and return it to client + """ + if not self.socket: + return + self.timer.stop() + html = json.dumps(data) + html = self.get_200_ok() + html + u'\n' + self.socket.write(html) + self.close() + + def get_200_ok(self): + """ + Successful request. Send OK headers. Assume html for now. + """ + return u'HTTP/1.1 200 OK\r\n' + \ + u'Content-Type: text/html; charset="utf-8"\r\n' + \ + u'\r\n' + + def get_404_not_found(self): + """ + Invalid url. Say so + """ + return u'HTTP/1.1 404 Not Found\r\n'+ \ + u'Content-Type: text/html; charset="utf-8"\r\n' + \ + u'\r\n' + + def get_408_timeout(self): + """ + A _request hasn't returned anything in the timeout period. + Return timeout + """ + return u'HTTP/1.1 408 Request Timeout\r\n' + + def timeout(self): + """ + Listener for timeout signal + """ + if not self.socket: + return + html = self.get_408_timeout() + self.socket.write(html) + self.close() + + def disconnected(self): + """ + The client has disconnected. Tidy up + """ + log.debug(u'socket disconnected') + self.close() + + def close(self): + """ + The server has closed the connection. Tidy up + """ + if not self.socket: + return + log.debug(u'close socket') + self.socket.close() + self.socket = None + self.parent.close_connection(self) + diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index 2e38c1e2b..abdda065f 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -57,9 +57,9 @@ class RemoteTab(SettingsTab): def load(self): self.RemotePortSpinBox.setValue( - QtCore.QSettings().value(self.settings_section + u'/remote port', + QtCore.QSettings().value(self.settingsSection + u'/remote port', QtCore.QVariant(4316)).toInt()[0]) def save(self): - QtCore.QSettings().setValue(self.settings_section + u'/remote port', + QtCore.QSettings().setValue(self.settingsSection + u'/remote port', QtCore.QVariant(self.RemotePortSpinBox.value())) diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py index 8bc91c824..2c632d90d 100644 --- a/openlp/plugins/remotes/remoteplugin.py +++ b/openlp/plugins/remotes/remoteplugin.py @@ -28,7 +28,7 @@ import logging from PyQt4 import QtNetwork, QtCore from openlp.core.lib import Plugin, Receiver -from openlp.plugins.remotes.lib import RemoteTab +from openlp.plugins.remotes.lib import RemoteTab, HttpServer log = logging.getLogger(__name__) @@ -36,22 +36,26 @@ class RemotesPlugin(Plugin): log.info(u'Remote Plugin loaded') def __init__(self, plugin_helpers): + """ + remotes constructor + """ Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers) self.weight = -1 self.server = None def initialise(self): + """ + Initialise the remotes plugin, and start the http server + """ log.debug(u'initialise') Plugin.initialise(self) self.insert_toolbox_item() - self.server = QtNetwork.QUdpSocket() - self.server.bind( - QtCore.QSettings().value(self.settings_section + u'/remote port', - QtCore.QVariant(4316)).toInt()[0]) - QtCore.QObject.connect(self.server, - QtCore.SIGNAL(u'readyRead()'), self.readData) + self.server = HttpServer(self) def finalise(self): + """ + Tidy up and close down the http server + """ log.debug(u'finalise') self.remove_toolbox_item() if self.server: @@ -62,28 +66,13 @@ class RemotesPlugin(Plugin): Create the settings Tab """ return RemoteTab(self.name) - - def readData(self): - log.info(u'Remoted data has arrived') - while self.server.hasPendingDatagrams(): - datagram, host, port = self.server.readDatagram( - self.server.pendingDatagramSize()) - self.handle_datagram(datagram) - - def handle_datagram(self, datagram): - log.info(u'Sending event %s ', datagram) - pos = datagram.find(u':') - event = unicode(datagram[:pos].lower()) - if event == u'alert': - Receiver.send_message(u'alerts_text', unicode(datagram[pos + 1:])) - elif event == u'next_slide': - Receiver.send_message(u'slidecontroller_live_next') - else: - Receiver.send_message(event, unicode(datagram[pos + 1:])) def about(self): + """ + Information about this plugin + """ about_text = self.trUtf8('Remote Plugin
This plugin ' 'provides the ability to send messages to a running version of ' - 'openlp on a different computer.
The Primary use for this ' - 'would be to send alerts from a creche') + 'openlp on a different computer via a web browser or other app
' + 'The Primary use for this would be to send alerts from a creche') return about_text diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 8e8e873a6..4c3f78e2f 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -150,8 +150,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def loadBooks(self): books = self.songmanager.get_books() booksCompleter = QtGui.QCompleter( - [book.name for book in books], - self.SongbookCombo) + [book.name for book in books], self.SongbookCombo) booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive); self.SongbookCombo.setCompleter(booksCompleter); self.SongbookCombo.clear() @@ -340,7 +339,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verse_form.setVerse(u'', self.VerseListWidget.count() + 1, True) if self.verse_form.exec_(): afterText, verse, subVerse = self.verse_form.getVerse() - data = u'%s:%s' %(verse, subVerse) + data = u'%s:%s' % (verse, subVerse) item = QtGui.QListWidgetItem(afterText) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data)) item.setText(afterText) @@ -351,11 +350,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if item: tempText = item.text() verseId = unicode((item.data(QtCore.Qt.UserRole)).toString()) - self.verse_form.setVerse(tempText, \ - self.VerseListWidget.count(), True, verseId) + self.verse_form.setVerse( + tempText, self.VerseListWidget.count(), True, verseId) if self.verse_form.exec_(): afterText, verse, subVerse = self.verse_form.getVerse() - data = u'%s:%s' %(verse, subVerse) + data = u'%s:%s' % (verse, subVerse) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data)) item.setText(afterText) #number of lines has change so repaint the list moving the data diff --git a/openlp/plugins/songs/forms/opensongexportdialog.py b/openlp/plugins/songs/forms/opensongexportdialog.py index 4d95e48e2..1821145ee 100644 --- a/openlp/plugins/songs/forms/opensongexportdialog.py +++ b/openlp/plugins/songs/forms/opensongexportdialog.py @@ -286,7 +286,7 @@ class Ui_OpenSongExportDialog(object): QtCore.QMetaObject.connectSlotsByName(OpenSongExportDialog) def retranslateUi(self, OpenSongExportDialog): - OpenSongExportDialog.setWindowTitle(translate('OpenSong Song Exporter')) + OpenSongExportDialog.setWindowTitle(translate('OpenSongExportForm', 'OpenSong Song Exporter')) self.ExportFileLabel.setText(translate('OpenSongExportForm', 'Select OpenSong song folder:')) self.ExportListLabel.setText(translate('OpenSongExportForm', 'Full Song List')) self.ExportListTable.horizontalHeaderItem(0).setText(translate('OpenSongExportForm', 'Song Title')) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 6a99c4ef7..040a6b26f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -133,7 +133,7 @@ class SongMediaItem(MediaManagerItem): def configUpdated(self): self.searchAsYouType = QtCore.QSettings().value( - self.settings_section + u'/search as type', + self.settingsSection + u'/search as type', QtCore.QVariant(u'False')).toBool() def retranslateUi(self): diff --git a/openlp/plugins/songs/lib/songstab.py b/openlp/plugins/songs/lib/songstab.py index 36438f6fc..38bdd791d 100644 --- a/openlp/plugins/songs/lib/songstab.py +++ b/openlp/plugins/songs/lib/songstab.py @@ -81,7 +81,7 @@ class SongsTab(SettingsTab): def load(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) self.song_search = settings.value( u'search as type', QtCore.QVariant(False)).toBool() self.song_bar = settings.value( @@ -92,7 +92,7 @@ class SongsTab(SettingsTab): def save(self): settings = QtCore.QSettings() - settings.beginGroup(self.settings_section) + settings.beginGroup(self.settingsSection) settings.setValue(u'search as type', QtCore.QVariant(self.song_search)) settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar)) settings.endGroup() diff --git a/openlp/plugins/songs/lib/songxml.py b/openlp/plugins/songs/lib/songxml.py index 71506ff2d..2dc55ff7d 100644 --- a/openlp/plugins/songs/lib/songxml.py +++ b/openlp/plugins/songs/lib/songxml.py @@ -137,7 +137,7 @@ class _OpenSong(XmlRootClass): newtag = "Pre-chorus" else: newtag = t - s = (u'# %s %s'%(newtag, c)).rstrip() + s = (u'# %s %s' % (newtag, c)).rstrip() res.append(s) res.append(l[1:]) if (len(l) == 0) and (not tagPending): diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index c6156e55c..31971f465 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -56,15 +56,15 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): self.FromDate.setSelectedDate(fromDate) self.ToDate.setSelectedDate(toDate) self.FileLineEdit.setText( - SettingsManager.get_last_dir(self.parent.settings_section, 1)) + SettingsManager.get_last_dir(self.parent.settingsSection, 1)) def defineOutputLocation(self): path = QtGui.QFileDialog.getExistingDirectory(self, self.trUtf8('Output File Location'), - SettingsManager.get_last_dir(self.parent.settings_section, 1)) + SettingsManager.get_last_dir(self.parent.settingsSection, 1)) path = unicode(path) if path != u'': - SettingsManager.set_last_dir(self.parent.settings_section, path, 1) + SettingsManager.set_last_dir(self.parent.settingsSection, path, 1) self.FileLineEdit.setText(path) def accept(self): diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index da557e81e..10899914c 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -108,10 +108,10 @@ class SongUsagePlugin(Plugin): log.info(u'SongUsage Initialising') Plugin.initialise(self) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'slidecontroller_live_started'), + QtCore.SIGNAL(u'songs_live_started'), self.onReceiveSongUsage) self.SongUsageActive = QtCore.QSettings().value( - self.settings_section + u'/active', + self.settingsSection + u'/active', QtCore.QVariant(False)).toBool() self.SongUsageStatus.setChecked(self.SongUsageActive) if self.songusagemanager is None: @@ -128,7 +128,7 @@ class SongUsagePlugin(Plugin): def toggleSongUsageState(self): self.SongUsageActive = not self.SongUsageActive - QtCore.QSettings().setValue(self.settings_section + u'/active', + QtCore.QSettings().setValue(self.settingsSection + u'/active', QtCore.QVariant(self.SongUsageActive)) def onReceiveSongUsage(self, items): diff --git a/resources/i18n/openlp_af.qm b/resources/i18n/openlp_af.qm index 865213138..785a97249 100644 Binary files a/resources/i18n/openlp_af.qm and b/resources/i18n/openlp_af.qm differ diff --git a/resources/i18n/openlp_de.qm b/resources/i18n/openlp_de.qm index 3142046ef..7197719b3 100644 Binary files a/resources/i18n/openlp_de.qm and b/resources/i18n/openlp_de.qm differ diff --git a/resources/i18n/openlp_en.ts b/resources/i18n/openlp_en.ts index 5f84b2125..41a956423 100644 --- a/resources/i18n/openlp_en.ts +++ b/resources/i18n/openlp_en.ts @@ -705,7 +705,7 @@ This General Public License does not permit incorporating your program into prop - + Bible not fully loaded @@ -1032,47 +1032,47 @@ Changes don't affect verses already in the service EditSongForm - + You need to enter a song title. - + You need to enter some verses. - + Save && Preview - + Error - + bitped - + v - + c - + Invalid verse entry - Vx or Cx - + Invalid verse entry, values must be I,B,T,P,E,O,Vx,Cx @@ -1376,12 +1376,12 @@ Changes don't affect verses already in the service - + No item selected - + You must select one item @@ -2184,7 +2184,7 @@ You can download the latest version from http://openlp.org MediaMediaItem - + Media @@ -2443,6 +2443,11 @@ You can download the latest version from http://openlp.org Close + + + OpenSong Song Exporter + + OpenSongImportForm @@ -2600,8 +2605,8 @@ You can download the latest version from http://openlp.org RemotesPlugin - - <b>Remote Plugin</b><br>This plugin provides the ability to send messages to a running version of openlp on a different computer.<br>The Primary use for this would be to send alerts from a creche + + <b>Remote Plugin</b><br>This plugin provides the ability to send messages to a running version of openlp on a different computer via a web browser or other app<br>The Primary use for this would be to send alerts from a creche @@ -2631,130 +2636,140 @@ You can download the latest version from http://openlp.org ServiceManager - + Save Changes to Service? - + Open Service - + Move to top - + Create a new service - + Save this service - + Theme: - + Delete From Service - + Save Service - + &Live Verse - + Move to &top - + New Service - + &Notes - + Move to end - + &Delete From Service - + Move up order - + Move down order - + Move &down - + Load an existing service - + &Preview Verse - + Move &up - + &Edit Item - + Move to &bottom - + &Maintain Item - + Your service is unsaved, do you want to save those changes before creating a new one? - + Your current service is unsaved, do you want to save the changes before opening a new one? + + + &Add New Item + + + + + &Add to Selected Item + + ServiceNoteForm @@ -2840,7 +2855,7 @@ You can download the latest version from http://openlp.org - + Verse @@ -2865,7 +2880,7 @@ You can download the latest version from http://openlp.org - + Chorus diff --git a/resources/i18n/openlp_en_GB.qm b/resources/i18n/openlp_en_GB.qm index 6ccb8a4ac..b2dc81931 100644 Binary files a/resources/i18n/openlp_en_GB.qm and b/resources/i18n/openlp_en_GB.qm differ diff --git a/resources/i18n/openlp_hu.qm b/resources/i18n/openlp_hu.qm index 9f67c7dbc..dc4e5fba2 100644 Binary files a/resources/i18n/openlp_hu.qm and b/resources/i18n/openlp_hu.qm differ diff --git a/resources/i18n/openlp_pt_BR.qm b/resources/i18n/openlp_pt_BR.qm index a0d2b109b..4e075ec64 100644 Binary files a/resources/i18n/openlp_pt_BR.qm and b/resources/i18n/openlp_pt_BR.qm differ diff --git a/resources/i18n/openlp_sv.qm b/resources/i18n/openlp_sv.qm index bd6daac49..f7b80c6ed 100644 Binary files a/resources/i18n/openlp_sv.qm and b/resources/i18n/openlp_sv.qm differ diff --git a/resources/pyinstaller/hook-lxml.objectify.py b/resources/pyinstaller/hook-lxml.objectify.py index 071a0dca4..9d83432df 100644 --- a/resources/pyinstaller/hook-lxml.objectify.py +++ b/resources/pyinstaller/hook-lxml.objectify.py @@ -1 +1 @@ -hiddenimports = ['lxml.etree'] +hiddenimports = ['lxml.etree'] diff --git a/scripts/openlp-remoteclient.py b/scripts/openlp-remoteclient.py index de3099920..3ff7ccc05 100755 --- a/scripts/openlp-remoteclient.py +++ b/scripts/openlp-remoteclient.py @@ -24,34 +24,33 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -import socket +import urllib import sys from optparse import OptionParser -def sendData(options, message): - addr = (options.address, options.port) +def sendData(options): + addr = 'http://%s:%s/send/%s?q=%s' % (options.address, options.port, + options.event, options.message) try: - UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) - UDPSock.sendto(message, addr) - print u'message sent ', message, addr + urllib.urlopen(addr) + print u'Message sent ', addr except: - print u'Errow thrown ', sys.exc_info()[1] - -def format_message(options): - return u'%s:%s' % (u'alert', options.message) + print u'Error thrown ', sys.exc_info()[1] def main(): - usage = "usage: %prog [options] arg1 arg2" + usage = "usage: %prog [-a address] [-p port] [-e event] [-m message]" parser = OptionParser(usage=usage) - parser.add_option("-v", "--verbose", - action="store_true", dest="verbose", default=True, - help="make lots of noise [%default]") parser.add_option("-p", "--port", default=4316, help="IP Port number %default ") parser.add_option("-a", "--address", - help="Recipient address ") + help="Recipient address ", + default="localhost") + parser.add_option("-e", "--event", + help="Action to be performed", + default="alerts_text") parser.add_option("-m", "--message", - help="Message to be passed for the action") + help="Message to be passed for the action", + default="") (options, args) = parser.parse_args() if args: @@ -60,12 +59,8 @@ def main(): elif options.address is None: parser.print_help() parser.error("IP address missing") - elif options.message is None: - parser.print_help() - parser.error("No message passed") else: - text = format_message(options) - sendData(options, text) + sendData(options) if __name__ == u'__main__': main()