openlp/openlp/core/lib/serviceitem.py

330 lines
12 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-03-21 23:58:01 +00:00
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
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
from openlp.core.lib import build_icon, Receiver, 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
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:
self.RenderManager = plugin.render_manager
self.name = plugin.name
self.title = 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
self.edit_enabled = False
2010-03-16 20:30:33 +00:00
self.maintain_allowed = False
2009-11-14 09:06:25 +00:00
self._raw_frames = []
self._display_frames = []
self._uuid = unicode(uuid.uuid1())
2010-03-28 15:56:49 +00:00
self.auto_preview_allowed = False
2010-03-02 19:44:55 +00:00
self.notes = u''
2010-03-28 15:56:49 +00:00
self.from_plugin = False
2009-05-02 11:16:08 +00:00
def addIcon(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``
An instance of QIcon or a string to an icon in the resource or on
disk.
"""
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 = []
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:
2009-09-13 07:39:48 +00:00
self.RenderManager.set_override_theme(None)
else:
self.RenderManager.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()
formated = self.RenderManager.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'
2009-11-28 12:38:48 +00:00
self._display_frames.append({u'title': title, \
u'text': lines.rstrip(), u'verseTag': slide[u'verseTag'] })
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:
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2009-09-03 17:46:46 +00:00
slide[u'image'] = \
resize_image(slide[u'image'], self.RenderManager.width,
self.RenderManager.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:
2009-09-15 19:06:40 +00:00
self.RenderManager.set_override_theme(None)
else:
self.RenderManager.set_override_theme(self.theme)
2009-11-14 09:06:25 +00:00
format = self._display_frames[row][u'text'].split(u'\n')
#if screen blank then do not display footer
2010-03-11 08:29:32 +00:00
if format[0]:
frame = self.RenderManager.generate_slide(format,
self.raw_footer)
else:
frame = self.RenderManager.generate_slide(format,u'')
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})
2009-11-28 12:38:48 +00:00
def add_from_text(self, title, raw_slide, verseTag=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(
2009-11-28 12:38:48 +00:00
{u'title': title, u'raw_slide': raw_slide, u'verseTag':verseTag})
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})
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-03-28 15:56:49 +00:00
u'preview':self.auto_preview_allowed,
2010-03-18 21:50:20 +00:00
u'edit':self.edit_enabled,
u'maintain':self.maintain_allowed,
2010-03-28 15:56:49 +00:00
u'from_plugin':self.from_plugin
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:
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']
self.addIcon(header[u'icon'])
self.raw_footer = header[u'footer']
self.audit = header[u'audit']
2010-03-28 15:56:49 +00:00
self.auto_preview_allowed = header[u'preview']
2010-03-02 19:44:55 +00:00
self.notes = header[u'notes']
2010-03-18 21:50:20 +00:00
self.edit_enabled = header[u'edit']
self.maintain_allowed = header[u'maintain']
2010-03-28 15:56:49 +00:00
self.from_plugin = header[u'from_plugin']
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'])
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
The _uuid is unique for a give 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_song(self):
return self.name.lower() == u'songs'
2009-11-11 19:10:38 +00:00
def is_media(self):
return self.name.lower() == u'media'
2009-11-11 19:10:38 +00:00
def is_command(self):
return self.service_item_type == ServiceItemType.Command
2009-11-11 19:10:38 +00:00
def is_image(self):
return self.service_item_type == ServiceItemType.Image
def uses_file(self):
return self.service_item_type == ServiceItemType.Image or \
self.service_item_type == ServiceItemType.Command
def is_text(self):
return self.service_item_type == ServiceItemType.Text
2009-11-14 08:40:14 +00:00
def get_frames(self):
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:
2009-12-01 17:02:18 +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']
def request_audit(self):
if self.audit:
2010-03-28 15:56:49 +00:00
Receiver.send_message(u'songusage_live', self.audit)