openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #29653
[Merge] lp:~knightrider0xd/openlp/preview-shows-live-fix-1080596 into lp:openlp
Ian Knight has proposed merging lp:~knightrider0xd/openlp/preview-shows-live-fix-1080596 into lp:openlp.
Requested reviews:
Raoul Snyman (raoul-snyman)
Related bugs:
Bug #1080596 in OpenLP: "Presentation preview shows desktop when live shows desktop"
https://bugs.launchpad.net/openlp/+bug/1080596
For more details, see:
https://code.launchpad.net/~knightrider0xd/openlp/preview-shows-live-fix-1080596/+merge/294803
Fixes bug 1080596 where presentations in the preview pane display live view rather than preview of selected slide.
In addition, fixes the aspect ratio & quality of thumbnails by saving them in the correct aspect ratio at a higher resolution, and loading them through the image manager.
New test cases implemented, or existing cases modified to test coverage complete for changes.
lp:~knightrider0xd/openlp/preview-shows-live-fix-1080596 (revision 2652)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1554/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1465/
Failing interface & coverage tests due to issue with unrelated crosswalk import module.
--
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2016-04-23 19:28:52 +0000
+++ openlp/core/lib/__init__.py 2016-05-16 12:42:11 +0000
@@ -55,9 +55,13 @@
``Theme``
This says, that the image is used by a theme.
+
+ ``CommandPlugins``
+ This states that an image is being used by a command plugin.
"""
ImagePlugin = 1
Theme = 2
+ CommandPlugins = 3
class MediaType(object):
@@ -174,10 +178,30 @@
ext = os.path.splitext(thumb_path)[1].lower()
reader = QtGui.QImageReader(image_path)
if size is None:
- ratio = reader.size().width() / reader.size().height()
+ # No size given; use default height of 88
+ if reader.size().isEmpty():
+ ratio = 1
+ else:
+ ratio = reader.size().width() / reader.size().height()
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
- else:
+ elif size.isValid():
+ # Complete size given
reader.setScaledSize(size)
+ else:
+ # Invalid size given
+ if reader.size().isEmpty():
+ ratio = 1
+ else:
+ ratio = reader.size().width() / reader.size().height()
+ if size.width() >= 0:
+ # Valid width; scale height
+ reader.setScaledSize(QtCore.QSize(size.width(), int(size.width() / ratio)))
+ elif size.height() >= 0:
+ # Valid height; scale width
+ reader.setScaledSize(QtCore.QSize(int(ratio * size.height()), size.height()))
+ else:
+ # Invalid; use default height of 88
+ reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
thumb = reader.read()
thumb.save(thumb_path, ext[1:])
if not return_icon:
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py 2016-02-14 17:53:16 +0000
+++ openlp/core/lib/serviceitem.py 2016-05-16 12:42:11 +0000
@@ -334,6 +334,8 @@
file_location_hash, ntpath.basename(image))
self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
'display_title': display_title, 'notes': notes})
+ if self.is_capable(ItemCapabilities.HasThumbnails):
+ self.image_manager.add_image(image, ImageSource.CommandPlugins, '#000000')
self._new_item()
def get_service_repr(self, lite_save):
=== modified file 'openlp/core/ui/lib/listpreviewwidget.py'
--- openlp/core/ui/lib/listpreviewwidget.py 2016-04-22 18:32:59 +0000
+++ openlp/core/ui/lib/listpreviewwidget.py 2016-05-16 12:42:11 +0000
@@ -27,7 +27,7 @@
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import RegistryProperties, Settings
-from openlp.core.lib import ImageSource, ServiceItem
+from openlp.core.lib import ImageSource, ItemCapabilities, ServiceItem
class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
@@ -152,14 +152,16 @@
else:
label.setScaledContents(True)
if self.service_item.is_command():
- pixmap = QtGui.QPixmap(frame['image'])
- pixmap.setDevicePixelRatio(label.devicePixelRatio())
- label.setPixmap(pixmap)
+ if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
+ image = self.image_manager.get_image(frame['image'], ImageSource.CommandPlugins)
+ pixmap = QtGui.QPixmap.fromImage(image)
+ else:
+ pixmap = QtGui.QPixmap(frame['image'])
else:
image = self.image_manager.get_image(frame['path'], ImageSource.ImagePlugin)
pixmap = QtGui.QPixmap.fromImage(image)
- pixmap.setDevicePixelRatio(label.devicePixelRatio())
- label.setPixmap(pixmap)
+ pixmap.setDevicePixelRatio(label.devicePixelRatio())
+ label.setPixmap(pixmap)
slide_height = width // self.screen_ratio
# Setup and validate row height cap if in use.
max_img_row_height = Settings().value('advanced/slide max height')
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2016-04-22 18:32:45 +0000
+++ openlp/core/ui/slidecontroller.py 2016-05-16 12:42:11 +0000
@@ -1135,9 +1135,21 @@
"""
self.log_debug('update_preview %s ' % self.screens.current['primary'])
if self.service_item and self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
- # Grab now, but try again in a couple of seconds if slide change is slow
- QtCore.QTimer.singleShot(500, self.grab_maindisplay)
- QtCore.QTimer.singleShot(2500, self.grab_maindisplay)
+ if self.is_live:
+ # If live, grab screen-cap of main display now
+ QtCore.QTimer.singleShot(500, self.grab_maindisplay)
+ # but take another in a couple of seconds in case slide change is slow
+ QtCore.QTimer.singleShot(2500, self.grab_maindisplay)
+ else:
+ # If not live, use the slide's thumbnail/icon instead
+ image_path = self.service_item.get_rendered_frame(self.selected_row)
+ if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
+ image = self.image_manager.get_image(image_path, ImageSource.CommandPlugins)
+ self.slide_image = QtGui.QPixmap.fromImage(image)
+ else:
+ self.slide_image = QtGui.QPixmap(image_path)
+ self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
+ self.slide_preview.setPixmap(self.slide_image)
else:
self.slide_image = self.display.preview()
self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
--- openlp/plugins/presentations/lib/presentationcontroller.py 2015-12-31 22:46:06 +0000
+++ openlp/plugins/presentations/lib/presentationcontroller.py 2016-05-16 12:42:11 +0000
@@ -242,13 +242,13 @@
def convert_thumbnail(self, file, idx):
"""
- Convert the slide image the application made to a standard 320x240 .png image.
+ Convert the slide image the application made to a scaled 360px height .png image.
"""
if self.check_thumbnails():
return
if os.path.isfile(file):
thumb_path = self.get_thumbnail_path(idx, False)
- create_thumb(file, thumb_path, False, QtCore.QSize(320, 240))
+ create_thumb(file, thumb_path, False, QtCore.QSize(-1, 360))
def get_thumbnail_path(self, slide_no, check_exists):
"""
=== modified file 'tests/functional/openlp_core_lib/test_lib.py'
--- tests/functional/openlp_core_lib/test_lib.py 2015-12-31 22:46:06 +0000
+++ tests/functional/openlp_core_lib/test_lib.py 2016-05-16 12:42:11 +0000
@@ -250,7 +250,7 @@
def create_thumb_with_size_test(self):
"""
- Test the create_thumb() function
+ Test the create_thumb() function with a given size.
"""
# GIVEN: An image to create a thumb of.
image_path = os.path.join(TEST_PATH, 'church.jpg')
@@ -270,7 +270,7 @@
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path, size=thumb_size)
- # THEN: Check if the thumb was created.
+ # THEN: Check if the thumb was created and scaled to the given size.
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
self.assertFalse(icon.isNull(), 'The icon should not be null')
@@ -282,6 +282,194 @@
except:
pass
+ def create_thumb_no_size_test(self):
+ """
+ Test the create_thumb() function with no size specified.
+ """
+ # GIVEN: An image to create a thumb of.
+ image_path = os.path.join(TEST_PATH, 'church.jpg')
+ thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
+ expected_size = QtCore.QSize(63, 88)
+
+ # Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
+ # last test.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ # Only continue when the thumb does not exist.
+ self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
+
+ # WHEN: Create the thumb.
+ icon = create_thumb(image_path, thumb_path)
+
+ # THEN: Check if the thumb was created, retaining its aspect ratio.
+ self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # Remove the thumb so that the test actually tests if the thumb will be created.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ def create_thumb_invalid_size_test(self):
+ """
+ Test the create_thumb() function with invalid size specified.
+ """
+ # GIVEN: An image to create a thumb of.
+ image_path = os.path.join(TEST_PATH, 'church.jpg')
+ thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
+ thumb_size = QtCore.QSize(-1, -1)
+ expected_size = QtCore.QSize(63, 88)
+
+ # Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
+ # last test.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ # Only continue when the thumb does not exist.
+ self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
+
+ # WHEN: Create the thumb.
+ icon = create_thumb(image_path, thumb_path, size=thumb_size)
+
+ # THEN: Check if the thumb was created, retaining its aspect ratio.
+ self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # Remove the thumb so that the test actually tests if the thumb will be created.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ def create_thumb_width_only_test(self):
+ """
+ Test the create_thumb() function with a size of only width specified.
+ """
+ # GIVEN: An image to create a thumb of.
+ image_path = os.path.join(TEST_PATH, 'church.jpg')
+ thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
+ thumb_size = QtCore.QSize(100, -1)
+ expected_size = QtCore.QSize(100, 137)
+
+ # Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
+ # last test.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ # Only continue when the thumb does not exist.
+ self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
+
+ # WHEN: Create the thumb.
+ icon = create_thumb(image_path, thumb_path, size=thumb_size)
+
+ # THEN: Check if the thumb was created, retaining its aspect ratio.
+ self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # Remove the thumb so that the test actually tests if the thumb will be created.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ def create_thumb_height_only_test(self):
+ """
+ Test the create_thumb() function with a size of only height specified.
+ """
+ # GIVEN: An image to create a thumb of.
+ image_path = os.path.join(TEST_PATH, 'church.jpg')
+ thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
+ thumb_size = QtCore.QSize(-1, 100)
+ expected_size = QtCore.QSize(72, 100)
+
+ # Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
+ # last test.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ # Only continue when the thumb does not exist.
+ self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
+
+ # WHEN: Create the thumb.
+ icon = create_thumb(image_path, thumb_path, size=thumb_size)
+
+ # THEN: Check if the thumb was created, retaining its aspect ratio.
+ self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # Remove the thumb so that the test actually tests if the thumb will be created.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ def create_thumb_empty_img_test(self):
+ """
+ Test the create_thumb() function with a size of only height specified.
+ """
+ # GIVEN: An image to create a thumb of.
+ image_path = os.path.join(TEST_PATH, 'church.jpg')
+ thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
+ thumb_size = QtCore.QSize(-1, 100)
+ expected_size_1 = QtCore.QSize(88, 88)
+ expected_size_2 = QtCore.QSize(100, 100)
+
+
+ # Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
+ # last test.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
+ # Only continue when the thumb does not exist.
+ self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
+
+ # WHEN: Create the thumb.
+ with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
+ mocked_size.return_value = QtCore.QSize(0, 0)
+ icon = create_thumb(image_path, thumb_path, size=None)
+
+ # THEN: Check if the thumb was created with aspect ratio of 1.
+ self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size_1, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # WHEN: Create the thumb.
+ with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
+ mocked_size.return_value = QtCore.QSize(0, 0)
+ icon = create_thumb(image_path, thumb_path, size=thumb_size)
+
+ # THEN: Check if the thumb was created with aspect ratio of 1.
+ self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
+ self.assertFalse(icon.isNull(), 'The icon should not be null')
+ self.assertEqual(expected_size_2, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
+
+ # Remove the thumb so that the test actually tests if the thumb will be created.
+ try:
+ os.remove(thumb_path)
+ except:
+ pass
+
def check_item_selected_true_test(self):
"""
Test that the check_item_selected() function returns True when there are selected indexes
=== modified file 'tests/functional/openlp_core_lib/test_serviceitem.py'
--- tests/functional/openlp_core_lib/test_serviceitem.py 2015-12-31 22:46:06 +0000
+++ tests/functional/openlp_core_lib/test_serviceitem.py 2016-05-16 12:42:11 +0000
@@ -244,14 +244,16 @@
self.assertEqual(service_item.service_item_type, ServiceItemType.Command, 'It should be a Command')
self.assertEqual(service_item.get_frames()[0], frame, 'Frames should match')
+ @patch(u'openlp.core.lib.serviceitem.ServiceItem.image_manager')
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
- def add_from_command_for_a_presentation_thumb_test(self, mocked_get_section_data_path):
+ def add_from_command_for_a_presentation_thumb_test(self, mocked_get_section_data_path, mocked_image_manager):
"""
- Test the Service Item - adding a presentation, and updating the thumb path
+ Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager
"""
# GIVEN: A service item, a mocked AppLocation and presentation data
mocked_get_section_data_path.return_value = os.path.join('mocked', 'section', 'path')
service_item = ServiceItem(None)
+ service_item.add_capability(ItemCapabilities.HasThumbnails)
service_item.has_original_files = False
service_item.name = 'presentations'
presentation_name = 'test.pptx'
@@ -270,6 +272,7 @@
# THEN: verify that it is setup as a Command and that the frame data matches
self.assertEqual(service_item.service_item_type, ServiceItemType.Command, 'It should be a Command')
self.assertEqual(service_item.get_frames()[0], frame, 'Frames should match')
+ self.assertEqual(1, mocked_image_manager.add_image.call_count, 'image_manager should be used')
def service_item_load_optical_media_from_service_test(self):
"""
=== modified file 'tests/functional/openlp_core_ui/test_slidecontroller.py'
--- tests/functional/openlp_core_ui/test_slidecontroller.py 2016-02-27 14:25:31 +0000
+++ tests/functional/openlp_core_ui/test_slidecontroller.py 2016-05-16 12:42:11 +0000
@@ -26,7 +26,7 @@
from unittest import TestCase
from openlp.core import Registry
-from openlp.core.lib import ServiceItemAction
+from openlp.core.lib import ImageSource, ServiceItemAction
from openlp.core.ui import SlideController, LiveController, PreviewController
from openlp.core.ui.slidecontroller import InfoLabel, WIDE_MENU, NON_TEXT_MENU
@@ -713,6 +713,175 @@
slide_controller.theme_screen, slide_controller.blank_screen
])
+ @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
+ @patch(u'PyQt5.QtCore.QTimer.singleShot')
+ def update_preview_test_live(self, mocked_singleShot, mocked_image_manager):
+ """
+ Test that the preview screen is updated with a screen grab for live service items
+ """
+ # GIVEN: A mocked live service item, a mocked image_manager, a mocked Registry,
+ # and a slide controller with many mocks.
+ # Mocked Live Item
+ mocked_live_item = MagicMock()
+ mocked_live_item.get_rendered_frame.return_value = ''
+ mocked_live_item.is_capable = MagicMock()
+ mocked_live_item.is_capable.side_effect = [True, True]
+ # Mock image_manager
+ mocked_image_manager.get_image.return_value = QtGui.QImage()
+ # Mock Registry
+ Registry.create()
+ mocked_main_window = MagicMock()
+ Registry().register('main_window', mocked_main_window)
+ # Mock SlideController
+ slide_controller = SlideController(None)
+ slide_controller.service_item = mocked_live_item
+ slide_controller.is_live = True
+ slide_controller.log_debug = MagicMock()
+ slide_controller.selected_row = MagicMock()
+ slide_controller.screens = MagicMock()
+ slide_controller.screens.current = {'primary': ''}
+ slide_controller.display = MagicMock()
+ slide_controller.display.preview.return_value = QtGui.QImage()
+ slide_controller.grab_maindisplay = MagicMock()
+ slide_controller.slide_preview = MagicMock()
+ slide_controller.slide_count = 0
+
+ # WHEN: update_preview is called
+ slide_controller.update_preview()
+
+ # THEN: A screen_grab should have been called
+ self.assertEqual(0, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should not be called')
+ self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
+ self.assertEqual(2, mocked_singleShot.call_count,
+ 'Timer to grab_maindisplay should have been called 2 times')
+ self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager not be called')
+
+ @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
+ @patch(u'PyQt5.QtCore.QTimer.singleShot')
+ def update_preview_test_pres(self, mocked_singleShot, mocked_image_manager):
+ """
+ Test that the preview screen is updated with the correct preview for presentation service items
+ """
+ # GIVEN: A mocked presentation service item, a mocked image_manager, a mocked Registry,
+ # and a slide controller with many mocks.
+ # Mocked Presentation Item
+ mocked_pres_item = MagicMock()
+ mocked_pres_item.get_rendered_frame.return_value = ''
+ mocked_pres_item.is_capable = MagicMock()
+ mocked_pres_item.is_capable.side_effect = [True, True]
+ # Mock image_manager
+ mocked_image_manager.get_image.return_value = QtGui.QImage()
+ # Mock Registry
+ Registry.create()
+ mocked_main_window = MagicMock()
+ Registry().register('main_window', mocked_main_window)
+ # Mock SlideController
+ slide_controller = SlideController(None)
+ slide_controller.service_item = mocked_pres_item
+ slide_controller.is_live = False
+ slide_controller.log_debug = MagicMock()
+ slide_controller.selected_row = MagicMock()
+ slide_controller.screens = MagicMock()
+ slide_controller.screens.current = {'primary': ''}
+ slide_controller.display = MagicMock()
+ slide_controller.display.preview.return_value = QtGui.QImage()
+ slide_controller.grab_maindisplay = MagicMock()
+ slide_controller.slide_preview = MagicMock()
+ slide_controller.slide_count = 0
+
+ # WHEN: update_preview is called
+ slide_controller.update_preview()
+
+ # THEN: setPixmap and the image_manager should have been called
+ self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
+ self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
+ self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
+ self.assertEqual(1, mocked_image_manager.get_image.call_count, 'image_manager should be called')
+
+ @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
+ @patch(u'PyQt5.QtCore.QTimer.singleShot')
+ def update_preview_test_media(self, mocked_singleShot, mocked_image_manager):
+ """
+ Test that the preview screen is updated with the correct preview for media service items
+ """
+ # GIVEN: A mocked media service item, a mocked image_manager, a mocked Registry,
+ # and a slide controller with many mocks.
+ # Mocked Media Item
+ mocked_media_item = MagicMock()
+ mocked_media_item.get_rendered_frame.return_value = ''
+ mocked_media_item.is_capable = MagicMock()
+ mocked_media_item.is_capable.side_effect = [True, False]
+ # Mock image_manager
+ mocked_image_manager.get_image.return_value = QtGui.QImage()
+ # Mock Registry
+ Registry.create()
+ mocked_main_window = MagicMock()
+ Registry().register('main_window', mocked_main_window)
+ # Mock SlideController
+ slide_controller = SlideController(None)
+ slide_controller.service_item = mocked_media_item
+ slide_controller.is_live = False
+ slide_controller.log_debug = MagicMock()
+ slide_controller.selected_row = MagicMock()
+ slide_controller.screens = MagicMock()
+ slide_controller.screens.current = {'primary': ''}
+ slide_controller.display = MagicMock()
+ slide_controller.display.preview.return_value = QtGui.QImage()
+ slide_controller.grab_maindisplay = MagicMock()
+ slide_controller.slide_preview = MagicMock()
+ slide_controller.slide_count = 0
+
+ # WHEN: update_preview is called
+ slide_controller.update_preview()
+
+ # THEN: setPixmap should have been called
+ self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
+ self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
+ self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
+ self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager should not be called')
+
+ @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
+ @patch(u'PyQt5.QtCore.QTimer.singleShot')
+ def update_preview_test_image(self, mocked_singleShot, mocked_image_manager):
+ """
+ Test that the preview screen is updated with the correct preview for image service items
+ """
+ # GIVEN: A mocked image service item, a mocked image_manager, a mocked Registry,
+ # and a slide controller with many mocks.
+ # Mocked Image Item
+ mocked_img_item = MagicMock()
+ mocked_img_item.get_rendered_frame.return_value = ''
+ mocked_img_item.is_capable = MagicMock()
+ mocked_img_item.is_capable.side_effect = [False, True]
+ # Mock image_manager
+ mocked_image_manager.get_image.return_value = QtGui.QImage()
+ # Mock Registry
+ Registry.create()
+ mocked_main_window = MagicMock()
+ Registry().register('main_window', mocked_main_window)
+ # Mock SlideController
+ slide_controller = SlideController(None)
+ slide_controller.service_item = mocked_img_item
+ slide_controller.is_live = False
+ slide_controller.log_debug = MagicMock()
+ slide_controller.selected_row = MagicMock()
+ slide_controller.screens = MagicMock()
+ slide_controller.screens.current = {'primary': ''}
+ slide_controller.display = MagicMock()
+ slide_controller.display.preview.return_value = QtGui.QImage()
+ slide_controller.grab_maindisplay = MagicMock()
+ slide_controller.slide_preview = MagicMock()
+ slide_controller.slide_count = 0
+
+ # WHEN: update_preview is called
+ slide_controller.update_preview()
+
+ # THEN: setPixmap and display.preview should have been called
+ self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
+ self.assertEqual(1, slide_controller.display.preview.call_count, 'display.preview() should be called')
+ self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
+ self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager should not be called')
+
class TestInfoLabel(TestCase):
=== modified file 'tests/functional/openlp_core_ui_lib/test_listpreviewwidget.py'
--- tests/functional/openlp_core_ui_lib/test_listpreviewwidget.py 2016-04-22 18:35:23 +0000
+++ tests/functional/openlp_core_ui_lib/test_listpreviewwidget.py 2016-05-16 12:42:11 +0000
@@ -24,9 +24,11 @@
"""
from unittest import TestCase
+from PyQt5 import QtGui
+
from openlp.core.common import Settings
from openlp.core.ui.lib.listpreviewwidget import ListPreviewWidget
-from openlp.core.lib import ServiceItem
+from openlp.core.lib import ImageSource, ServiceItem
from tests.functional import MagicMock, patch, call
@@ -72,6 +74,53 @@
self.assertIsNotNone(list_preview_widget, 'The ListPreviewWidget object should not be None')
self.assertEquals(list_preview_widget.screen_ratio, 1, 'Should not be called')
+ @patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.image_manager')
+ @patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.resizeRowsToContents')
+ @patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.setRowHeight')
+ def replace_service_item_test_thumbs(self, mocked_setRowHeight, mocked_resizeRowsToContents,
+ mocked_image_manager):
+ """
+ Test that thubmails for different slides are loaded properly in replace_service_item.
+ """
+ # GIVEN: A setting to adjust "Max height for non-text slides in slide controller",
+ # different ServiceItem(s), an ImageManager, and a ListPreviewWidget.
+
+ # Mock Settings().value('advanced/slide max height')
+ self.mocked_Settings_obj.value.return_value = 0
+ # Mock self.viewport().width()
+ self.mocked_viewport_obj.width.return_value = 200
+ # Mock Image service item
+ mocked_img_service_item = MagicMock()
+ mocked_img_service_item.is_text.return_value = False
+ mocked_img_service_item.is_media.return_value = False
+ mocked_img_service_item.is_command.return_value = False
+ mocked_img_service_item.is_capable.return_value = False
+ mocked_img_service_item.get_frames.return_value = [{'title': None, 'path': 'TEST1', 'image': 'FAIL'},
+ {'title': None, 'path': 'TEST2', 'image': 'FAIL'}]
+ # Mock Command service item
+ mocked_cmd_service_item = MagicMock()
+ mocked_cmd_service_item.is_text.return_value = False
+ mocked_cmd_service_item.is_media.return_value = False
+ mocked_cmd_service_item.is_command.return_value = True
+ mocked_cmd_service_item.is_capable.return_value = True
+ mocked_cmd_service_item.get_frames.return_value = [{'title': None, 'path': 'FAIL', 'image': 'TEST3'},
+ {'title': None, 'path': 'FAIL', 'image': 'TEST4'}]
+ # Mock image_manager
+ mocked_image_manager.get_image.return_value = QtGui.QImage()
+
+ # init ListPreviewWidget and load service item
+ list_preview_widget = ListPreviewWidget(None, 1)
+
+ # WHEN: replace_service_item is called
+ list_preview_widget.replace_service_item(mocked_img_service_item, 200, 0)
+ list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0)
+
+ # THEN: The ImageManager should be called in the appriopriate manner for each service item.
+ self.assertEquals(mocked_image_manager.get_image.call_count, 4, 'Should be called once for each slide')
+ calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin),
+ call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)]
+ mocked_image_manager.get_image.assert_has_calls(calls)
+
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.resizeRowsToContents')
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.setRowHeight')
def replace_recalculate_layout_test_text(self, mocked_setRowHeight, mocked_resizeRowsToContents):
@@ -120,6 +169,7 @@
# Mock image service item
service_item = MagicMock()
service_item.is_text.return_value = False
+ service_item.is_capable.return_value = False
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
{'title': None, 'path': None, 'image': None}]
# init ListPreviewWidget and load service item
@@ -156,6 +206,7 @@
# Mock image service item
service_item = MagicMock()
service_item.is_text.return_value = False
+ service_item.is_capable.return_value = False
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
{'title': None, 'path': None, 'image': None}]
# init ListPreviewWidget and load service item
@@ -225,6 +276,7 @@
# Mock image service item
service_item = MagicMock()
service_item.is_text.return_value = False
+ service_item.is_capable.return_value = False
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
{'title': None, 'path': None, 'image': None}]
# Mock self.cellWidget().children().setMaximumWidth()
@@ -261,6 +313,7 @@
# Mock image service item
service_item = MagicMock()
service_item.is_text.return_value = False
+ service_item.is_capable.return_value = False
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
{'title': None, 'path': None, 'image': None}]
# Mock self.cellWidget().children().setMaximumWidth()
Follow ups