Removed songs as well.

Updated to HEAD.
This commit is contained in:
Raoul Snyman 2010-10-30 09:46:58 +02:00
commit 533ac547cd
30 changed files with 400 additions and 183 deletions

View File

@ -81,9 +81,6 @@ html_expands.append({u'desc':u'Italics', u'start tag':u'{it}',
u'start html':u'<em>', u'end tag':u'{/it}', u'end html':u'</em>', u'start html':u'<em>', u'end tag':u'{/it}', u'end html':u'</em>',
u'protected':True}) u'protected':True})
# Image image_cache to stop regualar image resizing
image_cache = {}
def translate(context, text, comment=None): def translate(context, text, comment=None):
""" """
A special shortcut method to wrap around the Qt4 translation functions. A special shortcut method to wrap around the Qt4 translation functions.
@ -261,20 +258,14 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
return preview return preview
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio, preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation) QtCore.Qt.SmoothTransformation)
image_cache_key = u'%s%s%s' % (image, unicode(width), unicode(height))
if image_cache_key in image_cache:
log.debug(u'resize_image - end cache')
return image_cache[image_cache_key]
realw = preview.width() realw = preview.width()
realh = preview.height() realh = preview.height()
# and move it to the centre of the preview space # and move it to the centre of the preview space
new_image = QtGui.QImage(width, height, new_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
new_image.fill(background)
painter = QtGui.QPainter(new_image) painter = QtGui.QPainter(new_image)
painter.fillRect(new_image.rect(), background)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
image_cache[image_cache_key] = new_image
log.debug(u'resize_image - end')
return new_image return new_image
def check_item_selected(list_widget, message): def check_item_selected(list_widget, message):
@ -314,6 +305,7 @@ def expand_tags(text):
from spelltextedit import SpellTextEdit from spelltextedit import SpellTextEdit
from eventreceiver import Receiver from eventreceiver import Receiver
from imagemanager import ImageManager
from settingsmanager import SettingsManager from settingsmanager import SettingsManager
from plugin import PluginStatus, StringContent, Plugin from plugin import PluginStatus, StringContent, Plugin
from pluginmanager import PluginManager from pluginmanager import PluginManager

View File

@ -117,6 +117,7 @@ class Manager(object):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(plugin_name) settings.beginGroup(plugin_name)
self.db_url = u'' self.db_url = u''
self.is_dirty = False
db_type = unicode( db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite': if db_type == u'sqlite':
@ -150,6 +151,7 @@ class Manager(object):
self.session.add(object_instance) self.session.add(object_instance)
if commit: if commit:
self.session.commit() self.session.commit()
self.is_dirty = True
return True return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
@ -220,6 +222,7 @@ class Manager(object):
try: try:
self.session.delete(object_instance) self.session.delete(object_instance)
self.session.commit() self.session.commit()
self.is_dirty = True
return True return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
@ -241,8 +244,17 @@ class Manager(object):
query = query.filter(filter_clause) query = query.filter(filter_clause)
query.delete(synchronize_session=False) query.delete(synchronize_session=False)
self.session.commit() self.session.commit()
self.is_dirty = True
return True return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Failed to delete %s records', object_class.__name__) log.exception(u'Failed to delete %s records', object_class.__name__)
return False return False
def finalise(self):
"""
VACUUM the database on exit.
"""
if self.is_dirty:
engine = create_engine(self.db_url)
engine.execute("vacuum")

View File

@ -328,6 +328,7 @@ def build_html(item, screen, alert, islive):
height = screen[u'size'].height() height = screen[u'size'].height()
theme = item.themedata theme = item.themedata
webkitvers = webkit_version() webkitvers = webkit_version()
# Image generated and poked in
if item.bg_image_bytes: if item.bg_image_bytes:
image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes
else: else:

View File

@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# 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 #
###############################################################################
"""
Provides the store and management for Images automatically caching them and
resizing them when needed. Only one copy of each image is needed in the system.
A Thread is used to convert the image to a byte array so the user does not need
to wait for the conversion to happen.
"""
import logging
import os
import time
from PyQt4 import QtCore
from openlp.core.lib import resize_image, image_to_byte
log = logging.getLogger(__name__)
class ImageThread(QtCore.QThread):
"""
A special Qt thread class to speed up the display of text based frames.
This is threaded so it loads the frames in background
"""
def __init__(self, manager):
QtCore.QThread.__init__(self, None)
self.image_mamager = manager
def run(self):
"""
Run the thread.
"""
self.image_mamager.process()
class Image(object):
name = ''
path = ''
dirty = True
image = None
image_bytes = None
class ImageManager(QtCore.QObject):
"""
Image Manager handles the conversion and sizing of images.
"""
log.info(u'Image Manager loaded')
def __init__(self):
self._cache = {}
self._thread_running = False
self._cache_dirty = False
self.image_thread = ImageThread(self)
def update_display(self, width, height):
"""
Screen has changed size so rebuild the cache to new size
"""
log.debug(u'update_display')
self.width = width
self.height = height
# mark the images as dirty for a rebuild
for key in self._cache.keys():
image = self._cache[key]
image.dirty = True
fullpath = os.path.join(image.path, image.name)
image.image = resize_image(fullpath,
self.width, self.height)
self._cache_dirty = True
# only one thread please
if not self._thread_running:
self.image_thread.start()
def get_image(self, name):
"""
Return the Qimage from the cache
"""
log.debug(u'get_image %s' % name)
return self._cache[name].image
def get_image_bytes(self, name):
"""
Returns the byte string for an image
If not present wait for the background thread to process it.
"""
log.debug(u'get_image_bytes %s' % name)
if not self._cache[name].image_bytes:
while self._cache[name].dirty:
log.debug(u'get_image_bytes - waiting')
time.sleep(0.1)
return self._cache[name].image_bytes
def add_image(self, name, path):
"""
Add image to cache if it is not already there
"""
log.debug(u'add_image %s:%s' % (name, path))
if not name in self._cache:
image = Image()
image.name = name
image.path = path
image.image = resize_image(path,
self.width, self.height)
self._cache[name] = image
self._cache_dirty = True
# only one thread please
if not self._thread_running:
self.image_thread.start()
def process(self):
"""
Controls the processing called from a QThread
"""
log.debug(u'process - started')
self._thread_running = True
self.clean_cache()
# data loaded since we started ?
while self._cache_dirty:
log.debug(u'process - recycle')
self.clean_cache()
self._thread_running = False
log.debug(u'process - ended')
def clean_cache(self):
"""
Actually does the work.
"""
log.debug(u'clean_cache')
# we will clean the cache now
self._cache_dirty = False
for key in self._cache.keys():
image = self._cache[key]
if image.dirty:
image.image_bytes = image_to_byte(image.image)
image.dirty = False

View File

@ -51,11 +51,6 @@ class Renderer(object):
self._rect = None self._rect = None
self.theme_name = None self.theme_name = None
self._theme = None self._theme = None
self._bg_image_filename = None
self.frame = None
self.bg_frame = None
self.bg_image = None
self.bg_image_bytes = None
def set_theme(self, theme): def set_theme(self, theme):
""" """
@ -66,14 +61,7 @@ class Renderer(object):
""" """
log.debug(u'set theme') log.debug(u'set theme')
self._theme = theme self._theme = theme
self.bg_frame = None
self.bg_image = None
self.bg_image_bytes = None
self._bg_image_filename = None
self.theme_name = theme.theme_name self.theme_name = theme.theme_name
if theme.background_type == u'image':
if theme.background_filename:
self._bg_image_filename = unicode(theme.background_filename)
def set_text_rectangle(self, rect_main, rect_footer): def set_text_rectangle(self, rect_main, rect_footer):
""" """
@ -105,39 +93,6 @@ class Renderer(object):
(build_lyrics_format_css(self._theme, self.page_width, (build_lyrics_format_css(self._theme, self.page_width,
self.page_height), build_lyrics_outline_css(self._theme)) self.page_height), build_lyrics_outline_css(self._theme))
def set_frame_dest(self, frame_width, frame_height):
"""
Set the size of the slide.
``frame_width``
The width of the slide.
``frame_height``
The height of the slide.
"""
log.debug(u'set frame dest (frame) w %d h %d', frame_width,
frame_height)
self.frame = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename and not self.bg_image:
self.bg_image = resize_image(self._bg_image_filename,
self.frame.width(), self.frame.height())
if self._theme.background_type == u'image':
self.bg_frame = QtGui.QImage(self.frame.width(),
self.frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter = QtGui.QPainter()
painter.begin(self.bg_frame)
painter.fillRect(self.frame.rect(), QtCore.Qt.black)
if self.bg_image:
painter.drawImage(0, 0, self.bg_image)
painter.end()
self.bg_image_bytes = image_to_byte(self.bg_frame)
else:
self.bg_frame = None
self.bg_image_bytes = None
def format_slide(self, words, line_break): def format_slide(self, words, line_break):
""" """
Figure out how much text can appear on a slide, using the current Figure out how much text can appear on a slide, using the current

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Renderer, ThemeLevel, ServiceItem from openlp.core.lib import Renderer, ThemeLevel, ServiceItem, ImageManager
from openlp.core.ui import MainDisplay from openlp.core.ui import MainDisplay
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -56,7 +56,9 @@ class RenderManager(object):
""" """
log.debug(u'Initilisation started') log.debug(u'Initilisation started')
self.screens = screens self.screens = screens
self.image_manager = ImageManager()
self.display = MainDisplay(self, screens, False) self.display = MainDisplay(self, screens, False)
self.display.imageManager = self.image_manager
self.display.setup() self.display.setup()
self.theme_manager = theme_manager self.theme_manager = theme_manager
self.renderer = Renderer() self.renderer = Renderer()
@ -75,9 +77,11 @@ class RenderManager(object):
log.debug(u'Update Display') log.debug(u'Update Display')
self.calculate_default(self.screens.current[u'size']) self.calculate_default(self.screens.current[u'size'])
self.display = MainDisplay(self, self.screens, False) self.display = MainDisplay(self, self.screens, False)
self.display.imageManager = self.image_manager
self.display.setup() self.display.setup()
self.renderer.bg_frame = None self.renderer.bg_frame = None
self.themedata = None self.themedata = None
self.image_manager.update_display(self.width, self.height)
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global): def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
""" """
@ -153,7 +157,8 @@ class RenderManager(object):
self.calculate_default(self.screens.current[u'size']) self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata) self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata) self.build_text_rectangle(self.themedata)
self.renderer.set_frame_dest(self.width, self.height) self.image_manager.add_image(self.themedata.theme_name,
self.themedata.background_filename)
return self.renderer._rect, self.renderer._rect_footer return self.renderer._rect, self.renderer._rect_footer
def build_text_rectangle(self, theme): def build_text_rectangle(self, theme):
@ -211,7 +216,7 @@ class RenderManager(object):
serviceItem.raw_footer = footer serviceItem.raw_footer = footer
serviceItem.render(True) serviceItem.render(True)
self.display.buildHtml(serviceItem) self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)[1] raw_html = serviceItem.get_rendered_frame(0)
preview = self.display.text(raw_html) preview = self.display.text(raw_html)
# Reset the real screen size for subsequent render requests # Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size']) self.calculate_default(self.screens.current[u'size'])

View File

@ -30,7 +30,6 @@ type and capability of an item.
import logging import logging
import os import os
import time
import uuid import uuid
from PyQt4 import QtGui from PyQt4 import QtGui
@ -160,12 +159,10 @@ class ServiceItem(object):
theme = self.theme theme = self.theme
self.main, self.footer = \ self.main, self.footer = \
self.render_manager.set_override_theme(theme, useOverride) self.render_manager.set_override_theme(theme, useOverride)
self.bg_image_bytes = self.render_manager.renderer.bg_image_bytes
self.themedata = self.render_manager.renderer._theme self.themedata = self.render_manager.renderer._theme
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides') log.debug(u'Formatting slides')
for slide in self._raw_frames: for slide in self._raw_frames:
before = time.time()
formatted = self.render_manager \ formatted = self.render_manager \
.format_slide(slide[u'raw_slide'], line_break) .format_slide(slide[u'raw_slide'], line_break)
for page in formatted: for page in formatted:
@ -174,12 +171,8 @@ class ServiceItem(object):
u'text': clean_tags(page.rstrip()), u'text': clean_tags(page.rstrip()),
u'html': expand_tags(page.rstrip()), u'html': expand_tags(page.rstrip()),
u'verseTag': slide[u'verseTag'] }) u'verseTag': slide[u'verseTag'] })
log.log(15, u'Formatting took %4s' % (time.time() - before)) elif self.service_item_type == ServiceItemType.Image or \
elif self.service_item_type == ServiceItemType.Image: self.service_item_type == ServiceItemType.Command:
for slide in self._raw_frames:
slide[u'image'] = resize_image(slide[u'image'],
self.render_manager.width, self.render_manager.height)
elif self.service_item_type == ServiceItemType.Command:
pass pass
else: else:
log.error(u'Invalid value renderer :%s' % self.service_item_type) log.error(u'Invalid value renderer :%s' % self.service_item_type)
@ -192,7 +185,7 @@ class ServiceItem(object):
else: else:
self.foot_text = u'%s<br>%s' % (self.foot_text, foot) self.foot_text = u'%s<br>%s' % (self.foot_text, foot)
def add_from_image(self, path, title, image): def add_from_image(self, path, title):
""" """
Add an image slide to the service item. Add an image slide to the service item.
@ -201,13 +194,11 @@ class ServiceItem(object):
``title`` ``title``
A title for the slide in the service item. A title for the slide in the service item.
``image``
The actual image file name.
""" """
self.service_item_type = ServiceItemType.Image self.service_item_type = ServiceItemType.Image
self._raw_frames.append( self._raw_frames.append(
{u'title': title, u'image': image, u'path': path}) {u'title': title, u'path': path})
self.render_manager.image_manager.add_image(title, path)
self._new_item() self._new_item()
def add_from_text(self, title, raw_slide, verse_tag=None): def add_from_text(self, title, raw_slide, verse_tag=None):
@ -241,7 +232,7 @@ class ServiceItem(object):
""" """
self.service_item_type = ServiceItemType.Command self.service_item_type = ServiceItemType.Command
self._raw_frames.append( self._raw_frames.append(
{u'title': file_name, u'image': image, u'path': path}) {u'title': file_name, u'image':image, u'path': path})
self._new_item() self._new_item()
def get_service_repr(self): def get_service_repr(self):
@ -310,8 +301,7 @@ class ServiceItem(object):
elif self.service_item_type == ServiceItemType.Image: elif self.service_item_type == ServiceItemType.Image:
for text_image in serviceitem[u'serviceitem'][u'data']: for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image) filename = os.path.join(path, text_image)
real_image = QtGui.QImage(unicode(filename)) self.add_from_image(filename, text_image)
self.add_from_image(path, text_image, real_image)
elif self.service_item_type == ServiceItemType.Command: elif self.service_item_type == ServiceItemType.Command:
for text_image in serviceitem[u'serviceitem'][u'data']: for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image[u'title']) filename = os.path.join(path, text_image[u'title'])
@ -387,9 +377,11 @@ class ServiceItem(object):
renders it if required. renders it if required.
""" """
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
return None, self._display_frames[row][u'html'].split(u'\n')[0] return self._display_frames[row][u'html'].split(u'\n')[0]
elif self.service_item_type == ServiceItemType.Image:
return self._raw_frames[row][u'title']
else: else:
return self._raw_frames[row][u'image'], u'' return self._raw_frames[row][u'image']
def get_frame_title(self, row=0): def get_frame_title(self, row=0):
""" """

View File

@ -408,6 +408,9 @@ class ThemeXML(object):
elif field in integer_list: elif field in integer_list:
setattr(self, master + field, int(value)) setattr(self, master + field, int(value))
else: else:
# None means an empty string so lets have one.
if value == u'None':
value = u''
setattr(self, master + field, unicode(value)) setattr(self, master + field, unicode(value))
def __str__(self): def __str__(self):

View File

@ -225,7 +225,14 @@ class MainDisplay(DisplayWidget):
shrinkItem.resize(self.screen[u'size'].width(), shrinkItem.resize(self.screen[u'size'].width(),
self.screen[u'size'].height()) self.screen[u'size'].height())
def image(self, image): def directImage(self, name, path):
"""
API for replacement backgrounds so Images are added directly to cache
"""
image = self.imageManager.add_image(name, path)
self.image(name)
def image(self, name):
""" """
Add an image as the background. The image is converted to a Add an image as the background. The image is converted to a
bytestream on route. bytestream on route.
@ -234,24 +241,19 @@ class MainDisplay(DisplayWidget):
The Image to be displayed can be QImage or QPixmap The Image to be displayed can be QImage or QPixmap
""" """
log.debug(u'image to display') log.debug(u'image to display')
if not isinstance(image, QtGui.QImage): image = self.imageManager.get_image_bytes(name)
image = resize_image(image, self.screen[u'size'].width(),
self.screen[u'size'].height())
self.resetVideo() self.resetVideo()
self.displayImage(image) self.displayImage(image)
# show screen # show screen
if self.isLive: if self.isLive:
self.setVisible(True) self.setVisible(True)
return self.preview()
def displayImage(self, image): def displayImage(self, image):
""" """
Display an image, as is. Display an image, as is.
""" """
if image: if image:
if isinstance(image, QtGui.QImage):
js = u'show_image("data:image/png;base64,%s");' % \
image_to_byte(image)
else:
js = u'show_image("data:image/png;base64,%s");' % image js = u'show_image("data:image/png;base64,%s");' % image
else: else:
js = u'show_image("");' js = u'show_image("");'
@ -399,6 +401,9 @@ class MainDisplay(DisplayWidget):
self.loaded = False self.loaded = False
self.initialFrame = False self.initialFrame = False
self.serviceItem = serviceItem self.serviceItem = serviceItem
if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name)
html = build_html(self.serviceItem, self.screen, self.parent.alertTab, html = build_html(self.serviceItem, self.screen, self.parent.alertTab,
self.isLive) self.isLive)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')

View File

@ -73,6 +73,7 @@ class Ui_MainWindow(object):
MainWindow.setSizePolicy(sizePolicy) MainWindow.setSizePolicy(sizePolicy)
MainIcon = build_icon(u':/icon/openlp-logo-16x16.png') MainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
MainWindow.setWindowIcon(MainIcon) MainWindow.setWindowIcon(MainIcon)
self.setDockNestingEnabled(True)
# Set up the main container, which contains all the other form widgets # Set up the main container, which contains all the other form widgets
self.MainContent = QtGui.QWidget(MainWindow) self.MainContent = QtGui.QWidget(MainWindow)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
@ -781,7 +782,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.Save), QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save) QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save: if ret == QtGui.QMessageBox.Save:
self.ServiceManagerContents.onSaveService() self.ServiceManagerContents.onSaveService(True)
self.cleanUp() self.cleanUp()
event.accept() event.accept()
elif ret == QtGui.QMessageBox.Discard: elif ret == QtGui.QMessageBox.Discard:

View File

@ -25,6 +25,7 @@
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
class Ui_ServiceItemEditDialog(object): class Ui_ServiceItemEditDialog(object):
@ -44,16 +45,26 @@ class Ui_ServiceItemEditDialog(object):
self.topLayout.addWidget(self.listWidget) self.topLayout.addWidget(self.listWidget)
self.buttonLayout = QtGui.QVBoxLayout() self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout') self.buttonLayout.setObjectName(u'buttonLayout')
self.upButton = QtGui.QPushButton(self.layoutWidget)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.buttonLayout.addItem(spacerItem)
self.deleteButton = QtGui.QPushButton(self.layoutWidget) self.deleteButton = QtGui.QPushButton(self.layoutWidget)
self.deleteButton.setObjectName(u'deleteButton') self.deleteButton.setObjectName(u'deleteButton')
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.buttonLayout.addItem(spacerItem)
self.upButton = QtGui.QPushButton(self.layoutWidget)
self.upButton.setText(u'')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/services/service_up.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.upButton.setIcon(icon)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(self.layoutWidget) self.downButton = QtGui.QPushButton(self.layoutWidget)
self.downButton.setText(u'')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/services/service_down.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.downButton.setIcon(icon)
self.downButton.setObjectName(u'downButton') self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
self.topLayout.addLayout(self.buttonLayout) self.topLayout.addLayout(self.buttonLayout)
@ -70,7 +81,5 @@ class Ui_ServiceItemEditDialog(object):
def retranslateUi(self, serviceItemEditDialog): def retranslateUi(self, serviceItemEditDialog):
serviceItemEditDialog.setWindowTitle( serviceItemEditDialog.setWindowTitle(
translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item')) translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
self.upButton.setText(translate('OpenLP.ServiceItemEditForm', 'Up'))
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm', self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm',
'Delete')) 'Delete'))
self.downButton.setText(translate('OpenLP.ServiceItemEditForm', 'Down'))

View File

@ -346,7 +346,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item']) self.serviceItems[item][u'service_item'])
if self.serviceItemEditForm.exec_(): if self.serviceItemEditForm.exec_():
self.addServiceItem(self.serviceItemEditForm.getServiceItem(), self.addServiceItem(self.serviceItemEditForm.getServiceItem(),
replace=True, expand=self.serviceItems[item][u'expand']) replace=True, expand=self.serviceItems[item][u'expanded'])
def nextItem(self): def nextItem(self):
""" """
@ -650,6 +650,9 @@ class ServiceManager(QtGui.QWidget):
.get_service_repr()}) .get_service_repr()})
if item[u'service_item'].uses_file(): if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames(): for frame in item[u'service_item'].get_frames():
if item[u'service_item'].is_image():
path_from = frame[u'path']
else:
path_from = unicode(os.path.join( path_from = unicode(os.path.join(
frame[u'path'], frame[u'path'],
frame[u'title'])) frame[u'title']))

View File

@ -26,6 +26,7 @@
import logging import logging
import os import os
import time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
@ -400,6 +401,7 @@ class SlideController(QtGui.QWidget):
log.debug(u'screenSizeChanged live = %s' % self.isLive) log.debug(u'screenSizeChanged live = %s' % self.isLive)
# rebuild display as screen size changed # rebuild display as screen size changed
self.display = MainDisplay(self, self.screens, self.isLive) self.display = MainDisplay(self, self.screens, self.isLive)
self.display.imageManager = self.parent.RenderManager.image_manager
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height()) float(self.screens.current[u'size'].height())
@ -432,8 +434,12 @@ class SlideController(QtGui.QWidget):
request = unicode(self.sender().text()) request = unicode(self.sender().text())
slideno = self.slideList[request] slideno = self.slideList[request]
if slideno > self.PreviewListWidget.rowCount(): if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) self.PreviewListWidget.selectRow(
self.PreviewListWidget.rowCount() - 1)
else: else:
if slideno + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(slideno + 1, 0))
self.PreviewListWidget.selectRow(slideno) self.PreviewListWidget.selectRow(slideno)
self.onSlideSelected() self.onSlideSelected()
@ -525,6 +531,9 @@ class SlideController(QtGui.QWidget):
log.debug(u'addServiceManagerItem live = %s' % self.isLive) log.debug(u'addServiceManagerItem live = %s' % self.isLive)
# If service item is the same as the current on only change slide # If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem): if item.__eq__(self.serviceItem):
if slideno + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(slideno + 1, 0))
self.PreviewListWidget.selectRow(slideno) self.PreviewListWidget.selectRow(slideno)
self.onSlideSelected() self.onSlideSelected()
return return
@ -585,13 +594,14 @@ class SlideController(QtGui.QWidget):
label = QtGui.QLabel() label = QtGui.QLabel()
label.setMargin(4) label.setMargin(4)
label.setScaledContents(True) label.setScaledContents(True)
if isinstance(frame[u'image'], QtGui.QImage): if self.serviceItem.is_command():
label.setPixmap(QtGui.QPixmap.fromImage(frame[u'image'])) image = resize_image(frame[u'image'],
else:
pixmap = resize_image(frame[u'image'],
self.parent.RenderManager.width, self.parent.RenderManager.width,
self.parent.RenderManager.height) self.parent.RenderManager.height)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) else:
image = self.parent.RenderManager.image_manager. \
get_image(frame[u'title'])
label.setPixmap(QtGui.QPixmap.fromImage(image))
self.PreviewListWidget.setCellWidget(framenumber, 0, label) self.PreviewListWidget.setCellWidget(framenumber, 0, label)
slideHeight = width * self.parent.RenderManager.screen_ratio slideHeight = width * self.parent.RenderManager.screen_ratio
row += 1 row += 1
@ -605,8 +615,12 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.setColumnWidth(0, self.PreviewListWidget.setColumnWidth(0,
self.PreviewListWidget.viewport().size().width()) self.PreviewListWidget.viewport().size().width())
if slideno > self.PreviewListWidget.rowCount(): if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) self.PreviewListWidget.selectRow(
self.PreviewListWidget.rowCount() - 1)
else: else:
if slideno + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(slideno + 1, 0))
self.PreviewListWidget.selectRow(slideno) self.PreviewListWidget.selectRow(slideno)
self.enableToolBar(serviceItem) self.enableToolBar(serviceItem)
# Pass to display for viewing # Pass to display for viewing
@ -665,6 +679,9 @@ class SlideController(QtGui.QWidget):
[self.serviceItem, self.isLive, index]) [self.serviceItem, self.isLive, index])
self.updatePreview() self.updatePreview()
else: else:
if index + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(index + 1, 0))
self.PreviewListWidget.selectRow(index) self.PreviewListWidget.selectRow(index)
self.onSlideSelected() self.onSlideSelected()
@ -782,15 +799,12 @@ class SlideController(QtGui.QWidget):
[self.serviceItem, self.isLive, row]) [self.serviceItem, self.isLive, row])
self.updatePreview() self.updatePreview()
else: else:
frame, raw_html = self.serviceItem.get_rendered_frame(row) toDisplay = self.serviceItem.get_rendered_frame(row)
if self.serviceItem.is_text(): if self.serviceItem.is_text():
frame = self.display.text(raw_html) frame = self.display.text(toDisplay)
else: else:
self.display.image(frame) frame = self.display.image(toDisplay)
if isinstance(frame, QtGui.QImage):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
else:
self.SlidePreview.setPixmap(QtGui.QPixmap(frame))
self.selectedRow = row self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row) row)
@ -799,6 +813,9 @@ class SlideController(QtGui.QWidget):
""" """
The slide has been changed. Update the slidecontroller accordingly The slide has been changed. Update the slidecontroller accordingly
""" """
if row + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(row + 1, 0))
self.PreviewListWidget.selectRow(row) self.PreviewListWidget.selectRow(row)
self.updatePreview() self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
@ -844,6 +861,9 @@ class SlideController(QtGui.QWidget):
else: else:
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
return return
if row + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(row + 1, 0))
self.PreviewListWidget.selectRow(row) self.PreviewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()
@ -867,6 +887,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.rowCount() - 1 row = self.PreviewListWidget.rowCount() - 1
else: else:
row = 0 row = 0
if row + 1 < self.PreviewListWidget.rowCount():
self.PreviewListWidget.scrollToItem(
self.PreviewListWidget.item(row + 1, 0))
self.PreviewListWidget.selectRow(row) self.PreviewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()

View File

@ -117,3 +117,11 @@ class AlertsPlugin(Plugin):
self.textStrings[StringContent.VisibleName] = { self.textStrings[StringContent.VisibleName] = {
u'title': translate('AlertsPlugin', 'Alerts') u'title': translate('AlertsPlugin', 'Alerts')
} }
def finalise(self):
"""
Time to tidy up on exit
"""
log.info(u'Alerts Finalising')
self.manager.finalise()
Plugin.finalise(self)

View File

@ -172,3 +172,11 @@ class BiblePlugin(Plugin):
u'tooltip': translate('BiblesPlugin', u'tooltip': translate('BiblesPlugin',
'Add the selected Bible to the service') 'Add the selected Bible to the service')
} }
def finalise(self):
"""
Time to tidy up on exit
"""
log.info(u'Bible Finalising')
self.manager.finalise()
Plugin.finalise(self)

View File

@ -310,3 +310,11 @@ class BibleManager(object):
if bible == name: if bible == name:
return True return True
return False return False
def finalise(self):
"""
Loop through the databases to VACUUM them.
"""
for bible in self.db_cache:
self.db_cache[bible].finalise()

View File

@ -49,8 +49,8 @@ class CustomPlugin(Plugin):
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.3', plugin_helpers) Plugin.__init__(self, u'Custom', u'1.9.3', plugin_helpers)
self.weight = -5 self.weight = -5
self.custommanager = Manager(u'custom', init_schema) self.manager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.custommanager) self.edit_custom_form = EditCustomForm(self.manager)
self.icon_path = u':/plugins/plugin_custom.png' self.icon_path = u':/plugins/plugin_custom.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
@ -59,7 +59,7 @@ class CustomPlugin(Plugin):
return CustomTab(self.name, visible_name[u'title']) return CustomTab(self.name, visible_name[u'title'])
def getMediaManagerItem(self): def getMediaManagerItem(self):
# Create the CustomManagerItem object # Create the ManagerItem object
return CustomMediaItem(self, self, self.icon) return CustomMediaItem(self, self, self.icon)
def about(self): def about(self):
@ -76,7 +76,7 @@ class CustomPlugin(Plugin):
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.custommanager.get_all_objects(CustomSlide, if self.manager.get_all_objects(CustomSlide,
CustomSlide.theme_name == theme): CustomSlide.theme_name == theme):
return True return True
return False return False
@ -92,11 +92,11 @@ class CustomPlugin(Plugin):
``newTheme`` ``newTheme``
The new name the plugin should now use. The new name the plugin should now use.
""" """
customsUsingTheme = self.custommanager.get_all_objects(CustomSlide, customsUsingTheme = self.manager.get_all_objects(CustomSlide,
CustomSlide.theme_name == oldTheme) CustomSlide.theme_name == oldTheme)
for custom in customsUsingTheme: for custom in customsUsingTheme:
custom.theme_name = newTheme custom.theme_name = newTheme
self.custommanager.save_object(custom) self.manager.save_object(custom)
def setPluginTextStrings(self): def setPluginTextStrings(self):
""" """
@ -160,3 +160,11 @@ class CustomPlugin(Plugin):
u'tooltip': translate('CustomsPlugin', u'tooltip': translate('CustomsPlugin',
'Add the selected Custom to the service') 'Add the selected Custom to the service')
} }
def finalise(self):
"""
Time to tidy up on exit
"""
log.info(u'Custom Finalising')
self.manager.finalise()
Plugin.finalise(self)

View File

@ -110,6 +110,7 @@ class Ui_CustomEditDialog(object):
self.titleEdit.setObjectName(u'titleEdit') self.titleEdit.setObjectName(u'titleEdit')
self.horizontalLayout.addWidget(self.titleEdit) self.horizontalLayout.addWidget(self.titleEdit)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.retranslateUi(customEditDialog) self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customEditDialog.accept) customEditDialog.accept)

View File

@ -41,7 +41,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Class documentation goes here. Class documentation goes here.
""" """
log.info(u'Custom Editor loaded') log.info(u'Custom Editor loaded')
def __init__(self, custommanager, parent=None): def __init__(self, manager, parent=None):
""" """
Constructor Constructor
""" """
@ -74,7 +74,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms. # Create other objects and forms.
self.custommanager = custommanager self.manager = manager
self.editSlideForm = EditCustomSlideForm(self) self.editSlideForm = EditCustomSlideForm(self)
self.initialise() self.initialise()
@ -115,7 +115,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.customSlide = CustomSlide() self.customSlide = CustomSlide()
self.initialise() self.initialise()
if id != 0: if id != 0:
self.customSlide = self.custommanager.get_object(CustomSlide, id) self.customSlide = self.manager.get_object(CustomSlide, id)
self.titleEdit.setText(self.customSlide.title) self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits) self.creditEdit.setText(self.customSlide.credits)
customXML = CustomXMLParser(self.customSlide.text) customXML = CustomXMLParser(self.customSlide.text)
@ -162,13 +162,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
sxml.add_verse_to_lyrics(u'custom', unicode(count), sxml.add_verse_to_lyrics(u'custom', unicode(count),
unicode(self.slideListView.item(i).text())) unicode(self.slideListView.item(i).text()))
count += 1 count += 1
self.customSlide.title = unicode(self.titleEdit.displayText(), u'utf-8') self.customSlide.title = unicode(self.titleEdit.text())
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8') self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
self.customSlide.credits = unicode(self.creditEdit.displayText(), self.customSlide.credits = unicode(self.creditEdit.text())
u'utf-8') self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
self.customSlide.theme_name = unicode(self.themeComboBox.currentText(), return self.manager.save_object(self.customSlide)
u'utf-8')
return self.custommanager.save_object(self.customSlide)
def onUpButtonPressed(self): def onUpButtonPressed(self):
selectedRow = self.slideListView.currentRow() selectedRow = self.slideListView.currentRow()

View File

@ -56,6 +56,7 @@ class CustomMediaItem(MediaManagerItem):
# Holds information about whether the edit is remotly triggered and # Holds information about whether the edit is remotly triggered and
# which Custom is required. # which Custom is required.
self.remoteCustom = -1 self.remoteCustom = -1
self.manager = parent.manager
def addEndHeaderBar(self): def addEndHeaderBar(self):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -71,7 +72,7 @@ class CustomMediaItem(MediaManagerItem):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
def initialise(self): def initialise(self):
self.loadCustomListView(self.parent.custommanager.get_all_objects( self.loadCustomListView(self.manager.get_all_objects(
CustomSlide, order_by_ref=CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
#Called to redisplay the song list screen edith from a search #Called to redisplay the song list screen edith from a search
#or from the exit of the Song edit dialog. If remote editing is active #or from the exit of the Song edit dialog. If remote editing is active
@ -106,7 +107,7 @@ class CustomMediaItem(MediaManagerItem):
type of display is required. type of display is required.
""" """
fields = customid.split(u':') fields = customid.split(u':')
valid = self.parent.custommanager.get_object(CustomSlide, fields[1]) valid = self.manager.get_object(CustomSlide, fields[1])
if valid: if valid:
self.remoteCustom = fields[1] self.remoteCustom = fields[1]
self.remoteTriggered = fields[0] self.remoteTriggered = fields[0]
@ -139,7 +140,7 @@ class CustomMediaItem(MediaManagerItem):
id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0] id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]
for item in self.listView.selectedIndexes()] for item in self.listView.selectedIndexes()]
for id in id_list: for id in id_list:
self.parent.custommanager.delete_object(CustomSlide, id) self.parent.manager.delete_object(CustomSlide, id)
for row in row_list: for row in row_list:
self.listView.takeItem(row) self.listView.takeItem(row)
@ -161,7 +162,7 @@ class CustomMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
customSlide = self.parent.custommanager.get_object(CustomSlide, item_id) customSlide = self.parent.manager.get_object(CustomSlide, item_id)
title = customSlide.title title = customSlide.title
credit = customSlide.credits credit = customSlide.credits
service_item.editId = item_id service_item.editId = item_id

View File

@ -166,9 +166,8 @@ class ImageMediaItem(MediaManagerItem):
for item in items: for item in items:
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString()) filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
frame = QtGui.QImage(unicode(filename))
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
service_item.add_from_image(path, name, frame) service_item.add_from_image(filename, name)
return True return True
else: else:
return False return False
@ -185,7 +184,8 @@ class ImageMediaItem(MediaManagerItem):
for item in items: for item in items:
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString()) filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
self.parent.liveController.display.image(filename) (path, name) = os.path.split(filename)
self.parent.liveController.display.directImage(name, filename)
self.resetButton.setVisible(True) self.resetButton.setVisible(True)
def onPreviewClick(self): def onPreviewClick(self):

View File

@ -56,7 +56,7 @@ class MediaMediaItem(MediaManagerItem):
u':/media/media_video.png').toImage() u':/media/media_video.png').toImage()
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False self.singleServiceItem = False
self.serviceItemIconName = u':/media/media_video.png' self.serviceItemIconName = u':/media/image_clapperboard.png'
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')

View File

@ -199,3 +199,11 @@ class SongsPlugin(Plugin):
u'tooltip': translate('SongsPlugin', u'tooltip': translate('SongsPlugin',
'Add the selected Song to the service') 'Add the selected Song to the service')
} }
def finalise(self):
"""
Time to tidy up on exit
"""
log.info(u'Songs Finalising')
self.manager.finalise()
Plugin.finalise(self)

View File

@ -34,11 +34,11 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
""" """
Class documentation goes here. Class documentation goes here.
""" """
def __init__(self, songusagemanager, parent): def __init__(self, manager, parent):
""" """
Constructor Constructor
""" """
self.songusagemanager = songusagemanager self.manager = manager
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
@ -53,6 +53,6 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
QtGui.QMessageBox.Cancel) QtGui.QMessageBox.Cancel)
if ret == QtGui.QMessageBox.Ok: if ret == QtGui.QMessageBox.Ok:
deleteDate = self.deleteCalendar.selectedDate().toPyDate() deleteDate = self.deleteCalendar.selectedDate().toPyDate()
self.songusagemanager.delete_all_objects(SongUsageItem, self.manager.delete_all_objects(SongUsageItem,
SongUsageItem.usagedate <= deleteDate) SongUsageItem.usagedate <= deleteDate)
self.close() self.close()

View File

@ -76,7 +76,7 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
filename = u'usage_detail_%s_%s.txt' % ( filename = u'usage_detail_%s_%s.txt' % (
self.fromDate.selectedDate().toString(u'ddMMyyyy'), self.fromDate.selectedDate().toString(u'ddMMyyyy'),
self.toDate.selectedDate().toString(u'ddMMyyyy')) self.toDate.selectedDate().toString(u'ddMMyyyy'))
usage = self.plugin.songusagemanager.get_all_objects( usage = self.plugin.manager.get_all_objects(
SongUsageItem, and_( SongUsageItem, and_(
SongUsageItem.usagedate >= self.fromDate.selectedDate().toPyDate(), SongUsageItem.usagedate >= self.fromDate.selectedDate().toPyDate(),
SongUsageItem.usagedate < self.toDate.selectedDate().toPyDate()), SongUsageItem.usagedate < self.toDate.selectedDate().toPyDate()),

View File

@ -44,7 +44,7 @@ class SongUsagePlugin(Plugin):
Plugin.__init__(self, u'SongUsage', u'1.9.3', plugin_helpers) Plugin.__init__(self, u'SongUsage', u'1.9.3', plugin_helpers)
self.weight = -4 self.weight = -4
self.icon = build_icon(u':/plugins/plugin_songusage.png') self.icon = build_icon(u':/plugins/plugin_songusage.png')
self.songusagemanager = None self.manager = None
self.songusageActive = False self.songusageActive = False
def addToolsMenuItem(self, tools_menu): def addToolsMenuItem(self, tools_menu):
@ -115,9 +115,9 @@ class SongUsagePlugin(Plugin):
self.settingsSection + u'/active', self.settingsSection + u'/active',
QtCore.QVariant(False)).toBool() QtCore.QVariant(False)).toBool()
self.SongUsageStatus.setChecked(self.SongUsageActive) self.SongUsageStatus.setChecked(self.SongUsageActive)
if self.songusagemanager is None: if self.manager is None:
self.songusagemanager = Manager(u'songusage', init_schema) self.manager = Manager(u'songusage', init_schema)
self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager, self.SongUsagedeleteform = SongUsageDeleteForm(self.manager,
self.formparent) self.formparent)
self.SongUsagedetailform = SongUsageDetailForm(self, self.formparent) self.SongUsagedetailform = SongUsageDetailForm(self, self.formparent)
self.SongUsageMenu.menuAction().setVisible(True) self.SongUsageMenu.menuAction().setVisible(True)
@ -148,7 +148,7 @@ class SongUsagePlugin(Plugin):
song_usage_item.authors = u'' song_usage_item.authors = u''
for author in audit[1]: for author in audit[1]:
song_usage_item.authors += author + u' ' song_usage_item.authors += author + u' '
self.songusagemanager.save_object(song_usage_item) self.manager.save_object(song_usage_item)
def onSongUsageDelete(self): def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_() self.SongUsagedeleteform.exec_()
@ -176,3 +176,11 @@ class SongUsagePlugin(Plugin):
self.textStrings[StringContent.VisibleName] = { self.textStrings[StringContent.VisibleName] = {
u'title': translate('SongUsagePlugin', 'SongUsage') u'title': translate('SongUsagePlugin', 'SongUsage')
} }
def finalise(self):
"""
Time to tidy up on exit
"""
log.info(u'SongUsage Finalising')
self.manager.finalise()
Plugin.finalise(self)

View File

@ -35,9 +35,9 @@
<item> <item>
<layout class="QVBoxLayout" name="buttonLayout"> <layout class="QVBoxLayout" name="buttonLayout">
<item> <item>
<widget class="QPushButton" name="upButton"> <widget class="QPushButton" name="deleteButton">
<property name="text"> <property name="text">
<string>Up</string> <string>Delete</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -55,16 +55,24 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QPushButton" name="deleteButton"> <widget class="QPushButton" name="upButton">
<property name="text"> <property name="text">
<string>Delete</string> <string/>
</property>
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/services/service_up.png</normaloff>:/services/service_up.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="downButton"> <widget class="QPushButton" name="downButton">
<property name="text"> <property name="text">
<string>Down</string> <string/>
</property>
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/services/service_down.png</normaloff>:/services/service_down.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -82,6 +90,8 @@
</layout> </layout>
</widget> </widget>
</widget> </widget>
<resources/> <resources>
<include location="../images/openlp-2.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

Binary file not shown.