diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 15db0fead..6c30f9970 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -54,6 +54,25 @@ class EventReceiver(QtCore.QObject): ``request_spin_delay`` Requests a spin delay + ``{plugin}_start`` + Requests a plugin to start a external program + Path and file provided in message + + ``{plugin}_first`` + Requests a plugin to handle a first event + + ``{plugin}_previous`` + Requests a plugin to handle a previous event + + ``{plugin}_next`` + Requests a plugin to handle a next event + + ``{plugin}_last`` + Requests a plugin to handle a last event + + ``{plugin}_stop`` + Requests a plugin to handle a stop event + """ global log log = logging.getLogger(u'EventReceiver') diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 484d74f97..c1eaf79fb 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -135,6 +135,7 @@ class PluginManager(object): """ Loop through all the plugins. If a plugin has a valid settings tab item, add it to the settings tab. + Tabs are set for all plugins not just Active ones ``settingsform`` Defaults to *None*. The settings form to add tabs to. diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 5c74cdbf1..eba0372b2 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -51,6 +51,7 @@ class ServiceItem(object): if hostplugin is not None: self.RenderManager = self.plugin.render_manager self.shortname = hostplugin.name + self.name = self.plugin.name self.title = u'' self.items = [] self.iconic_representation = None @@ -158,6 +159,7 @@ class ServiceItem(object): file to represent this item. """ oos_header = { + u'name': self.name.lower(), u'plugin': self.shortname, u'theme':self.theme, u'title':self.title, @@ -190,6 +192,7 @@ class ServiceItem(object): """ header = serviceitem[u'serviceitem'][u'header'] self.title = header[u'title'] + self.name = header[u'name'] self.service_item_type = header[u'type'] self.shortname = header[u'plugin'] self.theme = header[u'theme'] diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index bc66c2375..3bd32a753 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -27,7 +27,9 @@ class SettingsManager(object): self.screen = screen[0] self.width = self.screen[u'size'].width() self.height = self.screen[u'size'].height() - self.mainwindow_width = self.width * 0.8 self.mainwindow_height = self.height * 0.8 - self.mainwindow_docbars = self.width / 3 - self.mainwindow_slidecontroller = self.width / 6 + self.mainwindow_docbars = self.width / 5 + if self.mainwindow_docbars > 300: + self.mainwindow_docbars = 300 + self.mainwindow_slidecontroller = (self.width - (self.mainwindow_docbars * 3 ) / 2) / 2 + print self.width, self.mainwindow_docbars, self.mainwindow_slidecontroller diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index f494d1880..4c5ecf56c 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -106,7 +106,7 @@ class Ui_MainWindow(object): self.MediaManagerDock.setWindowIcon(icon) self.MediaManagerDock.setFloating(False) self.MediaManagerDock.setObjectName(u'MediaManagerDock') - self.MediaManagerDock.setMinimumWidth(300) + self.MediaManagerDock.setMinimumWidth(self.settingsmanager.mainwindow_docbars) self.MediaManagerContents = QtGui.QWidget() self.MediaManagerContents.setObjectName(u'MediaManagerContents') self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents) @@ -128,7 +128,7 @@ class Ui_MainWindow(object): self.ServiceManagerDock.setFeatures( QtGui.QDockWidget.AllDockWidgetFeatures) self.ServiceManagerDock.setObjectName(u'ServiceManagerDock') - self.ServiceManagerDock.setMinimumWidth(300) + self.ServiceManagerDock.setMinimumWidth(self.settingsmanager.mainwindow_docbars) self.ServiceManagerContents = ServiceManager(self) self.ServiceManagerDock.setWidget(self.ServiceManagerContents) MainWindow.addDockWidget( diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 9ff0e37c2..0b347c1cc 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -18,6 +18,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import os +import sys import logging import cPickle import zipfile @@ -137,21 +138,28 @@ class ServiceManager(QtGui.QWidget): self.ServiceManagerList.addAction(contextMenuSeparator(self.ServiceManagerList)) self.ServiceManagerList.addAction(contextMenuAction( self.ServiceManagerList, ':/services/service_delete', - translate(u'ServiceManager',u'&Remove from Service'), self.onDeleteFromService)) + translate(u'ServiceManager',u'&Remove from Service'), + self.onDeleteFromService)) self.Layout.addWidget(self.ServiceManagerList) # Add the bottom toolbar self.OrderToolbar = OpenLPToolbar(self) - self.OrderToolbar.addToolbarButton(u'Move to top', u':/services/service_top.png', + self.OrderToolbar.addToolbarButton(u'Move to top', + u':/services/service_top.png', translate(u'ServiceManager', u'Move to top'), self.onServiceTop) - self.OrderToolbar.addToolbarButton(u'Move up', u':/services/service_up.png', + self.OrderToolbar.addToolbarButton(u'Move up', + u':/services/service_up.png', translate(u'ServiceManager', u'Move up order'), self.onServiceUp) - self.OrderToolbar.addToolbarButton(u'Move down', u':/services/service_down.png', + self.OrderToolbar.addToolbarButton(u'Move down', + u':/services/service_down.png', translate(u'ServiceManager', u'Move down order'), self.onServiceDown) - self.OrderToolbar.addToolbarButton(u'Move to bottom', u':/services/service_bottom.png', + self.OrderToolbar.addToolbarButton(u'Move to bottom', + u':/services/service_bottom.png', translate(u'ServiceManager', u'Move to end'), self.onServiceEnd) self.OrderToolbar.addSeparator() - self.OrderToolbar.addToolbarButton(u'Delete From Service', u':/services/service_delete.png', - translate(u'ServiceManager', u'Delete From Service'), self.onDeleteFromService) + self.OrderToolbar.addToolbarButton(u'Delete From Service', + u':/services/service_delete.png', + translate(u'ServiceManager', u'Delete From Service'), + self.onDeleteFromService) self.Layout.addWidget(self.OrderToolbar) # Connect up our signals and slots QtCore.QObject.connect(self.ThemeComboBox, @@ -402,6 +410,7 @@ class ServiceManager(QtGui.QWidget): #if not present do not worry pass except: + log.error(u'Problem processing oos load %s', sys.exc_info()[0]) pass self.serviceName = name[len(name) - 1] self.parent.OosChanged(True, self.serviceName) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 30fb3aaeb..c90359adc 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -68,6 +68,7 @@ class SlideController(QtGui.QWidget): self.parent = parent self.image_list = [u'Start Loop', u'Stop Loop', u'Loop Spearator', u'Image SpinBox'] self.timer_id = 0 + self.item = None self.Panel = QtGui.QWidget(parent.ControlSplitter) self.Splitter = QtGui.QSplitter(self.Panel) self.Splitter.setOrientation(QtCore.Qt.Vertical) @@ -229,9 +230,17 @@ class SlideController(QtGui.QWidget): Called by plugins """ log.debug(u'addServiceItem') + #If old item was a command tell it to stop + if self.item is not None and self.item.service_item_type == ServiceType.Command: + Receiver().send_message(u'%s_stop'%item.name.lower()) + self.item = item item.render() self.enableToolBar(item) - self.displayServiceManagerItems(item, 0) + if item.service_item_type == ServiceType.Command: + Receiver().send_message(u'%s_start'%item.name.lower(), \ + u'%s:%s:%s' % (item.shortname, item.service_item_path, item.service_frames[0][u'title'])) + else: + self.displayServiceManagerItems(item, 0) def addServiceManagerItem(self, item, slideno): """ @@ -240,8 +249,16 @@ class SlideController(QtGui.QWidget): Called by ServiceManager """ log.debug(u'addServiceItem') + #If old item was a command tell it to stop + if self.item.service_item_type == ServiceType.Command: + Receiver().send_message(u'%s_stop'%item.name.lower()) + self.item = item self.enableToolBar(item) - self.displayServiceManagerItems(item, slideno) + if item.service_item_type == ServiceType.Command: + Receiver().send_message(u'%s_start'%item.name.lower(), \ + u'%s:%s:%s' % (item.shortname, item.service_item_path, item.service_frames[0][u'title'])) + else: + self.displayServiceManagerItems(item, slideno) def displayServiceManagerItems(self, serviceitem, slideno): """ @@ -310,11 +327,14 @@ class SlideController(QtGui.QWidget): """ Go to the next slide. """ - row = self.PreviewListWidget.currentRow() + 1 - if row == self.PreviewListWidget.rowCount(): - row = 0 - self.PreviewListWidget.selectRow(row) - self.onSlideSelected() + if self.item.service_item_type == ServiceType.Command: + Receiver().send_message(u'%s_next'% self.item.name.lower()) + else: + row = self.PreviewListWidget.currentRow() + 1 + if row == self.PreviewListWidget.rowCount(): + row = 0 + self.PreviewListWidget.selectRow(row) + self.onSlideSelected() def onSlideSelectedPrevious(self): """ diff --git a/openlp/plugins/presentations/lib/__init__.py b/openlp/plugins/presentations/lib/__init__.py index 4eb846020..2b5d0d266 100644 --- a/openlp/plugins/presentations/lib/__init__.py +++ b/openlp/plugins/presentations/lib/__init__.py @@ -17,8 +17,11 @@ 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 """ +from impresscontroller import ImpressController +from messagelistener import MessageListener from mediaitem import PresentationMediaItem from presentationtab import PresentationTab -from impresscontroller import impressController -__all__ = ['PresentationMediaItem', 'PresentationTab', 'impressController'] + +__all__ = ['PresentationMediaItem', 'PresentationTab', + 'ImpressController', 'MessageListener'] diff --git a/openlp/plugins/presentations/lib/impresscom.py b/openlp/plugins/presentations/lib/impresscom.py index e2d2ca644..f15736f88 100644 --- a/openlp/plugins/presentations/lib/impresscom.py +++ b/openlp/plugins/presentations/lib/impresscom.py @@ -182,7 +182,7 @@ class ImpressCOMSlide(object): if __name__ == '__main__': ooo = Openoffice() ooo.createResolver() - #show = ImpressCOMPres(ooo, u'/home/timali/test1.odp') - #show.go() + show = ImpressCOMPres(ooo, u'/home/timali/test1.odp') + show.go() #show.resume() #show.nextStep() diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py new file mode 100644 index 000000000..356397945 --- /dev/null +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley + +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 +""" +# OOo API documentation: +# http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html +# http://docs.go-oo.org/sd/html/classsd_1_1SlideShow.html +# http://www.oooforum.org/forum/viewtopic.phtml?t=5252 +# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations +# http://mail.python.org/pipermail/python-win32/2008-January/006676.html +#http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python +#http://nxsy.org/comparing-documents-with-openoffice-and-python + +import logging +import os , subprocess +import time +import uno +import sys + +from PyQt4 import QtCore + +class ImpressController(object): + global log + log = logging.getLogger(u'ImpressController') + + def __init__(self): + log.debug(u'Initialising') + self.process = None + self.document = None + self.presentation = None + self.startOpenoffice() + + def startOpenoffice(self): + log.debug(u'start Openoffice') + cmd = u'openoffice.org -nologo -norestore -minimized -headless ' + u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"' + self.process = QtCore.QProcess() + self.process.startDetached(cmd) + self.process.waitForStarted() + + def kill(self): + log.debug(u'Kill') + self.closePresentation() + + def loadPresentation(self, presentation): + log.debug(u'create Resolver') + try: + context = uno.getComponentContext() + resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context) + ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext') + smgr = ctx.ServiceManager + desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx ) + url = uno.systemPathToFileUrl(presentation) + properties = [] + properties = tuple(properties) + self.document = desktop.loadComponentFromURL(url, "_blank", 0, properties) + self.presentation = self.document.getPresentation() + self.presentation.start() + except: + log.error(u'Failed reason %s' % sys.exc_info()) + + def closePresentation(self): + """ + Close presentation and clean up objects + Triggerent by new object being added to SlideController orOpenLP + being shut down + """ + if self.document is not None: + if self.presentation is not None: + self.presentation.end() + self.presentation = None + self.document.dispose() + self.document = None + + def isActive(self): + return self.presentation.isRunning() and self.presentation.isActive() + + def resume(self): + return self.presentation.resume() + + def pause(self): + return self.presentation.pause() + + def blankScreen(self): + self.presentation.blankScreen(0) + + def stop(self): + self.presentation.deactivate() + # self.presdoc.end() + + def go(self): + self.presentation.activate() + # self.presdoc.start() + + def getSlideNumber(self): + return self.presentation.getCurrentSlideIndex + + def setSlideNumber(self, slideno): + self.presentation.gotoSlideIndex(slideno) + + slideNumber = property(getSlideNumber, setSlideNumber) + + def nextStep(self): + self.presentation.gotoNextSlide() + + def prevStep(self): + self.presentation.gotoPreviousSlide() + diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 90f1bc580..96b64b6cb 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -22,6 +22,7 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD +from openlp.plugins.presentations.lib import MessageListener # We have to explicitly create separate classes for each plugin # in order for DnD to the Service manager to work correctly. @@ -54,6 +55,7 @@ class PresentationMediaItem(MediaManagerItem): # be instanced by the base MediaManagerItem self.ListViewWithDnD_class = PresentationListView MediaManagerItem.__init__(self, parent, icon, title) + self.message_listener = MessageListener(controllers) def addHeaderBar(self): self.PresentationWidget = QtGui.QWidget(self) diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py new file mode 100644 index 000000000..1bf8b2cc3 --- /dev/null +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley + +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 + +from PyQt4 import QtCore +from openlp.core.lib import Receiver +from openlp.plugins.presentations.lib import ImpressController + +class MessageListener(object): + """ + This is the Presentation listener who acts on events from the slide controller + and passes the messages on the the correct presentation handlers + """ + global log + log=logging.getLogger(u'MessageListener') + log.info(u'Message Listener loaded') + + def __init__(self, controllers): + self.controllers = controllers + self.handler = None + + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_start'), self.startup) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_stop'), self.next) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_first'), self.next) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_previous'), self.next) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_next'), self.next) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_last'), self.next) + + def startup(self, message): + """ + Start of new presentation + Save the handler as any new presentations start here + """ + self.handler, file = self.decodeMessage(message) + self.controllers[self.handler].loadPresentation(file) + + def next(self, message): + self.controllers[self.handler].nextStep() + + def decodeMessage(self, message): + bits = message.split(u':') + file = os.path.join(bits[1], bits[2]) + return bits[0], file diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 0f3a230e1..09928b4ba 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -19,12 +19,13 @@ Place, Suite 330, Boston, MA 02111-1307 USA """ import os +import sys import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, MediaManagerItem -from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, impressController +from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, ImpressController class PresentationPlugin(Plugin): @@ -65,16 +66,16 @@ class PresentationPlugin(Plugin): If Not do not install the plugin. """ log.debug('check_pre_conditions') - + #Lets see if Impress is required (Default is Not wanted) if int(self.config.get_config(u'Impress', 0)) == 2: try: #Check to see if we have uno installed import uno - openoffice = impressController() + openoffice = ImpressController() self.registerControllers(u'Impress', openoffice) except: - pass - #If we have no controllers disable plugin + log.error(u'Reason : %s', sys.exc_info())#[0]) + #If we have no available controllers disable plugin if len(self.controllers) > 0: return True else: @@ -82,7 +83,7 @@ class PresentationPlugin(Plugin): def finalise(self): log.debug(u'Finalise') - print self.controllers + #Ask each controller to tidy up for controller in self.controllers: print controller self.controllers[controller].kill() diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py new file mode 100644 index 000000000..21242207d --- /dev/null +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, + +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 +""" + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import SettingsTab, str_to_bool, translate + +class RemoteTab(SettingsTab): + """ + RemoteTab is the Remotes settings tab in the settings dialog. + """ + def __init__(self): + SettingsTab.__init__(self, translate(u'RemoteTab', u'Remotes'), u'Remotes') + + def setupUi(self): + self.setObjectName(u'RemoteTab') + self.RemoteLayout = QtGui.QFormLayout(self) + self.RemoteLayout.setObjectName(u'RemoteLayout') + self.RemoteModeGroupBox = QtGui.QGroupBox(self) + self.RemoteModeGroupBox.setObjectName(u'RemoteModeGroupBox') + self.RemoteModeLayout = QtGui.QVBoxLayout(self.RemoteModeGroupBox) + self.RemoteModeLayout.setSpacing(8) + self.RemoteModeLayout.setMargin(8) + self.RemoteModeLayout.setObjectName(u'RemoteModeLayout') + self.RemotePortSpinBox = QtGui.QSpinBox(self.RemoteModeGroupBox) + self.RemotePortSpinBox.setObjectName(u'RemotePortSpinBox') + self.RemotePortSpinBox.setMaximum(32767) + self.RemoteModeLayout.addWidget(self.RemotePortSpinBox) + self.WarningLabel = QtGui.QLabel(self.RemoteModeGroupBox) + self.WarningLabel.setObjectName(u'WarningLabel') + self.RemoteModeLayout.addWidget(self.WarningLabel) + self.RemoteLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.RemoteModeGroupBox) + + def retranslateUi(self): + self.RemoteModeGroupBox.setTitle(translate(u'RemoteTab', u'Remotes Receiver Port')) + self.WarningLabel.setText(translate(u'RemoteTab', u'A restart is needed for this change to become effective')) + + def load(self): + self.RemotePortSpinBox.setValue(int(self.config.get_config(u'remote port', 4316))) + + def save(self): + self.config.set_config(u'remote port', unicode(self.RemotePortSpinBox.value())) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 5dc49b015..6419e989f 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -285,7 +285,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verse_form.setVerse(item.text()) self.verse_form.exec_() item.setText(self.verse_form.getVerse()) - self.VerseListWidget.repaint() self.VerseEditButton.setEnabled(False) self.VerseDeleteButton.setEnabled(False)