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-...

bzr-revno: 2661
Fixes: https://launchpad.net/bugs/1080596
This commit is contained in:
ian@knightly.xyz 2016-05-16 17:26:29 +01:00 committed by Tim Bentley
commit 05e9e5dca0
9 changed files with 472 additions and 19 deletions

View File

@ -55,9 +55,13 @@ class ImageSource(object):
``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 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
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:

View File

@ -334,6 +334,8 @@ class ServiceItem(RegistryProperties):
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):

View File

@ -27,7 +27,7 @@ It is based on a QTableWidget but represents its contents in list form.
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 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
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')

View File

@ -1135,9 +1135,21 @@ class SlideController(DisplayController, RegistryProperties):
"""
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())

View File

@ -242,13 +242,13 @@ class PresentationDocument(object):
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):
"""

View File

@ -250,7 +250,7 @@ class TestLib(TestCase):
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 @@ class TestLib(TestCase):
# 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 @@ class TestLib(TestCase):
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

View File

@ -244,14 +244,16 @@ class TestServiceItem(TestCase):
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 @@ class TestServiceItem(TestCase):
# 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):
"""

View File

@ -26,7 +26,7 @@ from PyQt5 import QtCore, QtGui
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 @@ class TestSlideController(TestCase):
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):

View File

@ -24,9 +24,11 @@ Package to test the openlp.core.ui.lib.listpreviewwidget package.
"""
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 @@ class TestListPreviewWidget(TestCase):
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 @@ class TestListPreviewWidget(TestCase):
# 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 @@ class TestListPreviewWidget(TestCase):
# 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 @@ class TestListPreviewWidget(TestCase):
# 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 @@ class TestListPreviewWidget(TestCase):
# 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()