openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #04032
[Merge] lp:~trb143/openlp/bugfixes1 into lp:openlp
Tim Bentley has proposed merging lp:~trb143/openlp/bugfixes1 into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
#637547 Editing a song in a loaded service file crashes
https://bugs.launchpad.net/bugs/637547
#637886 Replacing live video background with nothing live causes crash
https://bugs.launchpad.net/bugs/637886
#642778 enchant.DictNotFoundError: Dictionary for language 'ja_JP' could not be found
https://bugs.launchpad.net/bugs/642778
Add new features:
- Update Service Song item from Edit in Song plugin (with option)
- Allow editing from Service Manager of songs saved
- Frame work for Adding Songs from Service Manager load (with Option)
--
https://code.launchpad.net/~trb143/openlp/bugfixes1/+merge/37786
Your team OpenLP Core is requested to review the proposed merge of lp:~trb143/openlp/bugfixes1 into lp:openlp.
=== modified file 'openlp/core/lib/eventreceiver.py'
--- openlp/core/lib/eventreceiver.py 2010-09-14 18:18:47 +0000
+++ openlp/core/lib/eventreceiver.py 2010-10-06 20:32:48 +0000
@@ -75,7 +75,7 @@
Broadcasts that an item has been made live/previewed
``slidecontroller_{live|preview}_change``
- Informs the slidecontroller that a slide change has occurred and to
+ Informs the slidecontroller that a slide change has occurred and to
update itself
``slidecontroller_{live|preview}_changed``
@@ -83,7 +83,7 @@
``slidecontroller_{live|preview}_text_request``
Request the text for the current item in the controller
- Returns a slidecontroller_{live|preview}_text_response with an
+ Returns a slidecontroller_{live|preview}_text_response with an
array of dictionaries with the tag and verse text
``slidecontroller_{live|preview}_blank``
@@ -106,23 +106,23 @@
``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
+ Blank the maindisplay window
``maindisplay_hide``
- Hide the maindisplay window
+ Hide the maindisplay window
``maindisplay_show``
- Return the maindisplay window
+ Return the maindisplay window
``maindisplay_active``
The maindisplay has been made active
-
+
``maindisplay_status_text``
Changes the bottom status bar text on the maindisplay window
@@ -193,9 +193,17 @@
``{plugin}_add_service_item``
Ask the plugin to push the selected items to the service item
+ ``{plugin}_service_load``
+ Ask the plugin to process an individual service item after it has been
+ loaded
+
+ ``service_item_update``
+ Passes back to the service manager the service item after it has been
+ processed by the plugin
+
``alerts_text``
Displays an alert message
-
+
``bibles_nobook``
Attempt to find book resulted in no match
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py 2010-09-27 18:15:55 +0000
+++ openlp/core/lib/mediamanageritem.py 2010-10-06 20:32:48 +0000
@@ -33,7 +33,7 @@
from openlp.core.lib import context_menu_action, context_menu_separator, \
SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \
- translate
+ translate, Receiver
log = logging.getLogger(__name__)
@@ -94,7 +94,7 @@
QtGui.QWidget.__init__(self)
self.parent = parent
#TODO: plugin should not be the parent in future
- self.plugin = parent#plugin
+ self.plugin = parent # plugin
visible_title = self.plugin.getString(StringContent.VisibleName)
self.title = visible_title[u'title']
self.settingsSection = self.plugin.name.lower()
@@ -115,6 +115,9 @@
self.requiredIcons()
self.setupUi()
self.retranslateUi()
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'%s_service_load' % self.parent.name.lower()),
+ self.serviceLoad)
def requiredIcons(self):
"""
@@ -471,8 +474,8 @@
translate('OpenLP.MediaManagerItem',
'You must select one or more items.'))
else:
- #Is it posssible to process multiple list items to generate multiple
- #service items?
+ # Is it posssible to process multiple list items to generate multiple
+ # service items?
if self.singleServiceItem or self.remoteTriggered:
log.debug(self.plugin.name + u' Add requested')
service_item = self.buildServiceItem()
@@ -501,7 +504,7 @@
log.debug(self.plugin.name + u' Add requested')
service_item = self.parent.serviceManager.getServiceItem()
if not service_item:
- QtGui.QMessageBox.information(self,
+ QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem',
'No Service Item Selected'),
translate('OpenLP.MediaManagerItem',
@@ -531,3 +534,11 @@
return service_item
else:
return None
+
+ def serviceLoad(self, message):
+ """
+ Method to add processing when a service has been loaded and
+ individual service items need to be processed by the plugins
+ """
+ pass
+
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py 2010-09-29 20:39:15 +0000
+++ openlp/core/lib/serviceitem.py 2010-10-06 20:32:48 +0000
@@ -58,6 +58,9 @@
AllowsLoop = 5
AllowsAdditions = 6
NoLineBreaks = 7
+ OnLoadUpdate = 8
+ AddIfNewItem = 9
+
class ServiceItem(object):
"""
@@ -98,6 +101,9 @@
self.main = None
self.footer = None
self.bg_image_bytes = None
+ self._new_item()
+ self.search_string = u''
+ self.data_string = u''
def _new_item(self):
"""
@@ -255,7 +261,9 @@
u'audit':self.audit,
u'notes':self.notes,
u'from_plugin':self.from_plugin,
- u'capabilities':self.capabilities
+ u'capabilities':self.capabilities,
+ u'search':self.search_string,
+ u'data':self.data_string
}
service_data = []
if self.service_item_type == ServiceItemType.Text:
@@ -293,6 +301,10 @@
self.notes = header[u'notes']
self.from_plugin = header[u'from_plugin']
self.capabilities = header[u'capabilities']
+ # Added later so may not be present in older services.
+ if u'search' in header:
+ self.search_string = header[u'search']
+ self.data_string = header[u'data']
if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
self._raw_frames.append(slide)
=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py 2010-09-27 18:34:40 +0000
+++ openlp/core/ui/servicemanager.py 2010-10-06 20:32:48 +0000
@@ -223,6 +223,8 @@
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
# Last little bits of setting up
self.service_theme = unicode(QtCore.QSettings().value(
self.parent.serviceSettingsSection + u'/service theme',
@@ -711,6 +713,9 @@
serviceitem.set_from_service(item, self.servicePath)
self.validateItem(serviceitem)
self.addServiceItem(serviceitem)
+ if serviceitem.is_capable(ItemCapabilities.OnLoadUpdate):
+ Receiver.send_message(u'%s_service_load' %
+ serviceitem.name.lower(), serviceitem)
try:
if os.path.isfile(p_file):
os.remove(p_file)
@@ -801,7 +806,31 @@
# does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName)
- def addServiceItem(self, item, rebuild=False, expand=True, replace=False):
+ def serviceItemUpdate(self, message):
+ """
+ Triggered from plugins to update service items.
+ """
+ editId, uuid = message.split(u':')
+ for item in self.serviceItems:
+ if item[u'service_item']._uuid == uuid:
+ item[u'service_item'].editId = editId
+
+ def replaceServiceItem(self, newItem):
+ """
+ Using the service item passed replace the one with the same edit id
+ if found.
+ """
+ newItem.render()
+ for itemcount, item in enumerate(self.serviceItems):
+ if item[u'service_item'].editId == newItem.editId and \
+ item[u'service_item'].name == newItem.name:
+ newItem.merge(item[u'service_item'])
+ item[u'service_item'] = newItem
+ self.repaintServiceList(itemcount + 1, 0)
+ self.parent.LiveController.replaceServiceManagerItem(newItem)
+ self.parent.serviceChanged(False, self.serviceName)
+
+ def addServiceItem(self, item, rebuild=False, expand=False, replace=False):
"""
Add a Service item to the list
@@ -817,7 +846,7 @@
self.repaintServiceList(sitem + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(item)
else:
- #nothing selected for dnd
+ # nothing selected for dnd
if self.droppos == 0:
if isinstance(item, list):
for inditem in item:
@@ -834,7 +863,7 @@
u'order': self.droppos,
u'expanded':expand})
self.repaintServiceList(self.droppos, 0)
- #if rebuilding list make sure live is fixed.
+ # if rebuilding list make sure live is fixed.
if rebuild:
self.parent.LiveController.replaceServiceManagerItem(item)
self.droppos = 0
@@ -914,7 +943,7 @@
else:
pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
count = item.data(0, QtCore.Qt.UserRole).toInt()[0]
- #adjust for zero based arrays
+ # adjust for zero based arrays
pos = pos - 1
return pos, count
@@ -940,7 +969,7 @@
if link.hasText():
plugin = event.mimeData().text()
item = self.serviceManagerList.itemAt(event.pos())
- #ServiceManager started the drag and drop
+ # ServiceManager started the drag and drop
if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem()
if item is None:
@@ -952,22 +981,22 @@
self.serviceItems.insert(endpos, serviceItem)
self.repaintServiceList(endpos, startCount)
else:
- #we are not over anything so drop
+ # we are not over anything so drop
replace = False
if item is None:
self.droppos = len(self.serviceItems)
else:
- #we are over somthing so lets investigate
+ # 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
+ # New action required
if action == self.newAction:
self.droppos = self._getParentItemData(item)
- #Append to existing action
+ # Append to existing action
if action == self.addToAction:
self.droppos = self._getParentItemData(item)
item.setSelected(True)
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2010-09-27 18:34:40 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2010-10-06 20:32:48 +0000
@@ -60,6 +60,7 @@
# Holds information about whether the edit is remotly triggered and
# which Song is required.
self.remoteSong = -1
+ self.editItem = None
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
@@ -123,7 +124,7 @@
QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onSearchTextEditChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
- QtCore.SIGNAL(u'songs_load_list'), self.onSearchTextButtonClick)
+ QtCore.SIGNAL(u'songs_load_list'), self.onSongListLoad)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(),
@@ -137,6 +138,12 @@
self.searchAsYouType = QtCore.QSettings().value(
self.settingsSection + u'/search as type',
QtCore.QVariant(u'False')).toBool()
+ self.updateServiceOnEdit = QtCore.QSettings().value(
+ self.settingsSection + u'/update service on edit',
+ QtCore.QVariant(u'False')).toBool()
+ self.AddSongFromServide = QtCore.QSettings().value(
+ self.settingsSection + u'/add song from service',
+ QtCore.QVariant(u'True')).toBool()
def retranslateUi(self):
self.SearchTextLabel.setText(
@@ -179,14 +186,26 @@
Author.display_name.like(u'%' + search_keywords + u'%'),
Author.display_name.asc())
self.displayResultsAuthor(search_results)
- #Called to redisplay the song list screen edith from a search
- #or from the exit of the Song edit dialog. If remote editing is active
- #Trigger it and clean up so it will not update again.
+
+ def onSongListLoad(self):
+ """
+ Handle the exit from the edit dialog and trigger remote updates
+ of songs
+ """
+ # Called to redisplay the song list screen edit from a search
+ # or from the exit of the Song edit dialog. If remote editing is active
+ # Trigger it and clean up so it will not update again.
if self.remoteTriggered == u'L':
self.onAddClick()
if self.remoteTriggered == u'P':
self.onPreviewClick()
+ # Push edits to the service manager to update items
+ if self.editItem and self.updateServiceOnEdit and \
+ not self.remoteTriggered:
+ item = self.buildServiceItem(self.editItem)
+ self.parent.serviceManager.replaceServiceItem(item)
self.onRemoteEditClear()
+ self.onSearchTextButtonClick()
def displayResultsSong(self, searchresults):
log.debug(u'display results Song')
@@ -271,8 +290,8 @@
if check_item_selected(self.listView,
translate('SongsPlugin.MediaItem',
'You must select an item to edit.')):
- item = self.listView.currentItem()
- item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
+ self.editItem = self.listView.currentItem()
+ item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
self.edit_song_form.loadSong(item_id, False)
self.edit_song_form.exec_()
@@ -322,6 +341,8 @@
service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
+ service_item.add_capability(ItemCapabilities.OnLoadUpdate)
+ service_item.add_capability(ItemCapabilities.AddIfNewItem)
song = self.parent.manager.get_object(Song, item_id)
service_item.theme = song.theme_name
service_item.editId = item_id
@@ -368,4 +389,31 @@
service_item.audit = [
song.title, author_audit, song.copyright, unicode(song.ccli_number)
]
+ service_item.data_string = {u'title':song.search_title, u'authors':author_list}
return True
+
+ def serviceLoad(self, item):
+ """
+ Triggered by a song being loaded by the service item
+ """
+ if item.data_string:
+ search_results = self.parent.manager.get_all_objects(Song,
+ Song.search_title.like(u'%' +
+ item.data_string[u'title'].split(u'@')[0] + u'%'),
+ Song.search_title.asc())
+ author_list = item.data_string[u'authors'].split(u',')
+ editId = 0
+ uuid = 0
+ if search_results:
+ for song in search_results:
+ count = 0
+ for author in song.authors:
+ if author.display_name in author_list:
+ count += 1
+ if count == len(author_list):
+ editId = song.id
+ uuid = item._uuid
+ if editId != 0:
+ Receiver.send_message(u'service_item_update',
+ u'%s:%s' %(editId, uuid))
+
=== modified file 'openlp/plugins/songs/lib/songstab.py'
--- openlp/plugins/songs/lib/songstab.py 2010-09-16 21:10:36 +0000
+++ openlp/plugins/songs/lib/songstab.py 2010-10-06 20:32:48 +0000
@@ -51,8 +51,14 @@
self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox')
self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox)
self.SongBarActiveCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
- self.SongBarActiveCheckBox.setObjectName(u'SearchAsTypeCheckBox')
+ self.SongBarActiveCheckBox.setObjectName(u'SongBarActiveCheckBox')
self.SongsModeLayout.addWidget(self.SongBarActiveCheckBox)
+ self.SongUpdateOnEditCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
+ self.SongUpdateOnEditCheckBox.setObjectName(u'SongUpdateOnEditCheckBox')
+ self.SongsModeLayout.addWidget(self.SongUpdateOnEditCheckBox)
+ self.SongAddFromServiceCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
+ self.SongAddFromServiceCheckBox.setObjectName(u'SongAddFromServiceCheckBox')
+ self.SongsModeLayout.addWidget(self.SongAddFromServiceCheckBox)
self.SongsLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.SongsModeGroupBox)
QtCore.QObject.connect(self.SearchAsTypeCheckBox,
@@ -60,7 +66,13 @@
self.onSearchAsTypeCheckBoxChanged)
QtCore.QObject.connect(self.SongBarActiveCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
- self.SongBarActiveCheckBoxChanged)
+ self.onSongBarActiveCheckBoxChanged)
+ QtCore.QObject.connect(self.SongUpdateOnEditCheckBox,
+ QtCore.SIGNAL(u'stateChanged(int)'),
+ self.onSongUpdateOnEditCheckBoxChanged)
+ QtCore.QObject.connect(self.SongBarActiveCheckBox,
+ QtCore.SIGNAL(u'stateChanged(int)'),
+ self.onSongAddFromServiceCheckBoxChanged)
def retranslateUi(self):
self.SongsModeGroupBox.setTitle(
@@ -69,6 +81,10 @@
translate('SongsPlugin.SongsTab', 'Enable search as you type'))
self.SongBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab',
'Display verses on live tool bar'))
+ self.SongUpdateOnEditCheckBox.setText(
+ translate('SongsPlugin.SongsTab', 'Update service from song edit'))
+ self.SongAddFromServiceCheckBox.setText(translate('SongsPlugin.SongsTab',
+ 'Add missing songs when opening service'))
def onSearchAsTypeCheckBoxChanged(self, check_state):
self.song_search = False
@@ -76,12 +92,24 @@
if check_state == QtCore.Qt.Checked:
self.song_search = True
- def SongBarActiveCheckBoxChanged(self, check_state):
+ def onSongBarActiveCheckBoxChanged(self, check_state):
self.song_bar = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
self.song_bar = True
+ def onSongUpdateOnEditCheckBoxChanged(self, check_state):
+ self.update_edit = False
+ # we have a set value convert to True/False
+ if check_state == QtCore.Qt.Checked:
+ self.update_edit = True
+
+ def onSongAddFromServiceCheckBoxChanged(self, check_state):
+ self.update_load = False
+ # we have a set value convert to True/False
+ if check_state == QtCore.Qt.Checked:
+ self.update_load = True
+
def load(self):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
@@ -89,8 +117,14 @@
u'search as type', QtCore.QVariant(False)).toBool()
self.song_bar = settings.value(
u'display songbar', QtCore.QVariant(True)).toBool()
+ self.update_edit = settings.value(
+ u'update service on edit', QtCore.QVariant(False)).toBool()
+ self.update_load = settings.value(
+ u'add song from service', QtCore.QVariant(True)).toBool()
self.SearchAsTypeCheckBox.setChecked(self.song_search)
self.SongBarActiveCheckBox.setChecked(self.song_bar)
+ self.SongUpdateOnEditCheckBox.setChecked(self.update_edit)
+ self.SongAddFromServiceCheckBox.setChecked(self.update_load)
settings.endGroup()
def save(self):
@@ -98,4 +132,6 @@
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.setValue(u'update service on edit', QtCore.QVariant(self.update_edit))
+ settings.setValue(u'add song from service', QtCore.QVariant(self.update_load))
settings.endGroup()
Follow ups