Changed Image dimension-key into width and height + a bunch of small changes

This commit is contained in:
Tomas Groth 2014-07-15 20:52:59 +02:00
parent 00693b8cce
commit a0b7c72e09
10 changed files with 42 additions and 49 deletions

View File

@ -107,7 +107,7 @@ class Image(object):
"""
secondary_priority = 0
def __init__(self, path, source, background, dimensions=''):
def __init__(self, path, source, background, width=-1, height=-1):
"""
Create an image for the :class:`ImageManager`'s cache.
@ -116,7 +116,8 @@ class Image(object):
:class:`~openlp.core.lib.ImageSource` class.
:param background: A ``QtGui.QColor`` object specifying the colour to be used to fill the gabs if the image's
ratio does not match with the display ratio.
:param width: The width of the image, defaults to -1 meaning that the screen width will be used.
:param height: The height of the image, defaults to -1 meaning that the screen height will be used.
"""
self.path = path
self.image = None
@ -125,15 +126,8 @@ class Image(object):
self.source = source
self.background = background
self.timestamp = 0
match = re.search('(\d+)x(\d+)', dimensions)
if match:
# let's make sure that the dimensions are within reason
self.width = sorted([10, int(match.group(1)), 1000])[1]
self.height = sorted([10, int(match.group(2)), 1000])[1]
else:
# -1 means use the default dimension in ImageManager
self.width = -1
self.height = -1
self.width = width
self.height = height
# FIXME: We assume that the path exist. The caller has to take care that it exists!
if os.path.exists(path):
self.timestamp = os.stat(path).st_mtime
@ -220,13 +214,13 @@ class ImageManager(QtCore.QObject):
image.background = background
self._reset_image(image)
def update_image_border(self, path, source, background, dimensions=''):
def update_image_border(self, path, source, background, width=-1, height=-1):
"""
Border has changed so update the image affected.
"""
log.debug('update_image_border')
# Mark the image as dirty for a rebuild by setting the image and byte stream to None.
image = self._cache[(path, source, dimensions)]
image = self._cache[(path, source, width, height)]
if image.source == source:
image.background = background
self._reset_image(image)
@ -247,12 +241,12 @@ class ImageManager(QtCore.QObject):
if not self.image_thread.isRunning():
self.image_thread.start()
def get_image(self, path, source, dimensions=''):
def get_image(self, path, source, width=-1, height=-1):
"""
Return the ``QImage`` from the cache. If not present wait for the background thread to process it.
"""
log.debug('getImage %s' % path)
image = self._cache[(path, source, dimensions)]
image = self._cache[(path, source, width, height)]
if image.image is None:
self._conversion_queue.modify_priority(image, Priority.High)
# make sure we are running and if not give it a kick
@ -267,12 +261,12 @@ class ImageManager(QtCore.QObject):
self._conversion_queue.modify_priority(image, Priority.Low)
return image.image
def get_image_bytes(self, path, source, dimensions=''):
def get_image_bytes(self, path, source, width=-1, height=-1):
"""
Returns the byte string for an image. If not present wait for the background thread to process it.
"""
log.debug('get_image_bytes %s' % path)
image = self._cache[(path, source, dimensions)]
image = self._cache[(path, source, width, height)]
if image.image_bytes is None:
self._conversion_queue.modify_priority(image, Priority.Urgent)
# make sure we are running and if not give it a kick
@ -282,14 +276,14 @@ class ImageManager(QtCore.QObject):
time.sleep(0.1)
return image.image_bytes
def add_image(self, path, source, background, dimensions=''):
def add_image(self, path, source, background, width=-1, height=-1):
"""
Add image to cache if it is not already there.
"""
log.debug('add_image %s' % path)
if not (path, source, dimensions) in self._cache:
image = Image(path, source, background, dimensions)
self._cache[(path, source, dimensions)] = image
if not (path, source, width, height) in self._cache:
image = Image(path, source, background, width, height)
self._cache[(path, source, width, height)] = image
self._conversion_queue.put((image.priority, image.secondary_priority, image))
# Check if the there are any images with the same path and check if the timestamp has changed.
for image in list(self._cache.values()):

View File

@ -321,6 +321,9 @@ class ServiceItem(RegistryProperties):
:param notes: Notes to show in the webinteface, optional.
"""
self.service_item_type = ServiceItemType.Command
# If the item should have a display title but this frame doesn't have one, we make one up
if self.is_capable(ItemCapabilities.HasDisplayTitle) and not display_title:
display_title = translate('OpenLP.ServiceItem', '[slide %d]') % (len(self._raw_frames) + 1)
self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
'display_title': display_title, 'notes': notes})
self._new_item()

View File

@ -1284,9 +1284,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
# prefer to use a display_title
if service_item_from_item.is_capable(ItemCapabilities.HasDisplayTitle):
text = frame['display_title'].replace('\n', ' ')
# oops, it is missing, let's make one up
if len(text.strip()) == 0:
text = '[slide ' + str(count+1) + ']'
else:
text = frame['title'].replace('\n', ' ')
child.setText(0, text[:40])

View File

@ -867,11 +867,7 @@ class SlideController(DisplayController, RegistryProperties):
:param message: remote message to be processed.
"""
index = 0
if len(message) == 0 or message[0] == 'undefined':
return
else:
index = int(message[0])
index = int(message[0])
if not self.service_item:
return
if self.service_item.is_command():

View File

@ -492,4 +492,3 @@ class ImpressDocument(PresentationDocument):
note = ' '
notes.append(note)
self.save_titles_and_notes(titles, notes)
return

View File

@ -326,23 +326,22 @@ class PresentationMediaItem(MediaManagerItem):
if img:
# Get titles and notes
titles, notes = doc.get_titles_and_notes()
service_item.add_capability(ItemCapabilities.HasDisplayTitle)
if notes.count('') != len(notes):
service_item.add_capability(ItemCapabilities.HasNotes)
service_item.add_capability(ItemCapabilities.HasThumbnails)
while img:
# Use title and note if available
title = None
title = ''
if titles and len(titles) >= i:
title = titles[i - 1]
note = None
note = ''
if notes and len(notes) >= i:
note = notes[i - 1]
service_item.add_from_command(path, name, img, title, note)
i += 1
img = doc.get_thumbnail_path(i, True)
doc.close_presentation()
if titles.count('') != len(titles):
service_item.add_capability(ItemCapabilities.HasDisplayTitle)
if notes.count('') != len(notes):
service_item.add_capability(ItemCapabilities.HasNotes)
service_item.add_capability(ItemCapabilities.HasThumbnails)
return True
else:
# File is no longer present

View File

@ -413,7 +413,6 @@ class PowerpointDocument(PresentationDocument):
note = ' '
notes.append(note)
self.save_titles_and_notes(titles, notes)
return
def show_error_msg(self):
"""

View File

@ -218,7 +218,6 @@ class PptviewDocument(PresentationDocument):
list_to_add[index] = text
# now let's write the files
self.save_titles_and_notes(titles, notes)
return
def close_presentation(self):
"""

View File

@ -388,8 +388,15 @@ class HttpRouter(RegistryProperties):
"""
log.debug('serve thumbnail %s/thumbnails%s/%s' % (controller_name, dimensions, file_name))
supported_controllers = ['presentations', 'images']
if not dimensions:
dimensions = ''
# -1 means use the default dimension in ImageManager
width = -1
height = -1
if dimensions:
match = re.search('(\d+)x(\d+)', dimensions)
if match:
# let's make sure that the dimensions are within reason
width = sorted([10, int(match.group(1)), 1000])[1]
height = sorted([10, int(match.group(2)), 1000])[1]
content = ''
content_type = None
if controller_name and file_name:
@ -400,9 +407,9 @@ class HttpRouter(RegistryProperties):
'thumbnails/' + full_path))
if os.path.exists(full_path):
path, just_file_name = os.path.split(full_path)
self.image_manager.add_image(full_path, just_file_name, None, dimensions)
self.image_manager.add_image(full_path, just_file_name, None, width, height)
ext, content_type = self.get_content_type(full_path)
image = self.image_manager.get_image(full_path, just_file_name, dimensions)
image = self.image_manager.get_image(full_path, just_file_name, width, height)
content = image_to_byte(image, False)
if len(content) == 0:
return self.do_not_found()

View File

@ -96,30 +96,30 @@ class TestImageManager(TestCase, TestMixin):
"""
# GIVEN: add an image with specific dimensions
full_path = os.path.normpath(os.path.join(TEST_PATH, 'church.jpg'))
self.image_manager.add_image(full_path, 'church.jpg', None, '80x80')
self.image_manager.add_image(full_path, 'church.jpg', None, 80, 80)
# WHEN: the image is retrieved
image = self.image_manager.get_image(full_path, 'church.jpg', '80x80')
image = self.image_manager.get_image(full_path, 'church.jpg', 80, 80)
# THEN: The return should be of type image
self.assertEqual(isinstance(image, QtGui.QImage), True, 'The returned object should be a QImage')
# WHEN: adding the same image with different dimensions
self.image_manager.add_image(full_path, 'church.jpg', None, '100x100')
self.image_manager.add_image(full_path, 'church.jpg', None, 100, 100)
# THEN: the cache should contain two pictures
self.assertEqual(len(self.image_manager._cache), 2,
'Image manager should consider two dimensions of the same picture as different')
# WHEN: adding the same image with first dimensions
self.image_manager.add_image(full_path, 'church.jpg', None, '80x80')
self.image_manager.add_image(full_path, 'church.jpg', None, 80, 80)
# THEN: the cache should still contain only two pictures
self.assertEqual(len(self.image_manager._cache), 2, 'Same dimensions should not be added again')
# WHEN: calling with correct image, but wrong dimensions
with self.assertRaises(KeyError) as context:
self.image_manager.get_image(full_path, 'church.jpg', '120x120')
self.image_manager.get_image(full_path, 'church.jpg', 120, 120)
self.assertNotEquals(context.exception, '', 'KeyError exception should have been thrown for missing dimension')
def process_cache_test(self):
@ -184,7 +184,7 @@ class TestImageManager(TestCase, TestMixin):
:param image: The name of the image. E. g. ``image1``
"""
return self.image_manager._cache[(TEST_PATH, image, '')].priority
return self.image_manager._cache[(TEST_PATH, image, -1, -1)].priority
def mocked_resize_image(self, *args):
"""