openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #18593
[Merge] lp:~trb143/openlp/media into lp:openlp
Tim Bentley has proposed merging lp:~trb143/openlp/media into lp:openlp.
Requested reviews:
Jonathan Corwin (j-corwin)
Related bugs:
Bug #885150 in OpenLP: "Need non self contained service files"
https://bugs.launchpad.net/openlp/+bug/885150
Bug #899714 in OpenLP: "Play/Pause button should be merged"
https://bugs.launchpad.net/openlp/+bug/899714
Bug #927829 in OpenLP: "media backends should provide some information about themselves in the settings"
https://bugs.launchpad.net/openlp/+bug/927829
Bug #952821 in OpenLP: "Unable to play videos from web"
https://bugs.launchpad.net/openlp/+bug/952821
Bug #958198 in OpenLP: "Replacing live background with a video shows theme behind"
https://bugs.launchpad.net/openlp/+bug/958198
Bug #999618 in OpenLP: "Video position slider jumps to part way through video"
https://bugs.launchpad.net/openlp/+bug/999618
Bug #1022053 in OpenLP: "Previewing media item interferes with live media item"
https://bugs.launchpad.net/openlp/+bug/1022053
Bug #1063211 in OpenLP: "Media and Presentation Plugins do not update the service suffix lists if players are added or removed without a restart"
https://bugs.launchpad.net/openlp/+bug/1063211
For more details, see:
https://code.launchpad.net/~trb143/openlp/media/+merge/141822
Clean up some fallout from the reformatting updates
Add a custom media slider with hover goodies and move to click
Add some new tests for service item.
Re-factor and firm up the service item validation code in service manager.
--
https://code.launchpad.net/~trb143/openlp/media/+merge/141822
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py 2012-12-29 20:56:56 +0000
+++ openlp/core/lib/serviceitem.py 2013-01-03 21:30:31 +0000
@@ -182,6 +182,7 @@
self.theme_overwritten = False
self.temporary_edit = False
self.will_auto_start = False
+ self.has_original_files = True
self._new_item()
def _new_item(self):
@@ -190,6 +191,7 @@
service items to see if they are the same.
"""
self._uuid = unicode(uuid.uuid1())
+ self.validate_item()
def add_capability(self, capability):
"""
@@ -395,6 +397,7 @@
self.end_time = header.get(u'end_time', 0)
self.media_length = header.get(u'media_length', 0)
self.will_auto_start = header.get(u'will_auto_start', False)
+ self.has_original_files = True
if u'background_audio' in header:
self.background_audio = []
for filename in header[u'background_audio']:
@@ -406,6 +409,7 @@
self._raw_frames.append(slide)
elif self.service_item_type == ServiceItemType.Image:
if path:
+ self.has_original_files = False
for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image)
self.add_from_image(filename, text_image)
@@ -415,6 +419,7 @@
elif self.service_item_type == ServiceItemType.Command:
for text_image in serviceitem[u'serviceitem'][u'data']:
if path:
+ self.has_original_files = False
self.add_from_command(path, text_image[u'title'], text_image[u'image'])
else:
self.add_from_command(text_image[u'path'], text_image[u'title'], text_image[u'image'])
@@ -605,8 +610,25 @@
if self.get_frame_path(frame=frame) in invalid_paths:
self.remove_frame(frame)
- def validate(self):
- """
- Validates this service item
- """
- return bool(self._raw_frames)
+ def missing_frames(self):
+ """
+ Returns if there are any frames in the service item
+ """
+ return not bool(self._raw_frames)
+
+ def validate_item(self, suffix_list=None):
+ """
+ Validates a service item to make sure it is valid
+ """
+ self.is_valid = True
+ for frame in self._raw_frames:
+ if self.is_image() and not os.path.exists((frame[u'path'])):
+ self.is_valid = False
+ elif self.is_command():
+ file = os.path.join(frame[u'path'],frame[u'title'])
+ if not os.path.exists(file):
+ self.is_valid = False
+ if suffix_list and not self.is_text():
+ type = frame[u'title'].split(u'.')[-1]
+ if type.lower() not in suffix_list:
+ self.is_valid = False
=== modified file 'openlp/core/ui/exceptiondialog.py'
--- openlp/core/ui/exceptiondialog.py 2012-12-29 20:56:56 +0000
+++ openlp/core/ui/exceptiondialog.py 2013-01-03 21:30:31 +0000
@@ -29,7 +29,7 @@
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import translate, build_icon
+from openlp.core.lib import translate
from openlp.core.lib.ui import create_button, create_button_box
class Ui_ExceptionDialog(object):
=== modified file 'openlp/core/ui/media/mediacontroller.py'
--- openlp/core/ui/media/mediacontroller.py 2012-12-29 20:56:56 +0000
+++ openlp/core/ui/media/mediacontroller.py 2013-01-03 21:30:31 +0000
@@ -29,19 +29,49 @@
import logging
import os
-import sys
+import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings
from openlp.core.lib.ui import UiStrings, critical_error_message_box
-from openlp.core.ui.media import MediaState, MediaInfo, MediaType, \
- get_media_players, set_media_players
+from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
from openlp.core.ui.media.mediaplayer import MediaPlayer
from openlp.core.utils import AppLocation
from openlp.core.ui import DisplayControllerType
log = logging.getLogger(__name__)
+class MediaSlider(QtGui.QSlider):
+ """
+ Allows the mouse events of a slider to be overridden and extra functionality added
+ """
+ def __init__(self, direction, manager, controller, parent=None):
+ QtGui.QSlider.__init__(self, direction)
+ self.manager = manager
+ self.controller = controller
+
+ def mouseMoveEvent(self, event):
+ """
+ Override event to allow hover time to be displayed.
+ """
+ timevalue = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
+ self.setToolTip(u'%s' % datetime.timedelta(seconds=int(timevalue/1000)))
+ QtGui.QSlider.mouseMoveEvent(self, event)
+
+ def mousePressEvent(self, event):
+ """
+ Mouse Press event no new functionality
+ """
+ QtGui.QSlider.mousePressEvent(self, event)
+
+ def mouseReleaseEvent(self, event):
+ """
+ Set the slider position when the mouse is clicked and released on the slider.
+ """
+ self.setValue(QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width()))
+ QtGui.QSlider.mouseReleaseEvent(self, event)
+
+
class MediaController(object):
"""
The implementation of the Media Controller. The Media Controller adds an own
@@ -69,8 +99,8 @@
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPlay'), self.media_play_msg)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPause'), self.media_pause_msg)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackStop'), self.media_stop_msg)
- QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'seekSlider'), self.media_seek)
- QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'volumeSlider'), self.media_volume)
+ QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'seekSlider'), self.media_seek_msg)
+ QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'volumeSlider'), self.media_volume_msg)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_hide'), self.media_hide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_blank'), self.media_blank)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_unblank'), self.media_unblank)
@@ -241,9 +271,10 @@
icon=u':/slides/media_playback_stop.png',
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.sendToPlugins)
# Build the seekSlider.
- controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
+ controller.seekSlider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
controller.seekSlider.setMaximum(1000)
- controller.seekSlider.setTracking(False)
+ controller.seekSlider.setTracking(True)
+ controller.seekSlider.setMouseTracking(True)
controller.seekSlider.setToolTip(translate('OpenLP.SlideController', 'Video position.'))
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
controller.seekSlider.setObjectName(u'seekSlider')
@@ -344,12 +375,8 @@
# stop running videos
self.media_reset(controller)
controller.media_info = MediaInfo()
- if videoBehindText:
- controller.media_info.volume = 0
- controller.media_info.is_background = True
- else:
- controller.media_info.volume = controller.volumeSlider.value()
- controller.media_info.is_background = False
+ controller.media_info.volume = controller.volumeSlider.value()
+ controller.media_info.is_background = videoBehindText
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
display = self._define_display(controller)
if controller.isLive:
@@ -361,7 +388,7 @@
controller.media_info.start_time = 0
controller.media_info.end_time = 0
else:
- controller.media_info.start_time = display.serviceItem.start_time
+ controller.media_info.start_time = serviceItem.start_time
controller.media_info.end_time = serviceItem.end_time
elif controller.previewDisplay:
isValid = self._check_file_type(controller, display, serviceItem)
@@ -483,9 +510,17 @@
The controller to be played
"""
log.debug(u'media_play')
+ controller.seekSlider.blockSignals(True)
+ controller.volumeSlider.blockSignals(True)
display = self._define_display(controller)
if not self.currentMediaPlayer[controller.controllerType].play(display):
+ controller.seekSlider.blockSignals(False)
+ controller.volumeSlider.blockSignals(False)
return False
+ if controller.media_info.is_background:
+ self.media_volume(controller, 0)
+ else:
+ self.media_volume(controller, controller.media_info.volume)
if status:
display.frame.evaluateJavaScript(u'show_blank("desktop");')
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
@@ -503,6 +538,8 @@
# Start Timer for ui updates
if not self.timer.isActive():
self.timer.start()
+ controller.seekSlider.blockSignals(False)
+ controller.volumeSlider.blockSignals(False)
return True
def media_pause_msg(self, msg):
@@ -557,7 +594,7 @@
controller.mediabar.actions[u'playbackStop'].setVisible(False)
controller.mediabar.actions[u'playbackPause'].setVisible(False)
- def media_volume(self, msg):
+ def media_volume_msg(self, msg):
"""
Changes the volume of a running video
@@ -566,11 +603,21 @@
"""
controller = msg[0]
vol = msg[1][0]
- log.debug(u'media_volume %d' % vol)
+ self.media_volume(controller, vol)
+
+ def media_volume(self, controller, volume):
+ """
+ Changes the volume of a running video
+
+ ``msg``
+ First element is the controller which should be used
+ """
+ log.debug(u'media_volume %d' % volume)
display = self._define_display(controller)
- self.currentMediaPlayer[controller.controllerType].volume(display, vol)
+ self.currentMediaPlayer[controller.controllerType].volume(display, volume)
+ controller.volumeSlider.setValue(volume)
- def media_seek(self, msg):
+ def media_seek_msg(self, msg):
"""
Responds to the request to change the seek Slider of a loaded video
@@ -581,6 +628,17 @@
log.debug(u'media_seek')
controller = msg[0]
seekVal = msg[1][0]
+ self.media_seek(controller, seekVal)
+
+ def media_seek(self, controller, seekVal):
+ """
+ Responds to the request to change the seek Slider of a loaded video
+
+ ``msg``
+ First element is the controller which should be used
+ Second element is a list with the seek Value as first element
+ """
+ log.debug(u'media_seek')
display = self._define_display(controller)
self.currentMediaPlayer[controller.controllerType].seek(display, seekVal)
@@ -610,7 +668,8 @@
return
controller = self.mainWindow.liveController
display = self._define_display(controller)
- if self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
+ if controller.controllerType in self.currentMediaPlayer and \
+ self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
self.currentMediaPlayer[controller.controllerType].pause(display)
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
=== modified file 'openlp/core/ui/media/phononplayer.py'
--- openlp/core/ui/media/phononplayer.py 2012-12-29 20:56:56 +0000
+++ openlp/core/ui/media/phononplayer.py 2013-01-03 21:30:31 +0000
@@ -31,7 +31,7 @@
import mimetypes
from datetime import datetime
-from PyQt4 import QtCore, QtGui
+from PyQt4 import QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, translate, Settings
=== modified file 'openlp/core/ui/media/vlcplayer.py'
--- openlp/core/ui/media/vlcplayer.py 2012-12-29 20:56:56 +0000
+++ openlp/core/ui/media/vlcplayer.py 2013-01-03 21:30:31 +0000
@@ -33,7 +33,7 @@
import os
import sys
-from PyQt4 import QtCore, QtGui
+from PyQt4 import QtGui
from openlp.core.lib import Receiver, translate, Settings
from openlp.core.ui.media import MediaState
@@ -188,6 +188,7 @@
display.vlcMediaPlayer.play()
if not self.media_state_wait(display, vlc.State.Playing):
return False
+ self.volume(display, controller.media_info.volume)
if start_time > 0:
self.seek(display, controller.media_info.start_time * 1000)
controller.media_info.length = int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py 2013-01-02 21:31:11 +0000
+++ openlp/core/ui/servicemanager.py 2013-01-03 21:30:31 +0000
@@ -114,6 +114,7 @@
# is a new service and has not been saved
self._modified = False
self._fileName = u''
+ self.service_has_all_original_files = True
self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
self.startTimeForm = StartTimeForm(self.mainwindow)
@@ -458,7 +459,7 @@
for item in list(self.serviceItems):
self.mainwindow.incrementProgressBar()
item[u'service_item'].remove_invalid_frames(missing_list)
- if not item[u'service_item'].validate():
+ if item[u'service_item'].missing_frames():
self.serviceItems.remove(item)
else:
service_item = item[u'service_item'].get_service_repr(self._saveLite)
@@ -693,7 +694,7 @@
serviceItem.set_from_service(item)
else:
serviceItem.set_from_service(item, self.servicePath)
- self.validateItem(serviceItem)
+ serviceItem.validate_item(self.suffixes)
self.load_item_uuid = 0
if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem)
@@ -1032,9 +1033,12 @@
"""
# Correct order of items in array
count = 1
+ self.service_has_all_original_files = True
for item in self.serviceItems:
item[u'order'] = count
count += 1
+ if not item[u'service_item'].has_original_files:
+ self.service_has_all_original_files = False
# Repaint the screen
self.serviceManagerList.clear()
for itemcount, item in enumerate(self.serviceItems):
@@ -1093,18 +1097,6 @@
self.serviceManagerList.setCurrentItem(treewidgetitem)
treewidgetitem.setExpanded(item[u'expanded'])
- def validateItem(self, serviceItem):
- """
- Validates the service item and if the suffix matches an accepted
- one it allows the item to be displayed.
- """
- #@todo check file items exist
- if serviceItem.is_command():
- type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
- if type.lower() not in self.suffixes:
- serviceItem.is_valid = False
- #@todo check file items exist
-
def cleanUp(self):
"""
Empties the servicePath of temporary files on system exit.
@@ -1144,7 +1136,7 @@
Receiver.send_message(u'cursor_busy')
log.debug(u'regenerateServiceItems')
# force reset of renderer as theme data has changed
- self.mainwindow.renderer.themedata = None
+ self.service_has_all_original_files = True
if self.serviceItems:
for item in self.serviceItems:
item[u'selected'] = False
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2012-12-29 20:56:56 +0000
+++ openlp/core/ui/slidecontroller.py 2013-01-03 21:30:31 +0000
@@ -933,8 +933,7 @@
else:
if not self.serviceItem.is_command():
Receiver.send_message(u'live_display_show')
- Receiver.send_message(u'%s_unblank' % self.serviceItem.name.lower(),
- [self.serviceItem, self.isLive])
+ Receiver.send_message(u'%s_unblank' % self.serviceItem.name.lower(), [self.serviceItem, self.isLive])
else:
if hide_mode:
Receiver.send_message(u'live_display_hide', hide_mode)
@@ -949,13 +948,11 @@
if self.serviceItem is not None:
if hide:
Receiver.send_message(u'live_display_hide', HideMode.Screen)
- Receiver.send_message(u'%s_hide' % self.serviceItem.name.lower(),
- [self.serviceItem, self.isLive])
+ Receiver.send_message(u'%s_hide' % self.serviceItem.name.lower(), [self.serviceItem, self.isLive])
else:
if not self.serviceItem.is_command():
Receiver.send_message(u'live_display_show')
- Receiver.send_message(u'%s_unblank' % self.serviceItem.name.lower(),
- [self.serviceItem, self.isLive])
+ Receiver.send_message(u'%s_unblank' % self.serviceItem.name.lower(), [self.serviceItem, self.isLive])
else:
if hide:
Receiver.send_message(u'live_display_hide', HideMode.Screen)
=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py 2012-12-29 20:56:56 +0000
+++ openlp/plugins/media/lib/mediaitem.py 2013-01-03 21:30:31 +0000
@@ -33,11 +33,11 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, SettingsManager, translate, \
- check_item_selected, Receiver, MediaType, ServiceItem, build_html, ServiceItemContext, Settings
+ check_item_selected, Receiver, MediaType, ServiceItem, ServiceItemContext, Settings, check_directory_exists
from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.ui import DisplayController, Display, DisplayControllerType
from openlp.core.ui.media import get_media_players, set_media_players
-from openlp.core.utils import locale_compare
+from openlp.core.utils import AppLocation, locale_compare
log = logging.getLogger(__name__)
@@ -130,8 +130,7 @@
"""
Called to reset the Live background with the media selected,
"""
- self.plugin.liveController.mediaController.media_reset(
- self.plugin.liveController)
+ self.plugin.liveController.mediaController.media_reset(self.plugin.liveController)
self.resetAction.setVisible(False)
def videobackgroundReplaced(self):
@@ -145,8 +144,7 @@
Called to replace Live background with the media selected.
"""
if check_item_selected(self.listView,
- translate('MediaPlugin.MediaItem',
- 'You must select a media file to replace the background with.')):
+ translate('MediaPlugin.MediaItem', 'You must select a media file to replace the background with.')):
item = self.listView.currentItem()
filename = item.data(QtCore.Qt.UserRole)
if os.path.exists(filename):
@@ -166,8 +164,8 @@
translate('MediaPlugin.MediaItem',
'There was a problem replacing your background, the media file "%s" no longer exists.') % filename)
- def generateSlideData(self, service_item, item=None, xmlVersion=False,
- remote=False, context=ServiceItemContext.Live):
+ def generateSlideData(self, service_item, item=None, xmlVersion=False, remote=False,
+ context=ServiceItemContext.Live):
if item is None:
item = self.listView.currentItem()
if item is None:
@@ -201,6 +199,8 @@
def initialise(self):
self.listView.clear()
self.listView.setIconSize(QtCore.QSize(88, 50))
+ self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settingsSection), u'thumbnails')
+ check_directory_exists(self.servicePath)
self.loadList(SettingsManager.load_list(self.settingsSection, u'media'))
self.populateDisplayTypes()
@@ -247,14 +247,13 @@
"""
Remove a media item from the list.
"""
- if check_item_selected(self.listView, translate('MediaPlugin.MediaItem',
- 'You must select a media file to delete.')):
+ if check_item_selected(self.listView,
+ translate('MediaPlugin.MediaItem', 'You must select a media file to delete.')):
row_list = [item.row() for item in self.listView.selectedIndexes()]
row_list.sort(reverse=True)
for row in row_list:
self.listView.takeItem(row)
- SettingsManager.set_list(self.settingsSection,
- u'media', self.getFileList())
+ SettingsManager.set_list(self.settingsSection, u'media', self.getFileList())
def loadList(self, media):
# Sort the media by its filename considering language specific
=== added directory 'tests/functional/openlp_core_lib/resources'
=== added file 'tests/functional/openlp_core_lib/resources/church.jpg'
Binary files tests/functional/openlp_core_lib/resources/church.jpg 1970-01-01 00:00:00 +0000 and tests/functional/openlp_core_lib/resources/church.jpg 2013-01-03 21:30:31 +0000 differ
=== added file 'tests/functional/openlp_core_lib/test_serviceitem.py'
--- tests/functional/openlp_core_lib/test_serviceitem.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_lib/test_serviceitem.py 2013-01-03 21:30:31 +0000
@@ -0,0 +1,158 @@
+"""
+ Package to test the openlp.core.lib package.
+"""
+from unittest import TestCase
+from mock import MagicMock
+from openlp.core.lib import ServiceItem
+
+VERSE = u'The Lord said to {r}Noah{/r}: \n'\
+ 'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\
+ 'The Lord said to {g}Noah{/g}:\n'\
+ 'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n'\
+ 'Get those children out of the muddy, muddy \n'\
+ '{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}'\
+ 'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
+FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
+
+class TestServiceItem(TestCase):
+
+ def serviceitem_basic_test(self):
+ """
+ Test the Service Item basic test
+ """
+ #GIVEN: A new service item
+
+ # WHEN:A service item is created (without a plugin)
+ service_item = ServiceItem(None)
+
+ # THEN: We should get back a valid service item
+ print service_item
+ print dir(service_item)
+ assert service_item.is_valid is True, u'A valid Service Item'
+ assert service_item.missing_frames() is True, u'No frames loaded yet'
+
+ def serviceitem_add_text_test(self):
+ """
+ Test the Service Item add text test
+ """
+ #GIVEN: A new service item
+ service_item = ServiceItem(None)
+
+ # WHEN: adding text to a service item
+ service_item.add_from_text(VERSE)
+ service_item.raw_footer = FOOTER
+
+ # THEN: We should get back a valid service item
+ assert service_item.is_valid is True, u'A valid Service Item'
+ assert service_item.missing_frames() is False, u'check frames loaded '
+
+ #GIVEN: A service item with text
+ mocked_renderer = MagicMock()
+ mocked_renderer.format_slide.return_value = [VERSE]
+ service_item.renderer = mocked_renderer
+
+ #WHEN: Render called
+ assert len(service_item._display_frames) is 0, u'A blank Service Item'
+ service_item.render(True)
+
+ #THEN: We should should have a page of output.
+ assert len(service_item._display_frames) is 1, u'A valid rendered Service Item has display frames'
+ assert service_item.get_rendered_frame(0) == VERSE.split(u'\n')[0], u'A valid render'
+
+ def serviceitem_add_image_test(self):
+ """
+ Test the Service Item add image test
+ """
+ #GIVEN: A new service item and a mocked renderer
+ service_item = ServiceItem(None)
+ service_item.name = u'test'
+ mocked_renderer = MagicMock()
+ service_item.renderer = mocked_renderer
+
+ # WHEN: adding image to a service item
+ service_item.add_from_image(u'resources/church.jpg', u'Image Title')
+
+ # THEN: We should get back a valid service item
+ assert service_item.is_valid is True, u'A valid Service Item'
+ assert len(service_item._display_frames) is 0, u'A blank Service Item'
+
+ #THEN: We should should have a page of output.
+ assert len(service_item._raw_frames) is 1, u'A valid rendered Service Item has display frames'
+ assert service_item.get_rendered_frame(0) == u'resources/church.jpg'
+
+ # WHEN: adding a second image to a service item
+ service_item.add_from_image(u'resources/church.jpg', u'Image1 Title')
+
+ #THEN: We should should have an increased page of output.
+ assert len(service_item._raw_frames) is 2, u'A valid rendered Service Item has display frames'
+ assert service_item.get_rendered_frame(0) == u'resources/church.jpg'
+ assert service_item.get_rendered_frame(0) == service_item.get_rendered_frame(1)
+
+ #When requesting a saved service item
+ service = service_item.get_service_repr(True)
+
+ #THEN: We should should have two parts of the service.
+ assert len(service) is 2, u'A saved service has two parts'
+ assert service[u'header'][u'name'] == u'test' , u'A test plugin'
+ assert service[u'data'][0][u'title'] == u'Image Title' , u'The first title name '
+ assert service[u'data'][0][u'path'] == u'resources/church.jpg' , u'The first image name'
+ assert service[u'data'][0][u'title'] != service[u'data'][1][u'title'], u'The titles should not match'
+ assert service[u'data'][0][u'path'] == service[u'data'][1][u'path'], u'The files should match'
+
+ #When validating a service item
+ service_item.validate_item([u'jpg'])
+
+ #Then the service item should be valid
+ assert service_item.is_valid is True, u'The service item is valid'
+
+ # WHEN: adding a second image to a service item
+ service_item.add_from_image(u'resources/church1.jpg', u'Image1 Title')
+
+ #When validating a service item
+ service_item.validate_item([u'jpg'])
+
+ #Then the service item should be valid
+ assert service_item.is_valid is False, u'The service item is not valid'
+
+ def serviceitem_add_command_test(self):
+ """
+ Test the Service Item add command test
+ """
+ #GIVEN: A new service item and a mocked renderer
+ service_item = ServiceItem(None)
+ service_item.name = u'test'
+ mocked_renderer = MagicMock()
+ service_item.renderer = mocked_renderer
+
+ # WHEN: adding image to a service item
+ service_item.add_from_command(u'resources', u'church.jpg', u'resources/church.jpg')
+
+ # THEN: We should get back a valid service item
+ assert service_item.is_valid is True, u'A valid Service Item'
+ assert len(service_item._display_frames) is 0, u'A blank Service Item'
+
+ #THEN: We should should have a page of output.
+ assert len(service_item._raw_frames) is 1, u'A valid rendered Service Item has display frames'
+ assert service_item.get_rendered_frame(0) == u'resources/church.jpg'
+
+ #When requesting a saved service item
+ service = service_item.get_service_repr(True)
+
+ #THEN: We should should have two parts of the service.
+ assert len(service) is 2, u'A saved service has two parts'
+ assert service[u'header'][u'name'] == u'test' , u'A test plugin'
+ assert service[u'data'][0][u'title'] == u'church.jpg' , u'The first title name '
+ assert service[u'data'][0][u'path'] == u'resources' , u'The first image name'
+ assert service[u'data'][0][u'image'] == u'resources/church.jpg' , u'The first image name'
+
+ #When validating a service item
+ service_item.validate_item([u'jpg'])
+
+ #Then the service item should be valid
+ assert service_item.is_valid is True, u'The service item is valid'
+
+ #When validating a service item with a different suffix
+ service_item.validate_item([u'png'])
+
+ #Then the service item should not be valid
+ assert service_item.is_valid is False, u'The service item is not valid'
\ No newline at end of file
=== added directory 'tests/functional/openlp_core_ui'
=== added file 'tests/functional/openlp_core_ui/starttimedialog.py'
--- tests/functional/openlp_core_ui/starttimedialog.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_ui/starttimedialog.py 2013-01-03 21:30:31 +0000
@@ -0,0 +1,48 @@
+"""
+ Package to test the openlp.core.ui package.
+"""
+import sys
+
+from unittest import TestCase
+from mock import MagicMock
+from openlp.core.ui import starttimeform
+from PyQt4 import QtCore, QtGui, QtTest
+
+class TestStartTimeDialog(TestCase):
+
+ def setUp(self):
+ """
+ Create the UI
+ """
+ self.app = QtGui.QApplication(sys.argv)
+ self.window = QtGui.QMainWindow()
+ self.form = starttimeform.StartTimeForm(self.window)
+
+ def ui_defaults_test(self):
+ """
+ Test StartTimeDialog defaults
+ """
+ self.assertEqual(self.form.hourSpinBox.minimum(), 0)
+ self.assertEqual(self.form.hourSpinBox.maximum(), 4)
+ self.assertEqual(self.form.minuteSpinBox.minimum(), 0)
+ self.assertEqual(self.form.minuteSpinBox.maximum(), 59)
+ self.assertEqual(self.form.secondSpinBox.minimum(), 0)
+ self.assertEqual(self.form.secondSpinBox.maximum(), 59)
+ self.assertEqual(self.form.hourFinishSpinBox.minimum(), 0)
+ self.assertEqual(self.form.hourFinishSpinBox.maximum(), 4)
+ self.assertEqual(self.form.minuteFinishSpinBox.minimum(), 0)
+ self.assertEqual(self.form.minuteFinishSpinBox.maximum(), 59)
+ self.assertEqual(self.form.secondFinishSpinBox.minimum(), 0)
+ self.assertEqual(self.form.secondFinishSpinBox.maximum(), 59)
+
+ def time_display_test(self):
+ """
+ Test StartTimeDialog display initialisation
+ """
+ #GIVEN: A service item with with time
+ mocked_serviceitem = MagicMock()
+ mocked_serviceitem.start_time = 61
+ mocked_serviceitem.end_time = 3701
+
+ self.form.item = mocked_serviceitem
+ #self.form.exec_()
\ No newline at end of file
=== added directory 'tests/functional/resources'
=== added file 'tests/functional/resources/church.jpg'
Binary files tests/functional/resources/church.jpg 1970-01-01 00:00:00 +0000 and tests/functional/resources/church.jpg 2013-01-03 21:30:31 +0000 differ
=== modified file 'tests/test_app.py'
--- tests/test_app.py 2012-06-22 14:14:53 +0000
+++ tests/test_app.py 2013-01-03 21:30:31 +0000
@@ -34,4 +34,4 @@
def test_start_app(openlpapp):
assert type(openlpapp) == OpenLP
assert type(openlpapp.mainWindow) == MainWindow
- assert unicode(openlpapp.mainWindow.windowTitle()) == u'OpenLP 2.0'
+ assert unicode(openlpapp.mainWindow.windowTitle()) == u'OpenLP 2.1'
Follow ups