This commit is contained in:
Tim Bentley 2013-01-24 20:08:52 +00:00
commit c0aca32660
14 changed files with 344 additions and 102 deletions

View File

@ -160,7 +160,7 @@ class ServiceItem(object):
self.service_item_type = None self.service_item_type = None
self._raw_frames = [] self._raw_frames = []
self._display_frames = [] self._display_frames = []
self._uuid = 0 self.unique_identifier = 0
self.notes = u'' self.notes = u''
self.from_plugin = False self.from_plugin = False
self.capabilities = [] self.capabilities = []
@ -194,7 +194,7 @@ class ServiceItem(object):
Method to set the internal id of the item. This is used to compare Method to set the internal id of the item. This is used to compare
service items to see if they are the same. service items to see if they are the same.
""" """
self._uuid = unicode(uuid.uuid1()) self.unique_identifier = unicode(uuid.uuid1())
self.validate_item() self.validate_item()
def add_capability(self, capability): def add_capability(self, capability):
@ -453,14 +453,14 @@ class ServiceItem(object):
def merge(self, other): def merge(self, other):
""" """
Updates the _uuid with the value from the original one Updates the unique_identifier with the value from the original one
The _uuid is unique for a given service item but this allows one to The unique_identifier is unique for a given service item but this allows one to
replace an original version. replace an original version.
``other`` ``other``
The service item to be merged with The service item to be merged with
""" """
self._uuid = other._uuid self.unique_identifier = other.unique_identifier
self.notes = other.notes self.notes = other.notes
self.temporary_edit = other.temporary_edit self.temporary_edit = other.temporary_edit
# Copy theme over if present. # Copy theme over if present.
@ -477,13 +477,13 @@ class ServiceItem(object):
""" """
if not other: if not other:
return False return False
return self._uuid == other._uuid return self.unique_identifier == other.unique_identifier
def __ne__(self, other): def __ne__(self, other):
""" """
Confirms the service items are not for the same instance Confirms the service items are not for the same instance
""" """
return self._uuid != other._uuid return self.unique_identifier != other.unique_identifier
def is_media(self): def is_media(self):
""" """
@ -636,12 +636,12 @@ class ServiceItem(object):
if self.is_image() and not os.path.exists((frame[u'path'])): if self.is_image() and not os.path.exists((frame[u'path'])):
self.is_valid = False self.is_valid = False
elif self.is_command(): elif self.is_command():
file = os.path.join(frame[u'path'],frame[u'title']) file_name = os.path.join(frame[u'path'], frame[u'title'])
if not os.path.exists(file): if not os.path.exists(file_name):
self.is_valid = False self.is_valid = False
if suffix_list and not self.is_text(): if suffix_list and not self.is_text():
type = frame[u'title'].split(u'.')[-1] file_suffix = frame[u'title'].split(u'.')[-1]
if type.lower() not in suffix_list: if file_suffix.lower() not in suffix_list:
self.is_valid = False self.is_valid = False
def _get_renderer(self): def _get_renderer(self):

View File

@ -102,8 +102,7 @@ def set_media_players(players_list, overridden_player=u'auto'):
""" """
log.debug(u'set_media_players') log.debug(u'set_media_players')
players = u','.join(players_list) players = u','.join(players_list)
if Settings().value(u'media/override player', QtCore.Qt.Unchecked) == QtCore.Qt.Checked and \ if Settings().value(u'media/override player') == QtCore.Qt.Checked and overridden_player != u'auto':
overridden_player != u'auto':
players = players.replace(overridden_player, u'[%s]' % overridden_player) players = players.replace(overridden_player, u'[%s]' % overridden_player)
Settings().setValue(u'media/players', players) Settings().setValue(u'media/players', players)

View File

@ -411,13 +411,13 @@ class WebkitPlayer(MediaPlayer):
else: else:
if display.frame.evaluateJavaScript(u'show_video("isEnded");') == 'true': if display.frame.evaluateJavaScript(u'show_video("isEnded");') == 'true':
self.stop(display) self.stop(display)
(currentTime, ok) = display.frame.evaluateJavaScript(u'show_video("currentTime");') currentTime = display.frame.evaluateJavaScript(u'show_video("currentTime");')
# check if conversion was ok and value is not 'NaN' # check if conversion was ok and value is not 'NaN'
if ok and currentTime != float('inf'): if currentTime and currentTime != float('inf'):
currentTime = int(currentTime * 1000) currentTime = int(currentTime * 1000)
(length, ok) = display.frame.evaluateJavaScript(u'show_video("length");') length = display.frame.evaluateJavaScript(u'show_video("length");')
# check if conversion was ok and value is not 'NaN' # check if conversion was ok and value is not 'NaN'
if ok and length != float('inf'): if length and length != float('inf'):
length = int(length * 1000) length = int(length * 1000)
if currentTime > 0: if currentTime > 0:
controller.media_info.length = length controller.media_info.length = length

View File

@ -110,7 +110,7 @@ class ServiceManager(QtGui.QWidget):
self.suffixes = [] self.suffixes = []
self.dropPosition = 0 self.dropPosition = 0
self.expandTabs = False self.expandTabs = False
self.serviceId = 0 self.service_id = 0
# is a new service and has not been saved # is a new service and has not been saved
self._modified = False self._modified = False
self._fileName = u'' self._fileName = u''
@ -165,8 +165,7 @@ class ServiceManager(QtGui.QWidget):
# Add the bottom toolbar # Add the bottom toolbar
self.orderToolbar = OpenLPToolbar(self) self.orderToolbar = OpenLPToolbar(self)
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.add_category( action_list.add_category(UiStrings().Service, CategoryOrder.standardToolbar)
UiStrings().Service, CategoryOrder.standardToolbar)
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(u'moveTop', self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(u'moveTop',
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=u':/services/service_top.png', text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=u':/services/service_top.png',
tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'), tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'),
@ -297,7 +296,7 @@ class ServiceManager(QtGui.QWidget):
has been modified. has been modified.
""" """
if modified: if modified:
self.serviceId += 1 self.service_id += 1
self._modified = modified self._modified = modified
serviceFile = self.shortFileName() or translate('OpenLP.ServiceManager', 'Untitled Service') serviceFile = self.shortFileName() or translate('OpenLP.ServiceManager', 'Untitled Service')
self.main_window.setServiceModified(modified, serviceFile) self.main_window.setServiceModified(modified, serviceFile)
@ -394,6 +393,9 @@ class ServiceManager(QtGui.QWidget):
self.loadFile(fileName) self.loadFile(fileName)
def saveModifiedService(self): def saveModifiedService(self):
"""
Check to see if a service needs to be saved.
"""
return QtGui.QMessageBox.question(self.main_window, return QtGui.QMessageBox.question(self.main_window,
translate('OpenLP.ServiceManager', 'Modified Service'), translate('OpenLP.ServiceManager', 'Modified Service'),
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
@ -401,6 +403,9 @@ class ServiceManager(QtGui.QWidget):
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save) QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
def onRecentServiceClicked(self): def onRecentServiceClicked(self):
"""
Load a recent file as the service triggered by mainwindow recent service list.
"""
sender = self.sender() sender = self.sender()
self.loadFile(sender.data()) self.loadFile(sender.data())
@ -411,7 +416,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceManagerList.clear() self.serviceManagerList.clear()
self.serviceItems = [] self.serviceItems = []
self.setFileName(u'') self.setFileName(u'')
self.serviceId += 1 self.service_id += 1
self.setModified(False) self.setModified(False)
Settings().setValue(u'servicemanager/last file', u'') Settings().setValue(u'servicemanager/last file', u'')
Receiver.send_message(u'servicemanager_new_service') Receiver.send_message(u'servicemanager_new_service')
@ -478,38 +483,36 @@ class ServiceManager(QtGui.QWidget):
else: else:
service_item = item[u'service_item'].get_service_repr(self._saveLite) service_item = item[u'service_item'].get_service_repr(self._saveLite)
if service_item[u'header'][u'background_audio']: if service_item[u'header'][u'background_audio']:
for i, filename in enumerate( for i, filename in enumerate(service_item[u'header'][u'background_audio']):
service_item[u'header'][u'background_audio']): new_file = os.path.join(u'audio', item[u'service_item'].unique_identifier, filename)
new_file = os.path.join(u'audio',
item[u'service_item']._uuid, filename)
audio_files.append((filename, new_file)) audio_files.append((filename, new_file))
service_item[u'header'][u'background_audio'][i] = new_file service_item[u'header'][u'background_audio'][i] = new_file
# Add the service item to the service. # Add the service item to the service.
service.append({u'serviceitem': service_item}) service.append({u'serviceitem': service_item})
self.repaintServiceList(-1, -1) self.repaintServiceList(-1, -1)
for file in write_list: for file_item in write_list:
file_size = os.path.getsize(file) file_size = os.path.getsize(file_item)
total_size += file_size total_size += file_size
log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' % total_size) log.debug(u'ServiceManager.savefile - ZIP contents size is %i bytes' % total_size)
service_content = cPickle.dumps(service) service_content = cPickle.dumps(service)
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be
# extracted using unzip in UNIX. # extracted using unzip in UNIX.
allow_zip_64 = (total_size > 2147483648 + len(service_content)) allow_zip_64 = (total_size > 2147483648 + len(service_content))
log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64) log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64)
zip = None zip_file = None
success = True success = True
self.main_window.incrementProgressBar() self.main_window.incrementProgressBar()
try: try:
zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64)
# First we add service contents. # First we add service contents.
# We save ALL filenames into ZIP using UTF-8. # We save ALL filenames into ZIP using UTF-8.
zip.writestr(service_file_name.encode(u'utf-8'), service_content) zip_file.writestr(service_file_name.encode(u'utf-8'), service_content)
# Finally add all the listed media files. # Finally add all the listed media files.
for write_from in write_list: for write_from in write_list:
zip.write(write_from, write_from.encode(u'utf-8')) zip_file.write(write_from, write_from.encode(u'utf-8'))
for audio_from, audio_to in audio_files: for audio_from, audio_to in audio_files:
if audio_from.startswith(u'audio'): if audio_from.startswith(u'audio'):
# When items are saved, they get new UUID's. Let's copy the # When items are saved, they get new unique_identifier. Let's copy the
# file to the new location. Unused files can be ignored, # file to the new location. Unused files can be ignored,
# OpenLP automatically cleans up the service manager dir on # OpenLP automatically cleans up the service manager dir on
# exit. # exit.
@ -519,7 +522,7 @@ class ServiceManager(QtGui.QWidget):
check_directory_exists(save_path) check_directory_exists(save_path)
if not os.path.exists(save_file): if not os.path.exists(save_file):
shutil.copy(audio_from, save_file) shutil.copy(audio_from, save_file)
zip.write(audio_from, audio_to.encode(u'utf-8')) zip_file.write(audio_from, audio_to.encode(u'utf-8'))
except IOError: except IOError:
log.exception(u'Failed to save service to disk: %s', temp_file_name) log.exception(u'Failed to save service to disk: %s', temp_file_name)
Receiver.send_message(u'openlp_error_message', { Receiver.send_message(u'openlp_error_message', {
@ -528,8 +531,8 @@ class ServiceManager(QtGui.QWidget):
}) })
success = False success = False
finally: finally:
if zip: if zip_file:
zip.close() zip_file.close()
self.main_window.finishedProgressBar() self.main_window.finishedProgressBar()
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
if success: if success:
@ -544,12 +547,8 @@ class ServiceManager(QtGui.QWidget):
def saveLocalFile(self): def saveLocalFile(self):
""" """
Save the current service file. Save the current service file but leave all the file references alone to point to the current machine.
This format is not transportable as it will not contain any files.
A temporary file is created so that we don't overwrite the existing one
and leave a mangled service file should there be an error when saving.
No files are added to this version of the service as it is deisgned
to only work on the machine it was save on if there are files.
""" """
if not self.fileName(): if not self.fileName():
return self.saveFileAs() return self.saveFileAs()
@ -559,8 +558,8 @@ class ServiceManager(QtGui.QWidget):
log.debug(temp_file_name) log.debug(temp_file_name)
path_file_name = unicode(self.fileName()) path_file_name = unicode(self.fileName())
path, file_name = os.path.split(path_file_name) path, file_name = os.path.split(path_file_name)
basename = os.path.splitext(file_name)[0] base_name = os.path.splitext(file_name)[0]
service_file_name = '%s.osd' % basename service_file_name = '%s.osd' % base_name
log.debug(u'ServiceManager.saveFile - %s', path_file_name) log.debug(u'ServiceManager.saveFile - %s', path_file_name)
Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path) Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path)
service = [] service = []
@ -574,14 +573,14 @@ class ServiceManager(QtGui.QWidget):
service.append({u'serviceitem': service_item}) service.append({u'serviceitem': service_item})
self.main_window.incrementProgressBar() self.main_window.incrementProgressBar()
service_content = cPickle.dumps(service) service_content = cPickle.dumps(service)
zip = None zip_file = None
success = True success = True
self.main_window.incrementProgressBar() self.main_window.incrementProgressBar()
try: try:
zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED,
True) True)
# First we add service contents. # First we add service contents.
zip.writestr(service_file_name.encode(u'utf-8'), service_content) zip_file.writestr(service_file_name.encode(u'utf-8'), service_content)
except IOError: except IOError:
log.exception(u'Failed to save service to disk: %s', temp_file_name) log.exception(u'Failed to save service to disk: %s', temp_file_name)
Receiver.send_message(u'openlp_error_message', { Receiver.send_message(u'openlp_error_message', {
@ -590,8 +589,8 @@ class ServiceManager(QtGui.QWidget):
}) })
success = False success = False
finally: finally:
if zip: if zip_file:
zip.close() zip_file.close()
self.main_window.finishedProgressBar() self.main_window.finishedProgressBar()
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
if success: if success:
@ -704,11 +703,11 @@ class ServiceManager(QtGui.QWidget):
else: else:
serviceItem.set_from_service(item, self.servicePath) serviceItem.set_from_service(item, self.servicePath)
serviceItem.validate_item(self.suffixes) serviceItem.validate_item(self.suffixes)
self.load_item_uuid = 0 self.load_item_unique_identifier = 0
if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate): if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem)
# if the item has been processed # if the item has been processed
if serviceItem._uuid == self.load_item_uuid: if serviceItem.unique_identifier == self.load_item_unique_identifier:
serviceItem.edit_id = int(self.load_item_edit_id) serviceItem.edit_id = int(self.load_item_edit_id)
serviceItem.temporary_edit = self.load_item_temporary serviceItem.temporary_edit = self.load_item_temporary
self.addServiceItem(serviceItem, repaint=False) self.addServiceItem(serviceItem, repaint=False)
@ -755,6 +754,9 @@ class ServiceManager(QtGui.QWidget):
self.loadFile(fileName) self.loadFile(fileName)
def contextMenu(self, point): def contextMenu(self, point):
"""
The Right click context menu from the Serviceitem list
"""
item = self.serviceManagerList.itemAt(point) item = self.serviceManagerList.itemAt(point)
if item is None: if item is None:
return return
@ -776,15 +778,13 @@ class ServiceManager(QtGui.QWidget):
if item.parent() is None: if item.parent() is None:
self.notesAction.setVisible(True) self.notesAction.setVisible(True)
if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \ if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \
len(serviceItem[u'service_item'].get_frames()) > 1: len(serviceItem[u'service_item'].get_frames()) > 1:
self.autoPlaySlidesGroup.menuAction().setVisible(True) self.autoPlaySlidesGroup.menuAction().setVisible(True)
self.autoPlaySlidesOnce.setChecked(serviceItem[u'service_item'].auto_play_slides_once) self.autoPlaySlidesOnce.setChecked(serviceItem[u'service_item'].auto_play_slides_once)
self.autoPlaySlidesLoop.setChecked(serviceItem[u'service_item'].auto_play_slides_loop) self.autoPlaySlidesLoop.setChecked(serviceItem[u'service_item'].auto_play_slides_loop)
self.timedSlideInterval.setChecked(serviceItem[u'service_item'].timed_slide_interval > 0) self.timedSlideInterval.setChecked(serviceItem[u'service_item'].timed_slide_interval > 0)
if serviceItem[u'service_item'].timed_slide_interval > 0: if serviceItem[u'service_item'].timed_slide_interval > 0:
delay_suffix = u' ' delay_suffix = u' %s s' % unicode(serviceItem[u'service_item'].timed_slide_interval)
delay_suffix += unicode(serviceItem[u'service_item'].timed_slide_interval)
delay_suffix += u' s'
else: else:
delay_suffix = u' ...' delay_suffix = u' ...'
self.timedSlideInterval.setText(translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix) self.timedSlideInterval.setText(translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix)
@ -881,8 +881,8 @@ class ServiceManager(QtGui.QWidget):
timed_slide_interval, 0, 180, 1) timed_slide_interval, 0, 180, 1)
if ok: if ok:
service_item.timed_slide_interval = timed_slide_interval service_item.timed_slide_interval = timed_slide_interval
if service_item.timed_slide_interval <> 0 and not service_item.auto_play_slides_loop\ if service_item.timed_slide_interval != 0 and not service_item.auto_play_slides_loop \
and not service_item.auto_play_slides_once: and not service_item.auto_play_slides_once:
service_item.auto_play_slides_loop = True service_item.auto_play_slides_loop = True
elif service_item.timed_slide_interval == 0: elif service_item.timed_slide_interval == 0:
service_item.auto_play_slides_loop = False service_item.auto_play_slides_loop = False
@ -914,9 +914,9 @@ class ServiceManager(QtGui.QWidget):
Called by the SlideController to request a preview item be made live Called by the SlideController to request a preview item be made live
and allows the next preview to be updated if relevant. and allows the next preview to be updated if relevant.
""" """
uuid, row = message.split(u':') unique_identifier, row = message.split(u':')
for sitem in self.serviceItems: for sitem in self.serviceItems:
if sitem[u'service_item']._uuid == uuid: if sitem[u'service_item'].unique_identifier == unique_identifier:
item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1) item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1)
self.serviceManagerList.setCurrentItem(item) self.serviceManagerList.setCurrentItem(item)
self.makeLive(int(row)) self.makeLive(int(row))
@ -1119,7 +1119,7 @@ class ServiceManager(QtGui.QWidget):
self.service_has_all_original_files = False self.service_has_all_original_files = False
# Repaint the screen # Repaint the screen
self.serviceManagerList.clear() self.serviceManagerList.clear()
for itemcount, item in enumerate(self.serviceItems): for item_count, item in enumerate(self.serviceItems):
serviceitem = item[u'service_item'] serviceitem = item[u'service_item']
treewidgetitem = QtGui.QTreeWidgetItem(self.serviceManagerList) treewidgetitem = QtGui.QTreeWidgetItem(self.serviceManagerList)
if serviceitem.is_valid: if serviceitem.is_valid:
@ -1168,7 +1168,7 @@ class ServiceManager(QtGui.QWidget):
text = frame[u'title'].replace(u'\n', u' ') text = frame[u'title'].replace(u'\n', u' ')
child.setText(0, text[:40]) child.setText(0, text[:40])
child.setData(0, QtCore.Qt.UserRole, count) child.setData(0, QtCore.Qt.UserRole, count)
if serviceItem == itemcount: if serviceItem == item_count:
if item[u'expanded'] and serviceItemChild == count: if item[u'expanded'] and serviceItemChild == count:
self.serviceManagerList.setCurrentItem(child) self.serviceManagerList.setCurrentItem(child)
elif serviceItemChild == -1: elif serviceItemChild == -1:
@ -1250,7 +1250,7 @@ class ServiceManager(QtGui.QWidget):
Triggered from plugins to update service items. Triggered from plugins to update service items.
Save the values as they will be used as part of the service load Save the values as they will be used as part of the service load
""" """
edit_id, self.load_item_uuid, temporary = message.split(u':') edit_id, self.load_item_unique_identifier, temporary = message.split(u':')
self.load_item_edit_id = int(edit_id) self.load_item_edit_id = int(edit_id)
self.load_item_temporary = str_to_bool(temporary) self.load_item_temporary = str_to_bool(temporary)
@ -1259,12 +1259,12 @@ class ServiceManager(QtGui.QWidget):
Using the service item passed replace the one with the same edit id Using the service item passed replace the one with the same edit id
if found. if found.
""" """
for itemcount, item in enumerate(self.serviceItems): for item_count, item in enumerate(self.serviceItems):
if item[u'service_item'].edit_id == newItem.edit_id and item[u'service_item'].name == newItem.name: if item[u'service_item'].edit_id == newItem.edit_id and item[u'service_item'].name == newItem.name:
newItem.render() newItem.render()
newItem.merge(item[u'service_item']) newItem.merge(item[u'service_item'])
item[u'service_item'] = newItem item[u'service_item'] = newItem
self.repaintServiceList(itemcount + 1, 0) self.repaintServiceList(item_count + 1, 0)
self.live_controller.replaceServiceManagerItem(newItem) self.live_controller.replaceServiceManagerItem(newItem)
self.setModified() self.setModified()
@ -1405,11 +1405,11 @@ class ServiceManager(QtGui.QWidget):
serviceItem = -1 serviceItem = -1
serviceItemChild = -1 serviceItemChild = -1
for item in items: for item in items:
parentitem = item.parent() parent_item = item.parent()
if parentitem is None: if parent_item is None:
serviceItem = item.data(0, QtCore.Qt.UserRole) serviceItem = item.data(0, QtCore.Qt.UserRole)
else: else:
serviceItem = parentitem.data(0, QtCore.Qt.UserRole) serviceItem = parent_item.data(0, QtCore.Qt.UserRole)
serviceItemChild = item.data(0, QtCore.Qt.UserRole) serviceItemChild = item.data(0, QtCore.Qt.UserRole)
# Adjust for zero based arrays. # Adjust for zero based arrays.
serviceItem -= 1 serviceItem -= 1
@ -1458,7 +1458,7 @@ class ServiceManager(QtGui.QWidget):
if item is None: if item is None:
endpos = len(self.serviceItems) endpos = len(self.serviceItems)
else: else:
endpos = self._getParentItemData(item) - 1 endpos = self._get_parent_item_data(item) - 1
serviceItem = self.serviceItems[startpos] serviceItem = self.serviceItems[startpos]
self.serviceItems.remove(serviceItem) self.serviceItems.remove(serviceItem)
self.serviceItems.insert(endpos, serviceItem) self.serviceItems.insert(endpos, serviceItem)
@ -1471,21 +1471,21 @@ class ServiceManager(QtGui.QWidget):
self.dropPosition = len(self.serviceItems) self.dropPosition = len(self.serviceItems)
else: else:
# we are over something so lets investigate # we are over something so lets investigate
pos = self._getParentItemData(item) - 1 pos = self._get_parent_item_data(item) - 1
serviceItem = self.serviceItems[pos] serviceItem = self.serviceItems[pos]
if (plugin == serviceItem[u'service_item'].name and if (plugin == serviceItem[u'service_item'].name and
serviceItem[u'service_item'].is_capable(ItemCapabilities.CanAppend)): serviceItem[u'service_item'].is_capable(ItemCapabilities.CanAppend)):
action = self.dndMenu.exec_(QtGui.QCursor.pos()) action = self.dndMenu.exec_(QtGui.QCursor.pos())
# New action required # New action required
if action == self.newAction: if action == self.newAction:
self.dropPosition = self._getParentItemData(item) self.dropPosition = self._get_parent_item_data(item)
# Append to existing action # Append to existing action
if action == self.addToAction: if action == self.addToAction:
self.dropPosition = self._getParentItemData(item) self.dropPosition = self._get_parent_item_data(item)
item.setSelected(True) item.setSelected(True)
replace = True replace = True
else: else:
self.dropPosition = self._getParentItemData(item) self.dropPosition = self._get_parent_item_data(item)
Receiver.send_message(u'%s_add_service_item' % plugin, replace) Receiver.send_message(u'%s_add_service_item' % plugin, replace)
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
@ -1517,6 +1517,9 @@ class ServiceManager(QtGui.QWidget):
self.regenerateServiceItems() self.regenerateServiceItems()
def onThemeChangeAction(self): def onThemeChangeAction(self):
"""
Handles theme change events
"""
theme = self.sender().objectName() theme = self.sender().objectName()
# No object name means that the "Default" theme is supposed to be used. # No object name means that the "Default" theme is supposed to be used.
if not theme: if not theme:
@ -1525,12 +1528,15 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item'].update_theme(theme) self.serviceItems[item][u'service_item'].update_theme(theme)
self.regenerateServiceItems(True) self.regenerateServiceItems(True)
def _getParentItemData(self, item): def _get_parent_item_data(self, item):
parentitem = item.parent() """
if parentitem is None: Finds and returns the parent item for any item
"""
parent_item = item.parent()
if parent_item is None:
return item.data(0, QtCore.Qt.UserRole) return item.data(0, QtCore.Qt.UserRole)
else: else:
return parentitem.data(0, QtCore.Qt.UserRole) return parent_item.data(0, QtCore.Qt.UserRole)
def printServiceOrder(self): def printServiceOrder(self):
""" """

View File

@ -1212,7 +1212,8 @@ class SlideController(DisplayController):
row = self.previewListWidget.currentRow() row = self.previewListWidget.currentRow()
if -1 < row < self.previewListWidget.rowCount(): if -1 < row < self.previewListWidget.rowCount():
if self.serviceItem.from_service: if self.serviceItem.from_service:
Receiver.send_message('servicemanager_preview_live', u'%s:%s' % (self.serviceItem._uuid, row)) Receiver.send_message('servicemanager_preview_live', u'%s:%s' %
(self.serviceItem.unique_identifier, row))
else: else:
self.parent().liveController.addServiceManagerItem(self.serviceItem, row) self.parent().liveController.addServiceManagerItem(self.serviceItem, row)

View File

@ -474,8 +474,7 @@ class ThemeManager(QtGui.QWidget):
Name of the theme to load from file Name of the theme to load from file
""" """
log.debug(u'getthemedata for theme %s', theme_name) log.debug(u'getthemedata for theme %s', theme_name)
xml_file = os.path.join(self.path, unicode(theme_name), xml_file = os.path.join(self.path, unicode(theme_name), unicode(theme_name) + u'.xml')
unicode(theme_name) + u'.xml')
xml = get_text_file_string(xml_file) xml = get_text_file_string(xml_file)
if not xml: if not xml:
log.debug(u'No theme data - using default theme') log.debug(u'No theme data - using default theme')

View File

@ -459,7 +459,7 @@ def get_uno_instance(resolver):
def format_time(text, local_time): def format_time(text, local_time):
""" """
Workaround for Python built-in time formatting fuction time.strftime(). Workaround for Python built-in time formatting function time.strftime().
time.strftime() accepts only ascii characters. This function accepts time.strftime() accepts only ascii characters. This function accepts
unicode string and passes individual % placeholders to time.strftime(). unicode string and passes individual % placeholders to time.strftime().

View File

@ -256,7 +256,7 @@ class CustomMediaItem(MediaManagerItem):
and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme, and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme,
CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:])) CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:]))
if custom: if custom:
Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False)) Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item.unique_identifier, False))
else: else:
if self.add_custom_from_service: if self.add_custom_from_service:
self.create_from_service_item(item) self.create_from_service_item(item)
@ -286,7 +286,7 @@ class CustomMediaItem(MediaManagerItem):
self.plugin.manager.save_object(custom) self.plugin.manager.save_object(custom)
self.onSearchTextButtonClicked() self.onSearchTextButtonClicked()
if item.name.lower() == u'custom': if item.name.lower() == u'custom':
Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False)) Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item.unique_identifier, False))
def onClearTextButtonClick(self): def onClearTextButtonClick(self):
""" """

View File

@ -252,17 +252,17 @@ class HttpConnection(object):
service_items = [] service_items = []
service_manager = self.parent.plugin.serviceManager service_manager = self.parent.plugin.serviceManager
if self.parent.current_item: if self.parent.current_item:
cur_uuid = self.parent.current_item._uuid current_unique_identifier = self.parent.current_item.unique_identifier
else: else:
cur_uuid = None current_unique_identifier = None
for item in service_manager.serviceItems: for item in service_manager.serviceItems:
service_item = item[u'service_item'] service_item = item[u'service_item']
service_items.append({ service_items.append({
u'id': unicode(service_item._uuid), u'id': unicode(service_item.unique_identifier),
u'title': unicode(service_item.get_display_title()), u'title': unicode(service_item.get_display_title()),
u'plugin': unicode(service_item.name), u'plugin': unicode(service_item.name),
u'notes': unicode(service_item.notes), u'notes': unicode(service_item.notes),
u'selected': (service_item._uuid == cur_uuid) u'selected': (service_item.unique_identifier == current_unique_identifier)
}) })
return service_items return service_items
@ -386,9 +386,9 @@ class HttpConnection(object):
Poll OpenLP to determine the current slide number and item name. Poll OpenLP to determine the current slide number and item name.
""" """
result = { result = {
u'service': self.parent.plugin.serviceManager.serviceId, u'service': self.parent.plugin.serviceManager.service_id,
u'slide': self.parent.current_slide or 0, u'slide': self.parent.current_slide or 0,
u'item': self.parent.current_item._uuid if self.parent.current_item else u'', u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'',
u'twelve':Settings().value(u'remotes/twelve hour'), u'twelve':Settings().value(u'remotes/twelve hour'),
u'blank': self.parent.plugin.liveController.blankScreen.isChecked(), u'blank': self.parent.plugin.liveController.blankScreen.isChecked(),
u'theme': self.parent.plugin.liveController.themeScreen.isChecked(), u'theme': self.parent.plugin.liveController.themeScreen.isChecked(),
@ -459,7 +459,7 @@ class HttpConnection(object):
data.append(item) data.append(item)
json_data = {u'results': {u'slides': data}} json_data = {u'results': {u'slides': data}}
if current_item: if current_item:
json_data[u'results'][u'item'] = self.parent.current_item._uuid json_data[u'results'][u'item'] = self.parent.current_item.unique_identifier
else: else:
if self.url_params and self.url_params.get(u'data'): if self.url_params and self.url_params.get(u'data'):
try: try:

View File

@ -537,7 +537,7 @@ class SongMediaItem(MediaManagerItem):
temporary = True temporary = True
# Update service with correct song id. # Update service with correct song id.
if editId: if editId:
Receiver.send_message(u'service_item_update%s:%s:%s' % (editId, item._uuid, temporary)) Receiver.send_message(u'service_item_update%s:%s:%s' % (editId, item.unique_identifier, temporary))
def search(self, string, showError): def search(self, string, showError):
""" """

View File

@ -2,11 +2,14 @@
Package to test the openlp.core.lib package. Package to test the openlp.core.lib package.
""" """
import os import os
import cPickle
from unittest import TestCase from unittest import TestCase
from mock import MagicMock from mock import MagicMock
from openlp.core.lib import ServiceItem, Registry from openlp.core.lib import ServiceItem, Registry
VERSE = u'The Lord said to {r}Noah{/r}: \n'\ VERSE = u'The Lord said to {r}Noah{/r}: \n'\
'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\ 'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\
'The Lord said to {g}Noah{/g}:\n'\ 'The Lord said to {g}Noah{/g}:\n'\
@ -18,6 +21,7 @@ FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources'))
class TestServiceItem(TestCase): class TestServiceItem(TestCase):
def setUp(self): def setUp(self):
@ -33,7 +37,7 @@ class TestServiceItem(TestCase):
def serviceitem_basic_test(self): def serviceitem_basic_test(self):
""" """
Test the Service Item basic test Test the Service Item - basic test
""" """
# GIVEN: A new service item # GIVEN: A new service item
@ -46,7 +50,7 @@ class TestServiceItem(TestCase):
def serviceitem_add_text_test(self): def serviceitem_add_text_test(self):
""" """
Test the Service Item add text test Test the Service Item - add text test
""" """
# GIVEN: A new service item # GIVEN: A new service item
service_item = ServiceItem(None) service_item = ServiceItem(None)
@ -69,7 +73,7 @@ class TestServiceItem(TestCase):
def serviceitem_add_image_test(self): def serviceitem_add_image_test(self):
""" """
Test the Service Item add image test Test the Service Item - add image test
""" """
# GIVEN: A new service item and a mocked renderer # GIVEN: A new service item and a mocked renderer
service_item = ServiceItem(None) service_item = ServiceItem(None)
@ -124,7 +128,7 @@ class TestServiceItem(TestCase):
def serviceitem_add_command_test(self): def serviceitem_add_command_test(self):
""" """
Test the Service Item add command test Test the Service Item - add command test
""" """
# GIVEN: A new service item and a mocked renderer # GIVEN: A new service item and a mocked renderer
service_item = ServiceItem(None) service_item = ServiceItem(None)
@ -156,10 +160,60 @@ class TestServiceItem(TestCase):
service_item.validate_item([u'jpg']) service_item.validate_item([u'jpg'])
# THEN the service item should be valid # THEN the service item should be valid
assert service_item.is_valid is True, u'The service item is valid' assert service_item.is_valid is True, u'The service item should be valid'
# WHEN validating a service item with a different suffix # WHEN validating a service item with a different suffix
service_item.validate_item([u'png']) service_item.validate_item([u'png'])
# THEN the service item should not be valid # THEN the service item should not be valid
assert service_item.is_valid is False, u'The service item is not valid' assert service_item.is_valid is False, u'The service item is not valid'
def serviceitem_load_custom_from_service_test(self):
"""
Test the Service Item - adding a custom slide from a saved service
"""
# GIVEN: A new service item and a mocked add icon function
service_item = ServiceItem(None)
mocked_add_icon = MagicMock()
service_item.add_icon = mocked_add_icon
mocked_renderer = MagicMock()
service_item.renderer = mocked_renderer
# WHEN: adding a custom from a saved Service
line = self.convert_file_service_item(u'serviceitem_custom1.osd')
service_item.set_from_service(line)
# THEN: We should get back a valid service item
assert service_item.is_valid is True, u'The new service item should be valid'
assert len(service_item._display_frames) == 0, u'The service item has no display frames'
assert len(service_item.capabilities) == 5, u'There are 5 default custom item capabilities'
service_item.render(True)
assert (service_item.get_display_title()) == u'Test Custom', u'The custom title should be correct'
def serviceitem_load_image_from_service_test(self):
"""
Test the Service Item - adding an image from a saved service
"""
# GIVEN: A new service item and a mocked add icon function
service_item = ServiceItem(None)
mocked_add_icon = MagicMock()
service_item.add_icon = mocked_add_icon
mocked_renderer = MagicMock()
service_item.renderer = mocked_renderer
# WHEN: adding a custom from a saved Service
# THEN: We should get back a valid service item
assert service_item.is_valid is True, u'The new service item should be valid'
def convert_file_service_item(self, name):
service_file = os.path.join(TESTPATH, name)
try:
open_file = open(service_file, u'r')
items = cPickle.load(open_file)
first_line = items[0]
except:
first_line = u''
return first_line

View File

@ -1,13 +1,12 @@
""" """
Package to test the openlp.core.ui package. Package to test the openlp.core.ui package.
""" """
import sys import sys
from unittest import TestCase from unittest import TestCase
from mock import MagicMock from mock import MagicMock, patch
from openlp.core.ui import starttimeform from openlp.core.ui import starttimeform
from PyQt4 import QtCore, QtGui, QtTest from PyQt4 import QtGui, QtTest
class TestStartTimeDialog(TestCase): class TestStartTimeDialog(TestCase):
@ -48,10 +47,19 @@ class TestStartTimeDialog(TestCase):
""" """
Test StartTimeDialog display initialisation Test StartTimeDialog display initialisation
""" """
#GIVEN: A service item with with time # GIVEN: A service item with with time
mocked_serviceitem = MagicMock() mocked_serviceitem = MagicMock()
mocked_serviceitem.start_time = 61 mocked_serviceitem.start_time = 61
mocked_serviceitem.end_time = 3701 mocked_serviceitem.end_time = 3701
# WHEN displaying the UI and pressing enter
self.form.item = mocked_serviceitem self.form.item = mocked_serviceitem
#self.form.exec_() with patch(u'openlp.core.lib.QtGui.QDialog') as MockedQtGuiQDialog:
MockedQtGuiQDialog.return_value = True
#does not work yet
#self.form.exec_()
# THEN the following values are returned
self.assertEqual(self.form.hourSpinBox.value(), 0)
self.assertEqual(self.form.minuteSpinBox.value(), 0)
self.assertEqual(self.form.secondSpinBox.value(), 0)

View File

@ -0,0 +1,96 @@
(lp1
(dp2
Vserviceitem
p3
(dp4
Vheader
p5
(dp6
Vfooter
p7
(lp8
VTest Custom Credits
p9
asVaudit
p10
V
sVsearch
p11
V
sVwill_auto_start
p12
I00
sVname
p13
Vcustom
p14
sVplugin
p15
g14
sVdata
p16
V
sVnotes
p17
V
sVtitle
p18
VTest Custom
p19
sVfrom_plugin
p20
I00
sVcapabilities
p21
(lp22
I2
aI1
aI5
aI13
aI8
asVmedia_length
p23
I0
sVtheme_overwritten
p24
I00
sVtheme
p25
NsVxml_version
p26
NsVend_time
p27
I0
sVbackground_audio
p28
(lp29
sVtype
p30
I1
sVstart_time
p31
I0
sVicon
p32
V:/plugins/plugin_custom.png
p33
ssg16
(lp34
(dp35
VverseTag
p36
NsVraw_slide
p37
VSlide 1
p38
sVtitle
p39
g38
sa(dp40
g36
Nsg37
VSlide 2
p41
sg39
g41
sassa.

View File

@ -0,0 +1,79 @@
(lp1
(dp2
Vserviceitem
p3
(dp4
Vheader
p5
(dp6
Vfooter
p7
(lp8
sVaudit
p9
V
sVsearch
p10
V
sVwill_auto_start
p11
I00
sVname
p12
Vimages
p13
sVplugin
p14
g13
sVdata
p15
V
sVnotes
p16
V
sVtitle
p17
VImages
p18
sVfrom_plugin
p19
I00
sVcapabilities
p20
(lp21
I3
aI1
aI5
aI6
asVmedia_length
p22
I0
sVtheme_overwritten
p23
I00
sVtheme
p24
I-1
sVxml_version
p25
NsVend_time
p26
I0
sVbackground_audio
p27
(lp28
sVtype
p29
I2
sVstart_time
p30
I0
sVicon
p31
V:/plugins/plugin_images.png
p32
ssg15
(lp33
VIMG_7453.JPG
p34
assa.