Edit Songs and Custom for Service Manager and auto replace

bzr-revno: 634
This commit is contained in:
Tim Bentley 2009-10-29 15:10:58 +00:00
commit 3c6d1e7efb
12 changed files with 151 additions and 39 deletions

View File

@ -78,6 +78,9 @@ class EventReceiver(QtCore.QObject):
``{plugin}_stop`` ``{plugin}_stop``
Requests a plugin to handle a stop event Requests a plugin to handle a stop event
``{plugin}_edit``
Requests a plugin edit a database item with the key as the payload
``songusage_live`` ``songusage_live``
Sends live song audit requests to the audit component Sends live song audit requests to the audit component
@ -97,6 +100,10 @@ class EventReceiver(QtCore.QObject):
``slidecontroller_change`` ``slidecontroller_change``
Informs the slidecontroller that a slide change has occurred Informs the slidecontroller that a slide change has occurred
``remote_edite_clear``
Informs all components that remote edit has been aborted.
""" """
global log global log
log = logging.getLogger(u'EventReceiver') log = logging.getLogger(u'EventReceiver')

View File

@ -70,6 +70,7 @@ class ServiceItem(object):
self.theme = None self.theme = None
self.service_item_path = None self.service_item_path = None
self.service_item_type = None self.service_item_type = None
self.editEnabled = False
self.service_frames = [] self.service_frames = []
def addIcon(self, icon): def addIcon(self, icon):

View File

@ -38,6 +38,24 @@ class ServiceManagerList(QtGui.QTreeWidget):
QtGui.QTreeWidget.__init__(self,parent) QtGui.QTreeWidget.__init__(self,parent)
self.parent = parent self.parent = parent
# def mousePressEvent(self, event):
# if event.button() == QtCore.Qt.RightButton:
# item = self.itemAt(event.pos())
# parentitem = item.parent()
# if parentitem is None:
# pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
# else:
# pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
# serviceItem = self.parent.serviceItems[pos - 1]
# if serviceItem[u'data'].editEnabled:
# self.parent.editAction.setVisible(True)
# else:
# self.parent.editAction.setVisible(False)
# event.accept()
# else:
# event.ignore()
def keyPressEvent(self, event): def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent: if type(event) == QtGui.QKeyEvent:
#here accept the event and do something #here accept the event and do something
@ -111,6 +129,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems = [] self.serviceItems = []
self.serviceName = u'' self.serviceName = u''
self.isNew = True self.isNew = True
self.remoteEditTriggered = False
self.Layout = QtGui.QVBoxLayout(self) self.Layout = QtGui.QVBoxLayout(self)
self.Layout.setSpacing(0) self.Layout.setSpacing(0)
self.Layout.setMargin(0) self.Layout.setMargin(0)
@ -157,6 +176,12 @@ class ServiceManager(QtGui.QWidget):
# Add a context menu to the service manager list # Add a context menu to the service manager list
self.ServiceManagerList.setContextMenuPolicy( self.ServiceManagerList.setContextMenuPolicy(
QtCore.Qt.ActionsContextMenu) QtCore.Qt.ActionsContextMenu)
self.editAction = contextMenuAction(
self.ServiceManagerList, ':/system/system_live.png',
self.trUtf8(u'&Edit Item'), self.remoteEdit)
self.ServiceManagerList.addAction(self.editAction)
self.ServiceManagerList.addAction(contextMenuSeparator(
self.ServiceManagerList))
self.ServiceManagerList.addAction(contextMenuAction( self.ServiceManagerList.addAction(contextMenuAction(
self.ServiceManagerList, ':/system/system_preview.png', self.ServiceManagerList, ':/system/system_preview.png',
self.trUtf8(u'&Preview Verse'), self.makePreview)) self.trUtf8(u'&Preview Verse'), self.makePreview))
@ -205,6 +230,8 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'update_themes'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear)
# Last little bits of setting up # Last little bits of setting up
self.config = PluginConfig(u'ServiceManager') self.config = PluginConfig(u'ServiceManager')
self.servicePath = self.config.get_data_path() self.servicePath = self.config.get_data_path()
@ -510,14 +537,19 @@ class ServiceManager(QtGui.QWidget):
""" """
sitem, count = self.findServiceItem() sitem, count = self.findServiceItem()
item.render() item.render()
if sitem == -1: if self.remoteEditTriggered:
self.serviceItems.append({u'data': item, self.serviceItems[sitem][u'data'] = item
u'order': len(self.serviceItems) + 1, u'expanded':True}) self.remoteEditTriggered = False
self.repaintServiceList(len(self.serviceItems) + 1, 0)
else:
self.serviceItems.insert(sitem + 1, {u'data': item,
u'order': len(self.serviceItems)+1, u'expanded':True})
self.repaintServiceList(sitem + 1, 0) self.repaintServiceList(sitem + 1, 0)
else:
if sitem == -1:
self.serviceItems.append({u'data': item,
u'order': len(self.serviceItems) + 1, u'expanded':True})
self.repaintServiceList(len(self.serviceItems) + 1, 0)
else:
self.serviceItems.insert(sitem + 1, {u'data': item,
u'order': len(self.serviceItems)+1, u'expanded':True})
self.repaintServiceList(sitem + 1, 0)
self.parent.serviceChanged(False, self.serviceName) self.parent.serviceChanged(False, self.serviceName)
def makePreview(self): def makePreview(self):
@ -536,6 +568,19 @@ class ServiceManager(QtGui.QWidget):
self.parent.LiveController.addServiceManagerItem( self.parent.LiveController.addServiceManagerItem(
self.serviceItems[item][u'data'], count) self.serviceItems[item][u'data'], count)
def remoteEdit(self):
"""
Posts a remote edit message to a plugin to allow item to be edited.
"""
item, count = self.findServiceItem()
if self.serviceItems[item][u'data'].editEnabled:
self.remoteEditTriggered = True
Receiver().send_message(u'%s_edit' % self.serviceItems[item][u'data'].name,
self.serviceItems[item][u'data'].editId )
def onRemoteEditClear(self):
self.remoteEditTriggered = False
def findServiceItem(self): def findServiceItem(self):
""" """
Finds a ServiceItem in the list Finds a ServiceItem in the list

View File

@ -266,7 +266,7 @@ class ThemeManager(QtGui.QWidget):
try: try:
xml = file_to_xml(xml_file) xml = file_to_xml(xml_file)
except: except:
xml = baseTheme() xml = self.baseTheme()
theme = ThemeXML() theme = ThemeXML()
theme.parse(xml) theme.parse(xml)
self.cleanTheme(theme) self.cleanTheme(theme)

View File

@ -69,4 +69,4 @@ class CustomPlugin(Plugin):
self.remove_toolbox_item() self.remove_toolbox_item()
def about(self): def about(self):
return u'<b>Custom Plugin</b> <br>This plugin allows slides to be displayed on the screen in the same way songs are. The difference between this plugin and songs is this plugin provides greater freedom.<br><br>This is a core plugin and cannot be made inactive</b>' return u'<b>Custom Plugin</b> <br>This plugin allows slides to be displayed on the screen in the same way songs are. The difference between this plugin and songs is this plugin provides greater freedom.<br>'

View File

@ -54,7 +54,8 @@ class Ui_customEditDialog(object):
self.UpButton.setIcon(icon1) self.UpButton.setIcon(icon1)
self.UpButton.setObjectName(u'UpButton') self.UpButton.setObjectName(u'UpButton')
self.verticalLayout.addWidget(self.UpButton) self.verticalLayout.addWidget(self.UpButton)
spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem = QtGui.QSpacerItem(20, 128,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem) self.verticalLayout.addItem(spacerItem)
self.DownButton = QtGui.QPushButton(customEditDialog) self.DownButton = QtGui.QPushButton(customEditDialog)
icon2 = buildIcon(u':/services/service_down.png') icon2 = buildIcon(u':/services/service_down.png')
@ -94,7 +95,8 @@ class Ui_customEditDialog(object):
self.ClearButton = QtGui.QPushButton(self.ButtonWidge) self.ClearButton = QtGui.QPushButton(self.ButtonWidge)
self.ClearButton.setObjectName(u'ClearButton') self.ClearButton.setObjectName(u'ClearButton')
self.verticalLayout_2.addWidget(self.ClearButton) self.verticalLayout_2.addWidget(self.ClearButton)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem1 = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem1) self.verticalLayout_2.addItem(spacerItem1)
self.EditLayout_3.addWidget(self.ButtonWidge) self.EditLayout_3.addWidget(self.ButtonWidge)
self.gridLayout.addWidget(self.EditWidget, 2, 0, 1, 1) self.gridLayout.addWidget(self.EditWidget, 2, 0, 1, 1)
@ -117,11 +119,16 @@ class Ui_customEditDialog(object):
self.horizontalLayout_2.addWidget(self.CreditEdit) self.horizontalLayout_2.addWidget(self.CreditEdit)
self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox') self.buttonBox.setObjectName(u'buttonBox')
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1) self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
self.retranslateUi(customEditDialog) self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), customEditDialog.accept)
QtCore.QMetaObject.connectSlotsByName(customEditDialog) QtCore.QMetaObject.connectSlotsByName(customEditDialog)
customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit) customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit)
customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton) customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton)

View File

@ -40,10 +40,6 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
#self.parent = parent #self.parent = parent
self.setupUi(self) self.setupUi(self)
# Connecting signals and slots # Connecting signals and slots
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), self.rejected)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), self.accept)
QtCore.QObject.connect(self.AddButton, QtCore.QObject.connect(self.AddButton,
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
QtCore.QObject.connect(self.EditButton, QtCore.QObject.connect(self.EditButton,
@ -113,6 +109,10 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
else: else:
self.ThemeComboBox.setCurrentIndex(0) self.ThemeComboBox.setCurrentIndex(0)
def closePressed(self):
Receiver().send_message(u'remote_edit_clear')
self.close()
def accept(self): def accept(self):
valid, message = self._validate() valid, message = self._validate()
if not valid: if not valid:
@ -132,9 +132,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.customSlide.credits = unicode(self.CreditEdit.displayText()) self.customSlide.credits = unicode(self.CreditEdit.displayText())
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText()) self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText())
self.custommanager.save_slide(self.customSlide) self.custommanager.save_slide(self.customSlide)
self.close() Receiver().send_message(u'load_custom_list')
def rejected(self):
self.close() self.close()
def onUpButtonPressed(self): def onUpButtonPressed(self):

View File

@ -26,7 +26,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, Receiver
class CustomListView(BaseListWithDnD): class CustomListView(BaseListWithDnD):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -53,6 +53,15 @@ class CustomMediaItem(MediaManagerItem):
self.servicePath = None self.servicePath = None
MediaManagerItem.__init__(self, parent, icon, title) MediaManagerItem.__init__(self, parent, icon, title)
self.parent = parent self.parent = parent
self.fromServiceManager = -1
def addEndHeaderBar(self):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'load_custom_list'), self.initialise)
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -68,12 +77,24 @@ class CustomMediaItem(MediaManagerItem):
custom_name.setData( custom_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id)) QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id))
self.ListView.addItem(custom_name) self.ListView.addItem(custom_name)
if CustomSlide.id == self.fromServiceManager:
self.onAddClick()
def onNewClick(self): def onNewClick(self):
self.parent.edit_custom_form.loadCustom(0) self.parent.edit_custom_form.loadCustom(0)
self.parent.edit_custom_form.exec_() self.parent.edit_custom_form.exec_()
self.initialise() self.initialise()
def onRemoteEditClear(self):
self.fromServiceManager = -1
def onRemoteEdit(self, item_id):
valid = self.parent.custommanager.get_custom(item_id)
if valid is not None:
self.fromServiceManager = item_id
self.parent.edit_custom_form.loadCustom(item_id)
self.parent.edit_custom_form.exec_()
def onEditClick(self): def onEditClick(self):
item = self.ListView.currentItem() item = self.ListView.currentItem()
if item is not None: if item is not None:
@ -95,13 +116,19 @@ class CustomMediaItem(MediaManagerItem):
raw_footer = [] raw_footer = []
slide = None slide = None
theme = None theme = None
item = self.ListView.currentItem() if self.fromServiceManager == -1:
if item is None: item = self.ListView.currentItem()
return False if item is None:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = self.fromServiceManager
self.fromServiceManager = -1
customSlide = self.parent.custommanager.get_custom(item_id) customSlide = self.parent.custommanager.get_custom(item_id)
title = customSlide.title title = customSlide.title
credit = customSlide.credits credit = customSlide.credits
service_item.editEnabled = True
service_item.editId = item_id
theme = customSlide.theme_name theme = customSlide.theme_name
if len(theme) is not 0 : if len(theme) is not 0 :
service_item.theme = theme service_item.theme = theme

View File

@ -383,7 +383,7 @@ class Ui_EditSongDialog(object):
self.retranslateUi(EditSongDialog) self.retranslateUi(EditSongDialog)
QtCore.QObject.connect(self.ButtonBox, QtCore.QObject.connect(self.ButtonBox,
QtCore.SIGNAL(u'rejected()'), EditSongDialog.close) QtCore.SIGNAL(u'rejected()'), EditSongDialog.closePressed)
QtCore.QObject.connect(self.ButtonBox, QtCore.QObject.connect(self.ButtonBox,
QtCore.SIGNAL(u'accepted()'), EditSongDialog.accept) QtCore.SIGNAL(u'accepted()'), EditSongDialog.accept)
QtCore.QMetaObject.connectSlotsByName(EditSongDialog) QtCore.QMetaObject.connectSlotsByName(EditSongDialog)

View File

@ -400,15 +400,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def onPreview(self, button): def onPreview(self, button):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == self.trUtf8(u'Save & Preview') and self.saveSong(): if button.text() == unicode(self.trUtf8(u'Save && Preview')) \
and self.saveSong():
Receiver().send_message(u'preview_song') Receiver().send_message(u'preview_song')
def closePressed(self):
Receiver().send_message(u'remote_edit_clear')
self.close()
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveSong(): if self.saveSong():
if self.title_change: Receiver().send_message(u'load_song_list')
Receiver().send_message(u'load_song_list')
Receiver().send_message(u'preview_song')
self.close() self.close()
def saveSong(self): def saveSong(self):

View File

@ -55,7 +55,8 @@ class SongMediaItem(MediaManagerItem):
self.edit_song_form = EditSongForm(self.parent.songmanager, self) self.edit_song_form = EditSongForm(self.parent.songmanager, self)
self.song_maintenance_form = SongMaintenanceForm( self.song_maintenance_form = SongMaintenanceForm(
self.parent.songmanager, self) self.parent.songmanager, self)
self.fromPreview = None self.fromPreview = -1
self.fromServiceManager = -1
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -126,6 +127,10 @@ class SongMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'edit_song'), self.onEventEditSong) QtCore.SIGNAL(u'edit_song'), self.onEventEditSong)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'preview_song'), self.onPreviewClick) QtCore.SIGNAL(u'preview_song'), self.onPreviewClick)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear)
def configUpdated(self): def configUpdated(self):
self.searchAsYouType = str_to_bool( self.searchAsYouType = str_to_bool(
@ -179,8 +184,11 @@ class SongMediaItem(MediaManagerItem):
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
self.ListView.addItem(song_name) self.ListView.addItem(song_name)
if song.id == self.fromPreview: if song.id == self.fromPreview:
self.fromPreview = 0
self.ListView.setCurrentItem(song_name) self.ListView.setCurrentItem(song_name)
self.onPreviewClick()
self.fromPreview = -1
if song.id == self.fromServiceManager:
self.onAddClick()
def displayResultsAuthor(self, searchresults): def displayResultsAuthor(self, searchresults):
log.debug(u'display results Author') log.debug(u'display results Author')
@ -226,11 +234,21 @@ class SongMediaItem(MediaManagerItem):
def onSongMaintenanceClick(self): def onSongMaintenanceClick(self):
self.song_maintenance_form.exec_() self.song_maintenance_form.exec_()
def onRemoteEditClear(self):
self.fromServiceManager = -1
def onRemoteEdit(self, songid):
valid = self.parent.songmanager.get_song(songid)
if valid is not None:
self.fromServiceManager = songid
self.edit_song_form.loadSong(songid)
self.edit_song_form.exec_()
def onEditClick(self, preview=False): def onEditClick(self, preview=False):
item = self.ListView.currentItem() item = self.ListView.currentItem()
if item is not None: if item is not None:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.fromPreview = 0 self.fromPreview = -1
if preview: if preview:
self.fromPreview = item_id self.fromPreview = item_id
self.edit_song_form.loadSong(item_id) self.edit_song_form.loadSong(item_id)
@ -253,12 +271,18 @@ class SongMediaItem(MediaManagerItem):
author_list = u'' author_list = u''
author_audit = [] author_audit = []
ccl = u'' ccl = u''
item = self.ListView.currentItem() if self.fromServiceManager == -1:
if item is None: item = self.ListView.currentItem()
return False if item is None:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = self.fromServiceManager
self.fromServiceManager = -1
song = self.parent.songmanager.get_song(item_id) song = self.parent.songmanager.get_song(item_id)
service_item.theme = song.theme_name service_item.theme = song.theme_name
service_item.editEnabled = True
service_item.editId = item_id
if song.lyrics.startswith(u'<?xml version='): if song.lyrics.startswith(u'<?xml version='):
songXML=SongXMLParser(song.lyrics) songXML=SongXMLParser(song.lyrics)
verseList = songXML.get_verses() verseList = songXML.get_verses()

View File

@ -180,4 +180,4 @@ class SongsPlugin(Plugin):
self.opensong_export_form.show() self.opensong_export_form.show()
def about(self): def about(self):
return u'<b>Song Plugin</b> <br>This plugin allows Songs to be managed and displayed.<br><br>This is a core plugin and cannot be made inactive</b>' return u'<b>Song Plugin</b> <br>This plugin allows Songs to be managed and displayed.<br>'