openlp/openlp/core/lib/serviceitem.py

399 lines
14 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2009-12-31 12:52:01 +00:00
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
2010-07-24 22:10:47 +00:00
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
2010-06-10 21:30:50 +00:00
"""
The :mod:`serviceitem` provides the service item functionality including the
type and capability of an item.
"""
2009-05-02 11:16:08 +00:00
import logging
import os
2009-09-27 12:56:14 +00:00
import time
2009-11-04 17:48:46 +00:00
import uuid
2009-07-10 13:16:15 +00:00
2009-09-25 00:43:42 +00:00
from PyQt4 import QtGui
2010-08-02 19:05:40 +00:00
from openlp.core.lib import build_icon, resize_image
2009-07-10 13:16:15 +00:00
2010-02-27 15:31:23 +00:00
log = logging.getLogger(__name__)
class ServiceItemType(object):
2009-09-29 04:58:26 +00:00
"""
Defines the type of service item
"""
Text = 1
Image = 2
Command = 3
2010-04-03 07:10:31 +00:00
class ItemCapabilities(object):
2010-06-10 21:30:50 +00:00
"""
Provides an enumeration of a serviceitem's capabilities
"""
2010-05-24 22:37:20 +00:00
AllowsPreview = 1
AllowsEdit = 2
AllowsMaintain = 3
RequiresMedia = 4
AllowsLoop = 5
AllowsAdditions = 6
2010-04-03 07:10:31 +00:00
2009-07-10 13:16:15 +00:00
class ServiceItem(object):
"""
The service item is a base class for the plugins to use to interact with
the service manager, the slide controller, and the projection screen
compositor.
"""
2009-05-02 11:16:08 +00:00
log.info(u'Service Item created')
2009-11-14 08:40:14 +00:00
def __init__(self, plugin=None):
"""
2009-07-10 13:16:15 +00:00
Set up the service item.
2009-11-14 08:40:14 +00:00
``plugin``
2009-07-10 13:16:15 +00:00
The plugin that this service item belongs to.
"""
2009-11-14 08:40:14 +00:00
if plugin:
2010-07-02 18:21:45 +00:00
self.render_manager = plugin.renderManager
2009-11-14 08:40:14 +00:00
self.name = plugin.name
self.title = u''
2010-06-12 20:22:58 +00:00
self.shortname = u''
self.audit = u''
2009-05-02 11:16:08 +00:00
self.items = []
self.iconic_representation = None
self.raw_footer = None
self.theme = None
self.service_item_type = None
2009-11-14 09:06:25 +00:00
self._raw_frames = []
self._display_frames = []
2010-08-02 19:08:55 +00:00
self._uuid = 0
2010-03-02 19:44:55 +00:00
self.notes = u''
2010-03-28 15:56:49 +00:00
self.from_plugin = False
2010-04-03 07:10:31 +00:00
self.capabilities = []
2010-05-07 18:29:17 +00:00
self.is_valid = True
2010-06-20 11:09:15 +00:00
self.cache = {}
2010-06-12 20:22:58 +00:00
self.icon = None
2010-04-02 19:02:38 +00:00
2010-08-02 19:08:55 +00:00
def _new_item(self):
self._uuid =unicode(uuid.uuid1())
2010-04-03 07:10:31 +00:00
def add_capability(self, capability):
2010-06-10 21:30:50 +00:00
"""
Add an ItemCapability to a ServiceItem
``capability``
The capability to add
"""
2010-04-03 07:10:31 +00:00
self.capabilities.append(capability)
2010-04-02 19:02:38 +00:00
2010-04-03 07:10:31 +00:00
def is_capable(self, capability):
2010-06-10 21:30:50 +00:00
"""
Tell the caller if a ServiceItem has a capability
``capability``
The capability to test for
"""
2010-04-03 07:10:31 +00:00
return capability in self.capabilities
2009-05-02 11:16:08 +00:00
2010-06-12 20:22:58 +00:00
def add_icon(self, icon):
2009-07-10 13:16:15 +00:00
"""
Add an icon to the service item. This is used when displaying the
service item in the service manager.
``icon``
2010-07-10 01:21:03 +00:00
A string to an icon in the resources or on disk.
2009-07-10 13:16:15 +00:00
"""
2009-06-08 19:06:42 +00:00
self.icon = icon
self.iconic_representation = build_icon(icon)
def render(self):
"""
2009-09-29 04:58:26 +00:00
The render method is what generates the frames for the screen.
"""
2009-05-02 11:16:08 +00:00
log.debug(u'Render called')
2009-11-14 09:06:25 +00:00
self._display_frames = []
2010-06-20 11:09:15 +00:00
self.clear_cache()
if self.service_item_type == ServiceItemType.Text:
2009-09-13 07:39:48 +00:00
log.debug(u'Formatting slides')
2009-09-25 23:06:54 +00:00
if self.theme is None:
2010-06-12 20:22:58 +00:00
self.render_manager.set_override_theme(None)
2009-09-13 07:39:48 +00:00
else:
2010-06-12 20:22:58 +00:00
self.render_manager.set_override_theme(self.theme)
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2009-09-27 12:56:14 +00:00
before = time.time()
2010-06-12 20:22:58 +00:00
formated = self.render_manager.format_slide(slide[u'raw_slide'])
for format in formated:
2009-09-15 17:45:32 +00:00
lines = u''
title = u''
2009-09-15 17:45:32 +00:00
for line in format:
if title == u'':
title = line
2009-09-15 17:45:32 +00:00
lines += line + u'\n'
2010-05-26 16:01:45 +00:00
self._display_frames.append({u'title': title,
u'text': lines.rstrip(),
u'verseTag': slide[u'verseTag'] })
2010-06-20 11:09:15 +00:00
if len(self._display_frames) in self.cache.keys():
del self.cache[len(self._display_frames)]
2009-11-15 07:07:40 +00:00
log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image:
2010-07-02 05:16:30 +00:00
for slide in self._raw_frames:
2010-06-12 20:22:58 +00:00
slide[u'image'] = resize_image(slide[u'image'],
self.render_manager.width, self.render_manager.height)
elif self.service_item_type == ServiceItemType.Command:
pass
else:
log.error(u'Invalid value renderer :%s' % self.service_item_type)
2009-09-15 18:37:03 +00:00
def render_individual(self, row):
2009-09-29 04:58:26 +00:00
"""
Takes an array of text and generates an Image from the
2009-09-29 04:58:26 +00:00
theme. It assumes the text will fit on the screen as it
has generated by the render method above.
"""
2009-09-15 19:06:40 +00:00
log.debug(u'render individual')
2009-09-25 23:06:54 +00:00
if self.theme is None:
2010-06-12 20:22:58 +00:00
self.render_manager.set_override_theme(None)
2009-09-15 19:06:40 +00:00
else:
2010-06-12 20:22:58 +00:00
self.render_manager.set_override_theme(self.theme)
2009-11-14 09:06:25 +00:00
format = self._display_frames[row][u'text'].split(u'\n')
2010-06-20 11:09:15 +00:00
if self.cache.get(row):
2010-05-10 18:19:45 +00:00
frame = self.cache[row]
2010-03-11 08:29:32 +00:00
else:
2010-05-10 18:19:45 +00:00
if format[0]:
2010-06-12 20:22:58 +00:00
frame = self.render_manager.generate_slide(format,
self.raw_footer)
2010-05-10 18:19:45 +00:00
else:
2010-06-12 20:22:58 +00:00
frame = self.render_manager.generate_slide(format, u'')
2010-05-10 18:19:45 +00:00
self.cache[row] = frame
2009-09-15 18:37:03 +00:00
return frame
2009-11-14 08:40:14 +00:00
def add_from_image(self, path, title, image):
2009-07-10 13:16:15 +00:00
"""
Add an image slide to the service item.
``path``
The directory in which the image file is located.
2009-11-14 08:40:14 +00:00
``title``
2009-07-10 13:16:15 +00:00
A title for the slide in the service item.
``image``
The actual image file name.
"""
self.service_item_type = ServiceItemType.Image
2009-11-14 09:06:25 +00:00
self._raw_frames.append(
2010-03-18 21:50:20 +00:00
{u'title': title, u'image': image, u'path': path})
2010-08-02 19:08:55 +00:00
self._new_item()
2010-06-12 20:22:58 +00:00
def add_from_text(self, title, raw_slide, verse_tag=None):
2009-07-10 13:16:15 +00:00
"""
Add a text slide to the service item.
``frame_title``
The title of the slide in the service item.
``raw_slide``
The raw text of the slide.
"""
self.service_item_type = ServiceItemType.Text
2009-11-14 08:40:14 +00:00
title = title.split(u'\n')[0]
2009-11-14 09:06:25 +00:00
self._raw_frames.append(
2010-06-12 20:22:58 +00:00
{u'title': title, u'raw_slide': raw_slide, u'verseTag':verse_tag})
2010-08-02 19:08:55 +00:00
self._new_item()
2009-11-14 08:40:14 +00:00
def add_from_command(self, path, file_name, image):
2009-07-10 13:16:15 +00:00
"""
Add a slide from a command.
2009-11-14 08:40:14 +00:00
``path``
2009-07-10 13:16:15 +00:00
The title of the slide in the service item.
2009-11-14 08:40:14 +00:00
``file_name``
2009-07-10 13:16:15 +00:00
The title of the slide in the service item.
``image``
2009-07-10 13:16:15 +00:00
The command of/for the slide.
"""
self.service_item_type = ServiceItemType.Command
2009-11-14 09:06:25 +00:00
self._raw_frames.append(
2010-03-18 21:50:20 +00:00
{u'title': file_name, u'image': image, u'path': path})
2010-08-02 19:08:55 +00:00
self._new_item()
2009-05-02 11:16:08 +00:00
2009-09-19 21:45:50 +00:00
def get_service_repr(self):
"""
2009-09-19 21:45:50 +00:00
This method returns some text which can be saved into the service
2009-07-10 13:16:15 +00:00
file to represent this item.
"""
2009-09-19 21:45:50 +00:00
service_header = {
2009-09-05 13:30:09 +00:00
u'name': self.name.lower(),
2009-11-14 08:40:14 +00:00
u'plugin': self.name,
2009-07-10 13:16:15 +00:00
u'theme':self.theme,
u'title':self.title,
u'icon':self.icon,
u'footer':self.raw_footer,
u'type':self.service_item_type,
u'audit':self.audit,
2010-03-02 19:44:55 +00:00
u'notes':self.notes,
2010-04-02 19:02:38 +00:00
u'from_plugin':self.from_plugin,
2010-04-03 07:10:31 +00:00
u'capabilities':self.capabilities
2009-07-10 13:16:15 +00:00
}
2009-09-19 21:45:50 +00:00
service_data = []
if self.service_item_type == ServiceItemType.Text:
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2009-09-19 21:45:50 +00:00
service_data.append(slide)
elif self.service_item_type == ServiceItemType.Image:
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2009-09-19 21:45:50 +00:00
service_data.append(slide[u'title'])
elif self.service_item_type == ServiceItemType.Command:
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2010-05-26 16:01:45 +00:00
service_data.append(
{u'title':slide[u'title'], u'image':slide[u'image']})
2009-09-19 21:45:50 +00:00
return {u'header': service_header, u'data': service_data}
2009-09-19 21:45:50 +00:00
def set_from_service(self, serviceitem, path=None):
"""
2009-07-10 13:16:15 +00:00
This method takes a service item from a saved service file (passed
from the ServiceManager) and extracts the data actually required.
``serviceitem``
The item to extract data from.
``path``
Defaults to *None*. Any path data, usually for images.
"""
header = serviceitem[u'serviceitem'][u'header']
self.title = header[u'title']
2009-09-05 13:30:09 +00:00
self.name = header[u'name']
self.service_item_type = header[u'type']
self.shortname = header[u'plugin']
self.theme = header[u'theme']
2010-06-12 20:22:58 +00:00
self.add_icon(header[u'icon'])
self.raw_footer = header[u'footer']
self.audit = header[u'audit']
2010-03-02 19:44:55 +00:00
self.notes = header[u'notes']
2010-03-28 15:56:49 +00:00
self.from_plugin = header[u'from_plugin']
2010-04-03 07:10:31 +00:00
self.capabilities = header[u'capabilities']
if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
2009-11-14 09:06:25 +00:00
self._raw_frames.append(slide)
elif self.service_item_type == ServiceItemType.Image:
for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image)
real_image = QtGui.QImage(unicode(filename))
self.add_from_image(path, text_image, real_image)
elif self.service_item_type == ServiceItemType.Command:
2009-08-31 18:27:36 +00:00
for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image[u'title'])
2010-05-26 16:01:45 +00:00
self.add_from_command(
path, text_image[u'title'], text_image[u'image'] )
2009-11-05 17:03:37 +00:00
def merge(self, other):
"""
2009-11-14 09:06:25 +00:00
Updates the _uuid with the value from the original one
2010-06-25 00:25:21 +00:00
The _uuid is unique for a given service item but this allows one to
2009-11-05 17:03:37 +00:00
replace an original version.
"""
2009-11-14 09:06:25 +00:00
self._uuid = other._uuid
2009-11-05 17:03:37 +00:00
def __eq__(self, other):
"""
Confirms the service items are for the same instance
"""
if not other:
return False
2009-11-14 09:06:25 +00:00
return self._uuid == other._uuid
2009-11-05 17:03:37 +00:00
def __ne__(self, other):
"""
Confirms the service items are not for the same instance
"""
2009-11-14 09:06:25 +00:00
return self._uuid != other._uuid
2009-11-05 17:03:37 +00:00
def is_media(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is media
"""
2010-04-03 07:10:31 +00:00
return ItemCapabilities.RequiresMedia in self.capabilities
2009-11-11 19:10:38 +00:00
def is_command(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is a command
"""
return self.service_item_type == ServiceItemType.Command
2009-11-11 19:10:38 +00:00
def is_image(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is an image
"""
return self.service_item_type == ServiceItemType.Image
def uses_file(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem uses a file
"""
return self.service_item_type == ServiceItemType.Image or \
self.service_item_type == ServiceItemType.Command
def is_text(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is text
"""
return self.service_item_type == ServiceItemType.Text
2009-11-14 08:40:14 +00:00
def get_frames(self):
2010-06-10 21:30:50 +00:00
"""
Returns the frames for the ServiceItem
"""
2009-11-14 09:02:30 +00:00
if self.service_item_type == ServiceItemType.Text:
2009-11-14 09:06:25 +00:00
return self._display_frames
2009-11-14 09:02:30 +00:00
else:
2009-11-14 09:06:25 +00:00
return self._raw_frames
2009-11-14 09:02:30 +00:00
def get_rendered_frame(self, row):
2009-11-14 09:06:25 +00:00
"""
Returns the correct frame for a given list and
renders it if required.
"""
2009-11-14 09:02:30 +00:00
if self.service_item_type == ServiceItemType.Text:
return self.render_individual(row)
else:
2010-07-02 05:16:30 +00:00
return {u'main':self._raw_frames[row][u'image'], u'trans':None}
def get_frame_title(self, row=0):
"""
Returns the title of the raw frame
"""
return self._raw_frames[row][u'title']
2010-03-30 19:01:23 +00:00
def get_frame_path(self, row=0):
"""
Returns the title of the raw frame
"""
return self._raw_frames[row][u'path']
2010-05-26 16:01:45 +00:00
2010-06-20 11:09:15 +00:00
def clear_cache(self):
"""
Clear's the service item's cache.
"""
self.cache = {}