This commit is contained in:
M2j 2010-06-30 12:26:46 +02:00
commit 83f1d7164d
154 changed files with 52954 additions and 7895 deletions

View File

@ -16,3 +16,5 @@ build
resources/innosetup/Output resources/innosetup/Output
_eric4project _eric4project
.pylint.d .pylint.d
*.qm
openlp/core/resources.py.old

View File

@ -1,6 +1,8 @@
recursive-include openlp *.py recursive-include openlp *.py
recursive-include openlp *.sqlite recursive-include openlp *.sqlite
recursive-include openlp *.csv recursive-include openlp *.csv
recursive-include openlp *.html
recursive-include openlp *.js
recursive-include documentation * recursive-include documentation *
recursive-include resources/forms * recursive-include resources/forms *
recursive-include resources/i18n * recursive-include resources/i18n *

View File

@ -163,7 +163,7 @@ def main():
parser.add_option("-s", "--style", dest="style", parser.add_option("-s", "--style", dest="style",
help="Set the Qt4 style (passed directly to Qt4).") help="Set the Qt4 style (passed directly to Qt4).")
# Set up logging # Set up logging
log_path = AppLocation.get_directory(AppLocation.ConfigDir) log_path = AppLocation.get_directory(AppLocation.CacheDir)
if not os.path.exists(log_path): if not os.path.exists(log_path):
os.makedirs(log_path) os.makedirs(log_path)
filename = os.path.join(log_path, u'openlp.log') filename = os.path.join(log_path, u'openlp.log')

View File

@ -1 +1 @@
1.9.1-bzr821 1.9.2

View File

@ -22,7 +22,6 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
""" """
The :mod:`lib` module contains most of the components and libraries that make The :mod:`lib` module contains most of the components and libraries that make
OpenLP work. OpenLP work.
@ -49,7 +48,8 @@ def translate(context, text, comment=None, count=-1):
The text to put into the translation tables for translation. The text to put into the translation tables for translation.
``comment`` ``comment``
A optional comment for translators. An identifying string for when the same text is used in different roles
within the same context.
``count`` ``count``
If count is given it replaces %n in the text. A propper plural form is If count is given it replaces %n in the text. A propper plural form is
@ -122,6 +122,18 @@ def build_icon(icon):
def context_menu_action(base, icon, text, slot): def context_menu_action(base, icon, text, slot):
""" """
Utility method to help build context menus for plugins Utility method to help build context menus for plugins
``base``
The parent menu to add this menu item to
``icon``
An icon for this action
``text``
The text to display for this action
``slot``
The code to run when this action is triggered
""" """
action = QtGui.QAction(text, base) action = QtGui.QAction(text, base)
if icon: if icon:
@ -132,6 +144,15 @@ def context_menu_action(base, icon, text, slot):
def context_menu(base, icon, text): def context_menu(base, icon, text):
""" """
Utility method to help build context menus for plugins Utility method to help build context menus for plugins
``base``
The parent object to add this menu to
``icon``
An icon for this menu
``text``
The text to display for this menu
""" """
action = QtGui.QMenu(text, base) action = QtGui.QMenu(text, base)
action.setIcon(build_icon(icon)) action.setIcon(build_icon(icon))
@ -140,6 +161,9 @@ def context_menu(base, icon, text):
def context_menu_separator(base): def context_menu_separator(base):
""" """
Add a separator to a context menu Add a separator to a context menu
``base``
The menu object to add the separator to
""" """
action = QtGui.QAction(u'', base) action = QtGui.QAction(u'', base)
action.setSeparator(True) action.setSeparator(True)
@ -166,6 +190,22 @@ def resize_image(image, width, height):
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
return new_image return new_image
def check_item_selected(list_widget, message):
"""
Check if a list item is selected so an action may be performed on it
``list_widget``
The list to check for selected items
``message``
The message to give the user if no item is selected
"""
if not list_widget.selectedIndexes():
QtGui.QMessageBox.information(list_widget.parent(),
translate('MediaManagerItem', 'No Items Selected'), message)
return False
return True
class ThemeLevel(object): class ThemeLevel(object):
""" """
@ -191,5 +231,4 @@ from themexmlhandler import ThemeXML
from renderer import Renderer from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem
from basemodel import BaseModel
from baselistwithdnd import BaseListWithDnD from baselistwithdnd import BaseListWithDnD

View File

@ -22,17 +22,20 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Extend QListWidget to handle drag and drop functionality
"""
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class BaseListWithDnD(QtGui.QListWidget): class BaseListWithDnD(QtGui.QListWidget):
""" """
Please put a short description of what this class does in here. Provide a list widget to store objects and handle drag and drop events
""" """
def __init__(self, parent=None): def __init__(self, parent=None):
"""
Initialise the list widget
"""
QtGui.QListWidget.__init__(self, parent) QtGui.QListWidget.__init__(self, parent)
self.parent = parent
# this must be set by the class which is inheriting # this must be set by the class which is inheriting
assert(self.PluginName) assert(self.PluginName)

View File

@ -1,40 +0,0 @@
# -*- 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, 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 #
###############################################################################
class BaseModel(object):
"""
BaseModel provides a base object with a set of generic functions
"""
@classmethod
def populate(cls, **kwargs):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
for key in kwargs:
me.__setattr__(key, kwargs[key])
return me

245
openlp/core/lib/db.py Normal file
View File

@ -0,0 +1,245 @@
# -*- 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, 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 #
###############################################################################
"""
The :mod:`db` module provides the core database functionality for OpenLP
"""
import logging
import os
from PyQt4 import QtCore
from sqlalchemy import create_engine, MetaData
from sqlalchemy.exceptions import InvalidRequestError
from sqlalchemy.orm import scoped_session, sessionmaker
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
def init_db(url, auto_flush=True, auto_commit=False):
"""
Initialise and return the session and metadata for a database
``url``
The database to initialise connection with
``auto_flush``
Sets the flushing behaviour of the session
``auto_commit``
Sets the commit behaviour of the session
"""
engine = create_engine(url)
metadata = MetaData(bind=engine)
session = scoped_session(sessionmaker(autoflush=auto_flush,
autocommit=auto_commit, bind=engine))
return session, metadata
def delete_database(plugin_name, db_file_name=None):
"""
Remove a database file from the system.
``plugin_name``
The name of the plugin to remove the database for
``db_file_name``
The database file name. Defaults to None resulting in the
plugin_name being used.
"""
db_file_path = None
if db_file_name:
db_file_path = os.path.join(
AppLocation.get_section_data_path(plugin_name), db_file_name)
else:
db_file_path = os.path.join(
AppLocation.get_section_data_path(plugin_name), plugin_name)
try:
os.remove(db_file_path)
return True
except OSError:
return False
class BaseModel(object):
"""
BaseModel provides a base object with a set of generic functions
"""
@classmethod
def populate(cls, **kwargs):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
for key in kwargs:
me.__setattr__(key, kwargs[key])
return me
class Manager(object):
"""
Provide generic object persistence management
"""
def __init__(self, plugin_name, init_schema, db_file_name=None):
"""
Runs the initialisation process that includes creating the connection
to the database and the tables if they don't exist.
``plugin_name``
The name to setup paths and settings section names
``init_schema``
The init_schema function for this database
``db_file_name``
The file name to use for this database. Defaults to None resulting
in the plugin_name being used.
"""
settings = QtCore.QSettings()
settings.beginGroup(plugin_name)
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
if db_file_name:
self.db_url = u'sqlite:///%s/%s' % (
AppLocation.get_section_data_path(plugin_name),
db_file_name)
else:
self.db_url = u'sqlite:///%s/%s.sqlite' % (
AppLocation.get_section_data_path(plugin_name), plugin_name)
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_schema(self.db_url)
def save_object(self, object_instance):
"""
Save an object to the database
``object_instance``
The object to save
"""
try:
self.session.add(object_instance)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Object save failed')
return False
def get_object(self, object_class, key=None):
"""
Return the details of an object
``object_class``
The type of object to return
``key``
The unique reference or primary key for the instance to return
"""
if not key:
return object_class()
else:
return self.session.query(object_class).get(key)
def get_object_filtered(self, object_class, filter_string):
"""
Returns an object matching specified criteria
``object_class``
The type of object to return
``filter_string``
The criteria to select the object by
"""
return self.session.query(object_class).filter(filter_string).first()
def get_all_objects(self, object_class, order_by_ref=None):
"""
Returns all the objects from the database
``object_class``
The type of objects to return
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
"""
if order_by_ref:
return self.session.query(object_class).order_by(order_by_ref).all()
return self.session.query(object_class).all()
def get_all_objects_filtered(self, object_class, filter_string):
"""
Returns a selection of objects from the database
``object_class``
The type of objects to return
``filter_string``
The filter governing selection of objects to return
"""
return self.session.query(object_class).filter(filter_string).all()
def delete_object(self, object_class, key):
"""
Delete an object from the database
``object_class``
The type of object to delete
``key``
The unique reference or primary key for the instance to be deleted
"""
if key != 0:
object_instance = self.get_object(object_class, key)
try:
self.session.delete(object_instance)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete object')
return False
else:
return True
def delete_all_objects(self, object_class):
"""
Delete all object records
``object_class``
The type of object to delete
"""
try:
self.session.query(object_class).delete(synchronize_session=False)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete all %s records',
object_class.__name__)
return False

View File

@ -22,7 +22,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide additional functionality required by OpenLP from the inherited
QDockWidget.
"""
import logging import logging
from PyQt4 import QtGui from PyQt4 import QtGui

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide event handling code for OpenLP
"""
import logging import logging
from PyQt4 import QtCore from PyQt4 import QtCore
@ -241,7 +243,11 @@ class Receiver(object):
``Receiver.send_message(u'<<Message ID>>', data)`` ``Receiver.send_message(u'<<Message ID>>', data)``
To receive a Message To receive a Message
``QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'<<Message ID>>'), <<ACTION>>)`` ``QtCore.QObject.connect(
Receiver.get_receiver(),
QtCore.SIGNAL(u'<<Message ID>>'),
<<ACTION>>
)``
""" """
eventreceiver = EventReceiver() eventreceiver = EventReceiver()

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provides the generic functions for interfacing plugins with the Media Manager.
"""
import logging import logging
import os import os
@ -204,44 +206,46 @@ class MediaManagerItem(QtGui.QWidget):
self.addListViewToToolBar() self.addListViewToToolBar()
def addMiddleHeaderBar(self): def addMiddleHeaderBar(self):
# Create buttons for the toolbar """
Create buttons for the media item toolbar
"""
## Import Button ## ## Import Button ##
if self.hasImportIcon: if self.hasImportIcon:
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Import %s')) % \ unicode(translate('MediaManagerItem', 'Import %s')) %
self.PluginNameShort, self.PluginNameShort,
unicode(translate('MediaManagerItem', 'Import a %s')) % \ unicode(translate('MediaManagerItem', 'Import a %s')) %
self.PluginNameVisible, self.PluginNameVisible,
u':/general/general_import.png', self.onImportClick) u':/general/general_import.png', self.onImportClick)
## File Button ## ## File Button ##
if self.hasFileIcon: if self.hasFileIcon:
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Load %s')) % \ unicode(translate('MediaManagerItem', 'Load %s')) %
self.PluginNameShort, self.PluginNameShort,
unicode(translate('MediaManagerItem', 'Load a new %s')) % \ unicode(translate('MediaManagerItem', 'Load a new %s')) %
self.PluginNameVisible, self.PluginNameVisible,
u':/general/general_open.png', self.onFileClick) u':/general/general_open.png', self.onFileClick)
## New Button ## ## New Button ##
if self.hasNewIcon: if self.hasNewIcon:
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'New %s')) % \ unicode(translate('MediaManagerItem', 'New %s')) %
self.PluginNameShort, self.PluginNameShort,
unicode(translate('MediaManagerItem', 'Add a new %s')) % \ unicode(translate('MediaManagerItem', 'Add a new %s')) %
self.PluginNameVisible, self.PluginNameVisible,
u':/general/general_new.png', self.onNewClick) u':/general/general_new.png', self.onNewClick)
## Edit Button ## ## Edit Button ##
if self.hasEditIcon: if self.hasEditIcon:
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Edit %s')) % \ unicode(translate('MediaManagerItem', 'Edit %s')) %
self.PluginNameShort, self.PluginNameShort,
unicode(translate( unicode(translate(
'MediaManagerItem', 'Edit the selected %s')) % \ 'MediaManagerItem', 'Edit the selected %s')) %
self.PluginNameVisible, self.PluginNameVisible,
u':/general/general_edit.png', self.onEditClick) u':/general/general_edit.png', self.onEditClick)
## Delete Button ## ## Delete Button ##
if self.hasDeleteIcon: if self.hasDeleteIcon:
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Delete %s')) % \ unicode(translate('MediaManagerItem', 'Delete %s')) %
self.PluginNameShort, self.PluginNameShort,
translate('MediaManagerItem', 'Delete the selected item'), translate('MediaManagerItem', 'Delete the selected item'),
u':/general/general_delete.png', self.onDeleteClick) u':/general/general_delete.png', self.onDeleteClick)
@ -249,7 +253,7 @@ class MediaManagerItem(QtGui.QWidget):
self.addToolbarSeparator() self.addToolbarSeparator()
## Preview ## ## Preview ##
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Preview %s')) % \ unicode(translate('MediaManagerItem', 'Preview %s')) %
self.PluginNameShort, self.PluginNameShort,
translate('MediaManagerItem', 'Preview the selected item'), translate('MediaManagerItem', 'Preview the selected item'),
u':/general/general_preview.png', self.onPreviewClick) u':/general/general_preview.png', self.onPreviewClick)
@ -260,13 +264,16 @@ class MediaManagerItem(QtGui.QWidget):
u':/general/general_live.png', self.onLiveClick) u':/general/general_live.png', self.onLiveClick)
## Add to service Button ## ## Add to service Button ##
self.addToolbarButton( self.addToolbarButton(
unicode(translate('MediaManagerItem', 'Add %s to Service')) % \ unicode(translate('MediaManagerItem', 'Add %s to Service')) %
self.PluginNameShort, self.PluginNameShort,
translate('MediaManagerItem', translate('MediaManagerItem',
'Add the selected item(s) to the service'), 'Add the selected item(s) to the service'),
u':/general/general_add.png', self.onAddClick) u':/general/general_add.png', self.onAddClick)
def addListViewToToolBar(self): def addListViewToToolBar(self):
"""
Creates the main widget for listing items the media item is tracking
"""
#Add the List widget #Add the List widget
self.ListView = self.ListViewWithDnD_class(self) self.ListView = self.ListViewWithDnD_class(self)
self.ListView.uniformItemSizes = True self.ListView.uniformItemSizes = True
@ -285,7 +292,7 @@ class MediaManagerItem(QtGui.QWidget):
self.ListView.addAction( self.ListView.addAction(
context_menu_action( context_menu_action(
self.ListView, u':/general/general_edit.png', self.ListView, u':/general/general_edit.png',
unicode(translate('MediaManagerItem', '&Edit %s')) % \ unicode(translate('MediaManagerItem', '&Edit %s')) %
self.PluginNameVisible, self.PluginNameVisible,
self.onEditClick)) self.onEditClick))
self.ListView.addAction(context_menu_separator(self.ListView)) self.ListView.addAction(context_menu_separator(self.ListView))
@ -293,14 +300,14 @@ class MediaManagerItem(QtGui.QWidget):
self.ListView.addAction( self.ListView.addAction(
context_menu_action( context_menu_action(
self.ListView, u':/general/general_delete.png', self.ListView, u':/general/general_delete.png',
unicode(translate('MediaManagerItem', '&Delete %s')) % \ unicode(translate('MediaManagerItem', '&Delete %s')) %
self.PluginNameVisible, self.PluginNameVisible,
self.onDeleteClick)) self.onDeleteClick))
self.ListView.addAction(context_menu_separator(self.ListView)) self.ListView.addAction(context_menu_separator(self.ListView))
self.ListView.addAction( self.ListView.addAction(
context_menu_action( context_menu_action(
self.ListView, u':/general/general_preview.png', self.ListView, u':/general/general_preview.png',
unicode(translate('MediaManagerItem', '&Preview %s')) % \ unicode(translate('MediaManagerItem', '&Preview %s')) %
self.PluginNameVisible, self.PluginNameVisible,
self.onPreviewClick)) self.onPreviewClick))
self.ListView.addAction( self.ListView.addAction(
@ -343,20 +350,10 @@ class MediaManagerItem(QtGui.QWidget):
""" """
pass pass
def checkItemSelected(self, message):
"""
Check if a list item is selected so an action may be performed on it
``message``
The message to give the user if no item is selected
"""
if not self.ListView.selectedIndexes():
QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'No Items Selected'), message)
return False
return True
def onFileClick(self): def onFileClick(self):
"""
Add a file to the list widget to make it available for showing
"""
files = QtGui.QFileDialog.getOpenFileNames( files = QtGui.QFileDialog.getOpenFileNames(
self, self.OnNewPrompt, self, self.OnNewPrompt,
SettingsManager.get_last_dir(self.settingsSection), SettingsManager.get_last_dir(self.settingsSection),
@ -370,6 +367,9 @@ class MediaManagerItem(QtGui.QWidget):
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())
def getFileList(self): def getFileList(self):
"""
Return the current list of files
"""
count = 0 count = 0
filelist = [] filelist = []
while count < self.ListView.count(): while count < self.ListView.count():
@ -393,6 +393,15 @@ class MediaManagerItem(QtGui.QWidget):
return False return False
def IconFromFile(self, file, thumb): def IconFromFile(self, file, thumb):
"""
Create a thumbnail icon from a given file
``file``
The file to create the icon from
``thumb``
The filename to save the thumbnail to
"""
icon = build_icon(unicode(file)) icon = build_icon(unicode(file))
pixmap = icon.pixmap(QtCore.QSize(88, 50)) pixmap = icon.pixmap(QtCore.QSize(88, 50))
ext = os.path.splitext(thumb)[1].lower() ext = os.path.splitext(thumb)[1].lower()
@ -420,6 +429,10 @@ class MediaManagerItem(QtGui.QWidget):
u'to be defined by the plugin') u'to be defined by the plugin')
def onPreviewClick(self): def onPreviewClick(self):
"""
Preview an item by building a service item then adding that service
item to the preview slide controller.
"""
if not self.ListView.selectedIndexes() and not self.remoteTriggered: if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'No Items Selected'), translate('MediaManagerItem', 'No Items Selected'),
@ -433,6 +446,10 @@ class MediaManagerItem(QtGui.QWidget):
self.parent.preview_controller.addServiceItem(service_item) self.parent.preview_controller.addServiceItem(service_item)
def onLiveClick(self): def onLiveClick(self):
"""
Send an item live by building a service item then adding that service
item to the live slide controller.
"""
if not self.ListView.selectedIndexes(): if not self.ListView.selectedIndexes():
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'No Items Selected'), translate('MediaManagerItem', 'No Items Selected'),
@ -446,6 +463,9 @@ class MediaManagerItem(QtGui.QWidget):
self.parent.live_controller.addServiceItem(service_item) self.parent.live_controller.addServiceItem(service_item)
def onAddClick(self): def onAddClick(self):
"""
Add a selected item to the current service
"""
if not self.ListView.selectedIndexes() and not self.remoteTriggered: if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'No Items Selected'), translate('MediaManagerItem', 'No Items Selected'),
@ -470,6 +490,9 @@ class MediaManagerItem(QtGui.QWidget):
self.parent.service_manager.addServiceItem(service_item) self.parent.service_manager.addServiceItem(service_item)
def onAddEditClick(self): def onAddEditClick(self):
"""
Add a selected item to an existing item in the current service.
"""
if not self.ListView.selectedIndexes() and not self.remoteTriggered: if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'No items selected'), translate('MediaManagerItem', 'No items selected'),
@ -491,7 +514,7 @@ class MediaManagerItem(QtGui.QWidget):
#Turn off the remote edit update message indicator #Turn off the remote edit update message indicator
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('MediaManagerItem', 'Invalid Service Item'), translate('MediaManagerItem', 'Invalid Service Item'),
translate(unicode('MediaManagerItem', unicode(translate('MediaManagerItem',
'You must select a %s service item.')) % self.title) 'You must select a %s service item.')) % self.title)
def buildServiceItem(self, item=None): def buildServiceItem(self, item=None):

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide the generic plugin functionality for OpenLP plugins.
"""
import logging import logging
from PyQt4 import QtCore from PyQt4 import QtCore

View File

@ -22,7 +22,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`renderer` module enables OpenLP to take the input from plugins and
format it for the output display.
"""
import logging import logging
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore

View File

@ -90,7 +90,7 @@ class ServiceItem(object):
self.from_plugin = False self.from_plugin = False
self.capabilities = [] self.capabilities = []
self.is_valid = True self.is_valid = True
self.cache = [] self.cache = {}
self.icon = None self.icon = None
def add_capability(self, capability): def add_capability(self, capability):
@ -129,7 +129,7 @@ class ServiceItem(object):
""" """
log.debug(u'Render called') log.debug(u'Render called')
self._display_frames = [] self._display_frames = []
self.cache = [] self.clear_cache()
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides') log.debug(u'Formatting slides')
if self.theme is None: if self.theme is None:
@ -149,7 +149,8 @@ class ServiceItem(object):
self._display_frames.append({u'title': title, self._display_frames.append({u'title': title,
u'text': lines.rstrip(), u'text': lines.rstrip(),
u'verseTag': slide[u'verseTag'] }) u'verseTag': slide[u'verseTag'] })
self.cache.insert(len(self._display_frames), None) if len(self._display_frames) in self.cache.keys():
del self.cache[len(self._display_frames)]
log.log(15, u'Formatting took %4s' % (time.time() - before)) log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image: elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames: for slide in self._raw_frames:
@ -172,8 +173,7 @@ class ServiceItem(object):
else: else:
self.render_manager.set_override_theme(self.theme) self.render_manager.set_override_theme(self.theme)
format = self._display_frames[row][u'text'].split(u'\n') format = self._display_frames[row][u'text'].split(u'\n')
#if screen blank then do not display footer if self.cache.get(row):
if len(self.cache) > 0 and self.cache[row] is not None:
frame = self.cache[row] frame = self.cache[row]
else: else:
if format[0]: if format[0]:
@ -304,7 +304,7 @@ class ServiceItem(object):
def merge(self, other): def merge(self, other):
""" """
Updates the _uuid with the value from the original one Updates the _uuid with the value from the original one
The _uuid is unique for a give service item but this allows one to The _uuid is unique for a given service item but this allows one to
replace an original version. replace an original version.
""" """
self._uuid = other._uuid self._uuid = other._uuid
@ -385,3 +385,8 @@ class ServiceItem(object):
""" """
return self._raw_frames[row][u'path'] return self._raw_frames[row][u'path']
def clear_cache(self):
"""
Clear's the service item's cache.
"""
self.cache = {}

View File

@ -22,7 +22,12 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide handling for persisting OpenLP settings. OpenLP uses QSettings to
manage settings persistence. QSettings provides a single API for saving and
retrieving settings from the application but writes to disk in an OS dependant
format.
"""
import os import os
from PyQt4 import QtCore from PyQt4 import QtCore
@ -56,6 +61,9 @@ class SettingsManager(object):
u'user interface/preview panel', QtCore.QVariant(True)).toBool() u'user interface/preview panel', QtCore.QVariant(True)).toBool()
def togglePreviewPanel(self, isVisible): def togglePreviewPanel(self, isVisible):
"""
Toggle the preview panel visibility.
"""
QtCore.QSettings().setValue(u'user interface/preview panel', QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(isVisible)) QtCore.QVariant(isVisible))

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide the theme XML and handling functions for OpenLP v2 themes.
"""
import os import os
from xml.dom.minidom import Document from xml.dom.minidom import Document
@ -339,7 +341,8 @@ class ThemeXML(object):
""" """
Pull out the XML string formatted for human consumption Pull out the XML string formatted for human consumption
""" """
return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n', encoding=u'utf-8') return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n',
encoding=u'utf-8')
def parse(self, xml): def parse(self, xml):
""" """
@ -364,7 +367,8 @@ class ThemeXML(object):
``xml`` ``xml``
The XML string to parse. The XML string to parse.
""" """
theme_xml = ElementTree(element=XML(xml.encode(u'ascii', u'xmlcharrefreplace'))) theme_xml = ElementTree(element=XML(xml.encode(u'ascii',
u'xmlcharrefreplace')))
xml_iter = theme_xml.getiterator() xml_iter = theme_xml.getiterator()
master = u'' master = u''
for element in xml_iter: for element in xml_iter:

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
Provide common toolbar handling for OpenLP
"""
import logging import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui

View File

@ -168,14 +168,15 @@ class Theme(object):
theme_strings.append(u'_%s_' % (getattr(self, key))) theme_strings.append(u'_%s_' % (getattr(self, key)))
return u''.join(theme_strings) return u''.join(theme_strings)
def _set_from_XML(self, xml): def _set_from_xml(self, xml):
""" """
Set theme class attributes with data from XML Set theme class attributes with data from XML
``xml`` ``xml``
The data to apply to the theme The data to apply to the theme
""" """
root = ElementTree(element=XML(xml.encode(u'ascii', u'xmlcharrefreplace'))) root = ElementTree(element=XML(xml.encode(u'ascii',
u'xmlcharrefreplace')))
xml_iter = root.getiterator() xml_iter = root.getiterator()
for element in xml_iter: for element in xml_iter:
delphi_color_change = False delphi_color_change = False

View File

@ -50,6 +50,7 @@ class Ui_AmendThemeDialog(object):
self.ThemeNameLayout.addWidget(self.ThemeNameLabel) self.ThemeNameLayout.addWidget(self.ThemeNameLabel)
self.ThemeNameEdit = QtGui.QLineEdit(self.ThemeNameWidget) self.ThemeNameEdit = QtGui.QLineEdit(self.ThemeNameWidget)
self.ThemeNameEdit.setObjectName(u'ThemeNameEdit') self.ThemeNameEdit.setObjectName(u'ThemeNameEdit')
self.ThemeNameLabel.setBuddy(self.ThemeNameEdit)
self.ThemeNameLayout.addWidget(self.ThemeNameEdit) self.ThemeNameLayout.addWidget(self.ThemeNameEdit)
self.AmendThemeLayout.addWidget(self.ThemeNameWidget) self.AmendThemeLayout.addWidget(self.ThemeNameWidget)
self.ContentWidget = QtGui.QWidget(AmendThemeDialog) self.ContentWidget = QtGui.QWidget(AmendThemeDialog)
@ -72,6 +73,7 @@ class Ui_AmendThemeDialog(object):
self.BackgroundLabel) self.BackgroundLabel)
self.BackgroundComboBox = QtGui.QComboBox(self.BackgroundTab) self.BackgroundComboBox = QtGui.QComboBox(self.BackgroundTab)
self.BackgroundComboBox.setObjectName(u'BackgroundComboBox') self.BackgroundComboBox.setObjectName(u'BackgroundComboBox')
self.BackgroundLabel.setBuddy(self.BackgroundComboBox)
self.BackgroundComboBox.addItem(QtCore.QString()) self.BackgroundComboBox.addItem(QtCore.QString())
self.BackgroundComboBox.addItem(QtCore.QString()) self.BackgroundComboBox.addItem(QtCore.QString())
self.BackgroundLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.BackgroundLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
@ -752,9 +754,9 @@ class Ui_AmendThemeDialog(object):
AmendThemeDialog.setWindowTitle( AmendThemeDialog.setWindowTitle(
translate('AmendThemeForm', 'Theme Maintenance')) translate('AmendThemeForm', 'Theme Maintenance'))
self.ThemeNameLabel.setText( self.ThemeNameLabel.setText(
translate('AmendThemeForm', 'Theme Name:')) translate('AmendThemeForm', 'Theme &Name:'))
self.BackgroundLabel.setText( self.BackgroundLabel.setText(
translate('AmendThemeForm', 'Visibility:')) translate('AmendThemeForm', '&Visibility:'))
self.BackgroundComboBox.setItemText(0, self.BackgroundComboBox.setItemText(0,
translate('AmendThemeForm', 'Opaque')) translate('AmendThemeForm', 'Opaque'))
self.BackgroundComboBox.setItemText(1, self.BackgroundComboBox.setItemText(1,

View File

@ -37,9 +37,9 @@ log = logging.getLogger(u'AmendThemeForm')
class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
def __init__(self, thememanager, parent=None): def __init__(self, parent):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.thememanager = thememanager self.thememanager = parent
self.path = None self.path = None
self.theme = ThemeXML() self.theme = ThemeXML()
self.setupUi(self) self.setupUi(self)

View File

@ -45,18 +45,67 @@ class DisplayManager(QtGui.QWidget):
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
self.screens = screens self.screens = screens
self.videoDisplay = VideoDisplay(self, screens) self.videoDisplay = VideoDisplay(self, screens)
self.audioPlayer = AudioPlayer(self)
self.mainDisplay = MainDisplay(self, screens) self.mainDisplay = MainDisplay(self, screens)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_start'), self.onStartVideo)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_stop'), self.onStopVideo)
def setup(self): def setup(self):
self.videoDisplay.setup() self.videoDisplay.setup()
self.mainDisplay.setup() self.mainDisplay.setup()
def hideDisplay(self, message):
"""
Hide the output displays
"""
self.videoDisplay.mediaHide(message)
self.mainDisplay.hideDisplay(message)
def showDisplay(self, message):
"""
Hide the output displays
"""
self.videoDisplay.mediaShow(message)
self.mainDisplay.showDisplay(message)
def addAlert(self, alertMessage, location):
"""
Handles the add Alert Message to the Displays
"""
self.mainDisplay.addAlert(alertMessage, location)
def onStartVideo(self, item):
"""
Handles the Starting of a Video and Display Management
"""
self.videoDisplay.setVisible(True)
self.mainDisplay.setVisible(False)
self.videoDisplay.onMediaQueue(item)
def onStopVideo(self):
"""
Handles the Stopping of a Video and Display Management
"""
self.mainDisplay.setVisible(True)
self.videoDisplay.setVisible(False)
self.videoDisplay.onMediaStop()
def close(self): def close(self):
"""
Handles the closure of the displays
"""
self.videoDisplay.close() self.videoDisplay.close()
self.audioPlayer.close()
self.mainDisplay.close() self.mainDisplay.close()
class DisplayWidget(QtGui.QWidget): class DisplayWidget(QtGui.QGraphicsView):
""" """
Customised version of QTableWidget which can respond to keyboard Customised version of QTableWidget which can respond to keyboard
events. events.
@ -117,32 +166,26 @@ class MainDisplay(DisplayWidget):
log.debug(u'Initialisation started') log.debug(u'Initialisation started')
DisplayWidget.__init__(self, parent) DisplayWidget.__init__(self, parent)
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint) self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
self.setWindowState(QtCore.Qt.WindowFullScreen) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.parent = parent self.parent = parent
self.setWindowTitle(u'OpenLP Display')
# WA_TranslucentBackground is not available in QT4.4 # WA_TranslucentBackground is not available in QT4.4
try: try:
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
except AttributeError: except AttributeError:
pass pass
self.screens = screens self.screens = screens
self.display_image = QtGui.QLabel(self) self.setupScene()
self.display_image.setScaledContents(True) self.setupImage()
self.display_text = QtGui.QLabel(self) self.setupText()
self.display_text.setScaledContents(True) self.setupAlert()
self.display_alert = QtGui.QLabel(self) self.setupBlank()
self.display_alert.setScaledContents(True)
self.primary = True self.primary = True
self.blankFrame = None self.blankFrame = None
self.frame = None self.frame = None
QtCore.QObject.connect(Receiver.get_receiver(), #Hide desktop for now untill we know where to put it
QtCore.SIGNAL(u'videodisplay_start'), self.hideDisplayForVideo) #and what size it should be.
QtCore.QObject.connect(Receiver.get_receiver(), self.setVisible(False)
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_background'), self.hideDisplayForVideo)
def setup(self): def setup(self):
""" """
@ -153,12 +196,8 @@ class MainDisplay(DisplayWidget):
self.setVisible(False) self.setVisible(False)
self.screen = self.screens.current self.screen = self.screens.current
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.display_alert.setGeometry(self.screen[u'size'])
self.display_image.resize(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_text.resize(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.scene.setSceneRect(0,0,self.size().width(), self.size().height())
#Build a custom splash screen #Build a custom splash screen
self.InitialFrame = QtGui.QImage( self.InitialFrame = QtGui.QImage(
self.screen[u'size'].width(), self.screen[u'size'].width(),
@ -186,30 +225,58 @@ class MainDisplay(DisplayWidget):
self.transparent = QtGui.QPixmap( self.transparent = QtGui.QPixmap(
self.screen[u'size'].width(), self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent) self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent) # self.display_text.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent) #self.frameView(self.transparent)
self.frameView(self.transparent)
# To display or not to display? # To display or not to display?
if not self.screen[u'primary']: if not self.screen[u'primary']:
self.showFullScreen() self.setVisible(True)
self.primary = False self.primary = False
else: else:
self.setVisible(False) self.setVisible(False)
self.primary = True self.primary = True
def setupScene(self):
self.scene = QtGui.QGraphicsScene(self)
self.scene.setSceneRect(0,0,self.size().width(), self.size().height())
self.setScene(self.scene)
def setupImage(self):
self.display_image = QtGui.QGraphicsPixmapItem()
self.display_image.setZValue(2)
self.scene.addItem(self.display_image)
def setupText(self):
#self.display_text = QtGui.QGraphicsTextItem()
self.display_text = QtGui.QGraphicsPixmapItem()
#self.display_text.setPos(0,0)
#self.display_text.setTextWidth(self.size().width())
self.display_text.setZValue(4)
self.scene.addItem(self.display_text)
def setupAlert(self):
self.alertText = QtGui.QGraphicsTextItem()
self.alertText.setTextWidth(self.size().width())
self.alertText.setZValue(8)
self.scene.addItem(self.alertText)
def setupBlank(self):
self.display_blank = QtGui.QGraphicsPixmapItem()
self.display_blank.setZValue(10)
self.scene.addItem(self.display_blank)
def resetDisplay(self): def resetDisplay(self):
log.debug(u'resetDisplay') log.debug(u'resetDisplay')
Receiver.send_message(u'slidecontroller_live_stop_loop') Receiver.send_message(u'slidecontroller_live_stop_loop')
if self.primary: if self.primary:
self.setVisible(False) self.setVisible(False)
else: else:
self.showFullScreen() self.setVisible(True)
def hideDisplayForVideo(self): # def hideDisplayForVideo(self):
""" # """
Hides the main display if for the video to be played # Hides the main display if for the video to be played
""" # """
self.hideDisplay(HideMode.Screen) # self.hideDisplay(HideMode.Screen)
def hideDisplay(self, mode=HideMode.Screen): def hideDisplay(self, mode=HideMode.Screen):
""" """
@ -217,45 +284,30 @@ class MainDisplay(DisplayWidget):
Store the images so they can be replaced when required Store the images so they can be replaced when required
""" """
log.debug(u'hideDisplay mode = %d', mode) log.debug(u'hideDisplay mode = %d', mode)
self.storeImage = QtGui.QPixmap(self.display_image.pixmap()) #self.display_text.setPixmap(self.transparent)
self.storeText = QtGui.QPixmap(self.display_text.pixmap())
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
if mode == HideMode.Screen: if mode == HideMode.Screen:
self.display_image.setPixmap(self.transparent) #self.display_image.setPixmap(self.transparent)
self.setVisible(False)
elif mode == HideMode.Blank: elif mode == HideMode.Blank:
self.display_image.setPixmap( self.display_blank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame)) QtGui.QPixmap.fromImage(self.blankFrame))
else: else:
if self.parent.renderManager.renderer.bg_frame: if self.parent.renderManager.renderer.bg_frame:
self.display_image.setPixmap(QtGui.QPixmap.fromImage( self.display_blank.setPixmap(QtGui.QPixmap.fromImage(
self.parent.renderManager.renderer.bg_frame)) self.parent.renderManager.renderer.bg_frame))
else: else:
self.display_image.setPixmap( self.display_blank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame)) QtGui.QPixmap.fromImage(self.blankFrame))
self.moveToTop()
def moveToTop(self): def showDisplay(self, message=u''):
log.debug(u'moveToTop')
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
self.show()
def showDisplay(self):
""" """
Show the stored layers so the screen reappears as it was Show the stored layers so the screen reappears as it was
originally. originally.
Make the stored images None to release memory. Make the stored images None to release memory.
""" """
log.debug(u'showDisplay') log.debug(u'showDisplay')
if self.storeImage: self.display_blank.setPixmap(self.transparent)
self.display_image.setPixmap(self.storeImage) #Trigger actions when display is active again
self.display_alert.setPixmap(self.transparent)
if self.storeText:
self.display_text.setPixmap(self.storeText)
self.storeImage = None
self.store = None
self.moveToTop()
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
def addImageWithText(self, frame): def addImageWithText(self, frame):
@ -263,21 +315,24 @@ class MainDisplay(DisplayWidget):
frame = resize_image( frame = resize_image(
frame, self.screen[u'size'].width(), self.screen[u'size'].height()) frame, self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
self.moveToTop()
def setAlertSize(self, top, height): def addAlert(self, message, location):
log.debug(u'setAlertSize') """
self.display_alert.setGeometry( Places the Alert text on the display at the correct location
QtCore.QRect(0, top, ``messgae``
self.screen[u'size'].width(), height)) Text to be displayed
``location``
def addAlertImage(self, frame, blank=False): Where on the screen the text should be. From the AlertTab
Combo box.
"""
log.debug(u'addAlertImage') log.debug(u'addAlertImage')
if blank: if location == 0:
self.display_alert.setPixmap(self.transparent) self.alertText.setPos(0, 0)
elif location == 1:
self.alertText.setPos(0,self.size().height()/2)
else: else:
self.display_alert.setPixmap(frame) self.alertText.setPos(0,self.size().height() - 76)
self.moveToTop() self.alertText.setHtml(message)
def frameView(self, frame, transition=False, display=True): def frameView(self, frame, transition=False, display=True):
""" """
@ -285,14 +340,16 @@ class MainDisplay(DisplayWidget):
if the alert is in progress the alert is added on top if the alert is in progress the alert is added on top
``frame`` ``frame``
Image frame to be rendered Image frame to be rendered
``transition``
Are transitions required.
""" """
log.debug(u'frameView %d' % (display)) log.debug(u'frameView %d' % display)
if display: if display:
if transition: if transition:
if self.frame is not None: if self.frame is not None:
self.display_text.setPixmap( self.display_text.setPixmap(
QtGui.QPixmap.fromImage(self.frame)) QtGui.QPixmap.fromImage(self.frame))
self.repaint() self.update()
self.frame = None self.frame = None
if frame[u'trans'] is not None: if frame[u'trans'] is not None:
self.display_text.setPixmap( self.display_text.setPixmap(
@ -311,7 +368,6 @@ class MainDisplay(DisplayWidget):
self.display_frame = frame self.display_frame = frame
if not self.isVisible() and self.screens.display: if not self.isVisible() and self.screens.display:
self.setVisible(True) self.setVisible(True)
self.showFullScreen()
else: else:
self.storeText = QtGui.QPixmap.fromImage(frame[u'main']) self.storeText = QtGui.QPixmap.fromImage(frame[u'main'])
@ -339,37 +395,29 @@ class VideoDisplay(Phonon.VideoWidget):
self.screens = screens self.screens = screens
self.hidden = False self.hidden = False
self.message = None self.message = None
self.mediaActive = False
self.mediaObject = Phonon.MediaObject() self.mediaObject = Phonon.MediaObject()
self.setAspectRatio(aspect) self.setAspectRatio(aspect)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self) Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.audioObject) Phonon.createPath(self.mediaObject, self.audioObject)
flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog
# WindowsStaysOnBottomHint is not available in QT4.4 ## # WindowsStaysOnBottomHint is not available in QT4.4
try: # try:
flags = flags | QtCore.Qt.WindowStaysOnBottomHint # flags = flags | QtCore.Qt.WindowStaysOnBottomHint
except AttributeError: # except AttributeError:
pass # pass
self.setWindowFlags(flags) self.setWindowFlags(flags)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.mediaHide)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.mediaShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_start'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay) QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause) QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(), # QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_stop'), self.onMediaStop) # QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.setup) QtCore.SIGNAL(u'config_updated'), self.setup)
QtCore.QObject.connect(self.mediaObject, QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaBackground) QtCore.SIGNAL(u'finished()'), self.onMediaStop)
self.setVisible(False) self.setVisible(False)
def keyPressEvent(self, event): def keyPressEvent(self, event):
@ -392,38 +440,48 @@ class VideoDisplay(Phonon.VideoWidget):
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
# To display or not to display? # To display or not to display?
if not self.screen[u'primary'] and self.isVisible(): if not self.screen[u'primary']: # and self.isVisible():
self.showFullScreen() #self.showFullScreen()
self.setVisible(False)
self.primary = False self.primary = False
else: else:
self.setVisible(False) self.setVisible(False)
self.primary = True self.primary = True
def onMediaBackground(self, message=None): def closeEvent(self, event):
""" """
Play a video triggered from the video plugin with the Shutting down so clean up connections
file name passed in on the event.
Also triggered from the Finish event so the video will loop
if it is triggered from the plugin
""" """
log.debug(u'VideoDisplay Queue new media message %s' % message) self.onMediaStop()
#If not file take the stored one for pth in self.outputPaths():
if not message: disconnected = pth.disconnect()
message = self.message
# still no file name then stop as it was a normal video stopping # def onMediaBackground(self, message=None):
if message: # """
self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) # Play a video triggered from the video plugin with the
self.message = message # file name passed in on the event.
self._play() # Also triggered from the Finish event so the video will loop
# if it is triggered from the plugin
# """
# log.debug(u'VideoDisplay Queue new media message %s' % message)
# #If not file take the stored one
# if not message:
# message = self.message
# # still no file name then stop as it was a normal video stopping
# if message:
# self.mediaObject.setCurrentSource(Phonon.MediaSource(message))
# self.message = message
# self._play()
def onMediaQueue(self, message): def onMediaQueue(self, message):
""" """
Set up a video to play from the serviceitem. Set up a video to play from the serviceitem.
""" """
log.debug(u'VideoDisplay Queue new media message %s' % message) log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(), file = os.path.join(message.get_frame_path(),
message[0].get_frame_title()) message.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.mediaActive = True
self._play() self._play()
def onMediaPlay(self): def onMediaPlay(self):
@ -442,7 +500,6 @@ class VideoDisplay(Phonon.VideoWidget):
log.debug(u'VideoDisplay _play called') log.debug(u'VideoDisplay _play called')
self.mediaObject.play() self.mediaObject.play()
self.setVisible(True) self.setVisible(True)
self.showFullScreen()
def onMediaPause(self): def onMediaPause(self):
""" """
@ -458,6 +515,7 @@ class VideoDisplay(Phonon.VideoWidget):
""" """
log.debug(u'VideoDisplay Media stopped by user') log.debug(u'VideoDisplay Media stopped by user')
self.message = None self.message = None
self.mediaActive = False
self.mediaObject.stop() self.mediaObject.stop()
self.onMediaFinish() self.onMediaFinish()
@ -469,7 +527,7 @@ class VideoDisplay(Phonon.VideoWidget):
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
self.setVisible(False) self.setVisible(False)
def mediaHide(self): def mediaHide(self, message=u''):
""" """
Hide the video display Hide the video display
""" """
@ -477,10 +535,90 @@ class VideoDisplay(Phonon.VideoWidget):
self.hidden = True self.hidden = True
self.setVisible(False) self.setVisible(False)
def mediaShow(self): def mediaShow(self, message=''):
""" """
Show the video disaply if it was already hidden Show the video disaply if it was already hidden
""" """
if self.hidden: if self.hidden:
self.hidden = False self.hidden = False
if self.mediaActive:
self._play() self._play()
class AudioPlayer(QtCore.QObject):
"""
This Class will play audio only allowing components to work witn a
soundtrack which does not take over the user interface.
"""
log.info(u'AudioPlayer Loaded')
def __init__(self, parent):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'AudioPlayer Initialisation started')
QtCore.QObject.__init__(self)
self.parent = parent
self.message = None
self.mediaObject = Phonon.MediaObject()
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject)
def setup(self):
"""
Sets up the Audio Player for use
"""
log.debug(u'AudioPlayer Setup')
def close(self):
"""
Shutting down so clean up connections
"""
self.onMediaStop()
for pth in self.mediaObject.outputPaths():
disconnected = pth.disconnect()
def onMediaQueue(self, message):
"""
Set up a video to play from the serviceitem.
"""
log.debug(u'AudioPlayer Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(),
message[0].get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.onMediaPlay()
def onMediaPlay(self):
"""
We want to play the play so start it
"""
log.debug(u'AudioPlayer _play called')
self.mediaObject.play()
def onMediaPause(self):
"""
Pause the Audio
"""
log.debug(u'AudioPlayer Media paused by user')
self.mediaObject.pause()
def onMediaStop(self):
"""
Stop the Audio and clean up
"""
log.debug(u'AudioPlayer Media stopped by user')
self.message = None
self.mediaObject.stop()
self.onMediaFinish()
def onMediaFinish(self):
"""
Clean up the Object queue
"""
log.debug(u'AudioPlayer Reached end of media playlist')
self.mediaObject.clearQueue()

View File

@ -63,7 +63,7 @@ class VersionThread(QtCore.QThread):
self.parent = parent self.parent = parent
self.app_version = app_version self.app_version = app_version
self.version_splitter = re.compile( self.version_splitter = re.compile(
r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))') r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
def run(self): def run(self):
""" """
@ -79,14 +79,14 @@ class VersionThread(QtCore.QThread):
remote_version[u'major'] = int(match.group(1)) remote_version[u'major'] = int(match.group(1))
remote_version[u'minor'] = int(match.group(2)) remote_version[u'minor'] = int(match.group(2))
remote_version[u'release'] = int(match.group(3)) remote_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3: if len(match.groups()) > 3 and match.group(4):
remote_version[u'revision'] = int(match.group(4)) remote_version[u'revision'] = int(match.group(4))
match = self.version_splitter.match(self.app_version[u'full']) match = self.version_splitter.match(self.app_version[u'full'])
if match: if match:
local_version[u'major'] = int(match.group(1)) local_version[u'major'] = int(match.group(1))
local_version[u'minor'] = int(match.group(2)) local_version[u'minor'] = int(match.group(2))
local_version[u'release'] = int(match.group(3)) local_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3: if len(match.groups()) > 3 and match.group(4):
local_version[u'revision'] = int(match.group(4)) local_version[u'revision'] = int(match.group(4))
if remote_version[u'major'] > local_version[u'major'] or \ if remote_version[u'major'] > local_version[u'major'] or \
remote_version[u'minor'] > local_version[u'minor'] or \ remote_version[u'minor'] > local_version[u'minor'] or \

View File

@ -76,6 +76,7 @@ class MediaDockManager(object):
log.debug(u'remove %s dock' % name) log.debug(u'remove %s dock' % name)
for dock_index in range(0, self.media_dock.count()): for dock_index in range(0, self.media_dock.count()):
if self.media_dock.widget(dock_index): if self.media_dock.widget(dock_index):
if self.media_dock.widget(dock_index).settingsSection == name: if self.media_dock.widget(dock_index).settingsSection == \
name.lower():
self.media_dock.widget(dock_index).hide() self.media_dock.widget(dock_index).hide()
self.media_dock.removeItem(dock_index) self.media_dock.removeItem(dock_index)

View File

@ -73,6 +73,14 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
for frame in self.itemList: for frame in self.itemList:
item_name = QtGui.QListWidgetItem(frame[u'title']) item_name = QtGui.QListWidgetItem(frame[u'title'])
self.listWidget.addItem(item_name) self.listWidget.addItem(item_name)
if self.listWidget.count() == 1:
self.downButton.setEnabled(False)
self.upButton.setEnabled(False)
self.deleteButton.setEnabled(False)
else:
self.downButton.setEnabled(True)
self.upButton.setEnabled(True)
self.deleteButton.setEnabled(True)
def onItemDelete(self): def onItemDelete(self):
""" """
@ -83,6 +91,10 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
row = self.listWidget.row(item) row = self.listWidget.row(item)
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
self.loadData() self.loadData()
if row == self.listWidget.count():
self.listWidget.setCurrentRow(row - 1)
else:
self.listWidget.setCurrentRow(row)
def onItemUp(self): def onItemUp(self):
""" """

View File

@ -33,7 +33,7 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
Receiver, build_icon, ItemCapabilities, SettingsManager, translate Receiver, build_icon, ItemCapabilities, SettingsManager, translate, ThemeLevel
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
@ -134,15 +134,13 @@ class ServiceManager(QtGui.QWidget):
self.ThemeLabel = QtGui.QLabel(translate('ServiceManager', 'Theme:'), self.ThemeLabel = QtGui.QLabel(translate('ServiceManager', 'Theme:'),
self) self)
self.ThemeLabel.setMargin(3) self.ThemeLabel.setMargin(3)
self.Toolbar.addWidget(self.ThemeLabel) self.Toolbar.addToolbarWidget(u'ThemeLabel', self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(self.Toolbar) self.ThemeComboBox = QtGui.QComboBox(self.Toolbar)
self.ThemeComboBox.setToolTip(translate('ServiceManager', self.ThemeComboBox.setToolTip(translate('ServiceManager',
'Select a theme for the service')) 'Select a theme for the service'))
self.ThemeComboBox.setSizeAdjustPolicy( self.ThemeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents) QtGui.QComboBox.AdjustToContents)
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar) self.Toolbar.addToolbarWidget(u'ThemeWidget', self.ThemeComboBox)
self.ThemeWidget.setDefaultWidget(self.ThemeComboBox)
self.Toolbar.addAction(self.ThemeWidget)
self.Layout.addWidget(self.Toolbar) self.Layout.addWidget(self.Toolbar)
# Create the service manager list # Create the service manager list
self.ServiceManagerList = ServiceManagerList(self) self.ServiceManagerList = ServiceManagerList(self)
@ -214,6 +212,8 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest) QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems) QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
# Last little bits of setting up # Last little bits of setting up
self.service_theme = unicode(QtCore.QSettings().value( self.service_theme = unicode(QtCore.QSettings().value(
self.parent.serviceSettingsSection + u'/service theme', self.parent.serviceSettingsSection + u'/service theme',
@ -661,9 +661,8 @@ class ServiceManager(QtGui.QWidget):
filename = unicode(filename) filename = unicode(filename)
name = filename.split(os.path.sep) name = filename.split(os.path.sep)
if filename: if filename:
SettingsManager.set_last_dir( SettingsManager.set_last_dir(self.parent.serviceSettingsSection,
self.parent.serviceSettingsSection, name[0])
os.path.split(filename)[0])
zip = None zip = None
file_to = None file_to = None
try: try:
@ -677,7 +676,7 @@ class ServiceManager(QtGui.QWidget):
translate('ServiceManager', translate('ServiceManager',
'File is not a valid service.\n' 'File is not a valid service.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
log.exception(u'Filename "%s" is not valid UTF-8' % \ log.exception(u'Filename "%s" is not valid UTF-8' %
file.decode(u'utf-8', u'replace')) file.decode(u'utf-8', u'replace'))
continue continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
@ -697,7 +696,7 @@ class ServiceManager(QtGui.QWidget):
self.onNewService() self.onNewService()
for item in items: for item in items:
serviceitem = ServiceItem() serviceitem = ServiceItem()
serviceitem.RenderManager = self.parent.RenderManager serviceitem.render_manager = self.parent.RenderManager
serviceitem.set_from_service(item, self.servicePath) serviceitem.set_from_service(item, self.servicePath)
self.validateItem(serviceitem) self.validateItem(serviceitem)
self.addServiceItem(serviceitem) self.addServiceItem(serviceitem)
@ -757,6 +756,18 @@ class ServiceManager(QtGui.QWidget):
QtCore.QVariant(self.service_theme)) QtCore.QVariant(self.service_theme))
self.regenerateServiceItems() self.regenerateServiceItems()
def themeChange(self):
"""
The theme may have changed in the settings dialog so make
sure the theme combo box is in the correct state.
"""
if self.parent.RenderManager.theme_level == ThemeLevel.Global:
self.Toolbar.actions[u'ThemeLabel'].setVisible(False)
self.Toolbar.actions[u'ThemeWidget'].setVisible(False)
else:
self.Toolbar.actions[u'ThemeLabel'].setVisible(True)
self.Toolbar.actions[u'ThemeWidget'].setVisible(True)
def regenerateServiceItems(self): def regenerateServiceItems(self):
""" """
Rebuild the service list as things have changed and a Rebuild the service list as things have changed and a

View File

@ -107,7 +107,6 @@ class SlideController(QtGui.QWidget):
self.mainDisplay = self.parent.displayManager.mainDisplay self.mainDisplay = self.parent.displayManager.mainDisplay
self.loopList = [ self.loopList = [
u'Start Loop', u'Start Loop',
u'Stop Loop',
u'Loop Separator', u'Loop Separator',
u'Image SpinBox' u'Image SpinBox'
] ]
@ -196,18 +195,25 @@ class SlideController(QtGui.QWidget):
self.onSlideSelectedLast) self.onSlideSelectedLast)
if self.isLive: if self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarSeparator(u'Close Separator')
self.blankButton = self.Toolbar.addToolbarButton( self.HideMenu = QtGui.QToolButton(self.Toolbar)
u'Blank Screen', u':/slides/slide_blank.png', self.HideMenu.setText(translate('SlideController', 'Hide'))
translate('SlideController', 'Blank Screen'), self.HideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.onBlankDisplay, True) self.Toolbar.addToolbarWidget(u'Hide Menu', self.HideMenu)
self.themeButton = self.Toolbar.addToolbarButton( self.HideMenu.setMenu(QtGui.QMenu(
u'Display Theme', u':/slides/slide_theme.png', translate('SlideController', 'Hide'), self.Toolbar))
translate('SlideController', 'Theme Screen'), self.BlankScreen = QtGui.QAction(QtGui.QIcon( u':/slides/slide_blank.png'), u'Blank Screen', self.HideMenu)
self.onThemeDisplay, True) self.BlankScreen.setCheckable(True)
self.hideButton = self.Toolbar.addToolbarButton( QtCore.QObject.connect(self.BlankScreen, QtCore.SIGNAL("triggered(bool)"), self.onBlankDisplay)
u'Hide screen', u':/slides/slide_desktop.png', self.ThemeScreen = QtGui.QAction(QtGui.QIcon(u':/slides/slide_theme.png'), u'Blank to Theme', self.HideMenu)
translate('SlideController', 'Hide Screen'), self.ThemeScreen.setCheckable(True)
self.onHideDisplay, True) QtCore.QObject.connect(self.ThemeScreen, QtCore.SIGNAL("triggered(bool)"), self.onThemeDisplay)
self.DesktopScreen = QtGui.QAction(QtGui.QIcon(u':/slides/slide_desktop.png'), u'Show Desktop', self.HideMenu)
self.DesktopScreen.setCheckable(True)
QtCore.QObject.connect(self.DesktopScreen, QtCore.SIGNAL("triggered(bool)"), self.onHideDisplay)
self.HideMenu.setDefaultAction(self.BlankScreen)
self.HideMenu.menu().addAction(self.BlankScreen)
self.HideMenu.menu().addAction(self.ThemeScreen)
self.HideMenu.menu().addAction(self.DesktopScreen)
if not self.isLive: if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton( self.Toolbar.addToolbarButton(
@ -252,19 +258,6 @@ class SlideController(QtGui.QWidget):
u'Media Stop', u':/slides/media_playback_stop.png', u'Media Stop', u':/slides/media_playback_stop.png',
translate('SlideController', 'Start playing media'), translate('SlideController', 'Start playing media'),
self.onMediaStop) self.onMediaStop)
if self.isLive:
self.blankButton = self.Mediabar.addToolbarButton(
u'Blank Screen', u':/slides/slide_blank.png',
translate('SlideController', 'Blank Screen'),
self.onBlankDisplay, True)
self.themeButton = self.Mediabar.addToolbarButton(
u'Display Theme', u':/slides/slide_theme.png',
translate('SlideController', 'Theme Screen'),
self.onThemeDisplay, True)
self.hideButton = self.Mediabar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png',
translate('SlideController', 'Hide Screen'),
self.onHideDisplay, True)
if not self.isLive: if not self.isLive:
self.seekSlider = Phonon.SeekSlider() self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
@ -340,6 +333,7 @@ class SlideController(QtGui.QWidget):
self.receiveSpinDelay) self.receiveSpinDelay)
if isLive: if isLive:
self.Toolbar.makeWidgetsInvisible(self.loopList) self.Toolbar.makeWidgetsInvisible(self.loopList)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
else: else:
self.Toolbar.makeWidgetsInvisible(self.songEditList) self.Toolbar.makeWidgetsInvisible(self.songEditList)
self.Mediabar.setVisible(False) self.Mediabar.setVisible(False)
@ -436,8 +430,8 @@ class SlideController(QtGui.QWidget):
self.Mediabar.setVisible(False) self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible([u'Song Menu']) self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
self.Toolbar.makeWidgetsInvisible(self.loopList) self.Toolbar.makeWidgetsInvisible(self.loopList)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
if item.is_text(): if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.loopList)
if QtCore.QSettings().value( if QtCore.QSettings().value(
self.parent.songsSettingsSection + u'/show songbar', self.parent.songsSettingsSection + u'/show songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0: QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
@ -520,16 +514,20 @@ class SlideController(QtGui.QWidget):
log.debug(u'processManagerItem') log.debug(u'processManagerItem')
self.onStopLoop() self.onStopLoop()
#If old item was a command tell it to stop #If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command(): if self.serviceItem:
if self.serviceItem.is_command():
Receiver.send_message(u'%s_stop' %
self.serviceItem.name.lower(), [serviceItem, self.isLive])
if self.serviceItem.is_media():
self.onMediaStop() self.onMediaStop()
if serviceItem.is_media(): if serviceItem.is_media():
self.onMediaStart(serviceItem) self.onMediaStart(serviceItem)
if self.isLive: # if self.isLive:
blanked = self.blankButton.isChecked() # blanked = self.blankButton.isChecked()
else: # else:
blanked = False # blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), # Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno]) # [serviceItem, self.isLive, blanked, slideno])
self.slideList = {} self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at #Set pointing cursor when we have somthing to point at
@ -537,7 +535,7 @@ class SlideController(QtGui.QWidget):
before = time.time() before = time.time()
#Clear the old serviceItem cache to release memory #Clear the old serviceItem cache to release memory
if self.serviceItem and self.serviceItem is not serviceItem: if self.serviceItem and self.serviceItem is not serviceItem:
self.serviceItem.cache = [] self.serviceItem.clear_cache()
self.serviceItem = serviceItem self.serviceItem = serviceItem
self.PreviewListWidget.clear() self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0) self.PreviewListWidget.setRowCount(0)
@ -655,7 +653,9 @@ class SlideController(QtGui.QWidget):
""" """
Allow the main display to blank the main display at startup time Allow the main display to blank the main display at startup time
""" """
self.blankButton.setChecked(True) log.debug(u'mainDisplaySetBackground')
if not self.mainDisplay.primary:
self.onBlankDisplay(True)
def onSlideBlank(self): def onSlideBlank(self):
""" """
@ -671,56 +671,57 @@ class SlideController(QtGui.QWidget):
def onBlankDisplay(self, checked): def onBlankDisplay(self, checked):
""" """
Handle the blank screen button Handle the blank screen button actions
""" """
log.debug(u'onBlankDisplay %d' % checked) log.debug(u'onBlankDisplay %s' % checked)
self.hideButton.setChecked(False) self.HideMenu.setDefaultAction(self.BlankScreen)
self.themeButton.setChecked(False) self.BlankScreen.setChecked(checked)
self.canDisplay = not checked self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(False)
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank', self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(checked)) QtCore.QVariant(checked))
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Blank) Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
self.blankPlugin(True)
else: else:
Receiver.send_message(u'maindisplay_show') Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False) self.blankPlugin(checked)
def onThemeDisplay(self, checked): def onThemeDisplay(self, checked):
""" """
Handle the Theme screen button Handle the Theme screen button
""" """
log.debug(u'onThemeDisplay %d' % checked) log.debug(u'onThemeDisplay %s' % checked)
self.blankButton.setChecked(False) self.HideMenu.setDefaultAction(self.ThemeScreen)
self.hideButton.setChecked(False) self.BlankScreen.setChecked(False)
self.canDisplay = False self.ThemeScreen.setChecked(checked)
self.DesktopScreen.setChecked(False)
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme) Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
self.blankPlugin(True)
else: else:
Receiver.send_message(u'maindisplay_show') Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False) self.blankPlugin(checked)
def onHideDisplay(self, checked): def onHideDisplay(self, checked):
""" """
Handle the Hide screen button Handle the Hide screen button
""" """
log.debug(u'onHideDisplay %d' % checked) log.debug(u'onHideDisplay %s' % checked)
self.blankButton.setChecked(False) self.HideMenu.setDefaultAction(self.DesktopScreen)
self.themeButton.setChecked(False) self.BlankScreen.setChecked(False)
self.canDisplay = False self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(checked)
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen) Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.hidePlugin(True)
else: else:
Receiver.send_message(u'maindisplay_show') Receiver.send_message(u'maindisplay_show')
self.hidePlugin(False) self.hidePlugin(checked)
def blankPlugin(self, blank): def blankPlugin(self, blank):
""" """
Blank the display screen within a plugin if required. Blank the display screen within a plugin if required.
""" """
log.debug(u'blankPlugin %s ', blank)
if self.serviceItem is not None: if self.serviceItem is not None:
if blank: if blank:
Receiver.send_message(u'%s_blank' Receiver.send_message(u'%s_blank'
@ -733,8 +734,9 @@ class SlideController(QtGui.QWidget):
def hidePlugin(self, hide): def hidePlugin(self, hide):
""" """
Blank the display screen. Tell the plugin to hide the display screen.
""" """
log.debug(u'hidePlugin %s ', hide)
if self.serviceItem is not None: if self.serviceItem is not None:
if hide: if hide:
Receiver.send_message(u'%s_hide' Receiver.send_message(u'%s_hide'
@ -779,7 +781,7 @@ class SlideController(QtGui.QWidget):
log.log( log.log(
15, u'Slide Rendering took %4s' % (time.time() - before)) 15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive: if self.isLive:
self.mainDisplay.frameView(frame, True, self.canDisplay) self.mainDisplay.frameView(frame, True)#, self.canDisplay)
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)
@ -824,7 +826,7 @@ class SlideController(QtGui.QWidget):
return return
Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(), Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command() and self.isLive:
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() + 1 row = self.PreviewListWidget.currentRow() + 1
@ -848,7 +850,7 @@ class SlideController(QtGui.QWidget):
return return
Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(), Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command() and self.isLive:
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() - 1 row = self.PreviewListWidget.currentRow() - 1
@ -882,6 +884,8 @@ class SlideController(QtGui.QWidget):
if self.PreviewListWidget.rowCount() > 1: if self.PreviewListWidget.rowCount() > 1:
self.timer_id = self.startTimer( self.timer_id = self.startTimer(
int(self.DelaySpinBox.value()) * 1000) int(self.DelaySpinBox.value()) * 1000)
self.Toolbar.actions[u'Stop Loop'].setVisible(True)
self.Toolbar.actions[u'Start Loop'].setVisible(False)
def onStopLoop(self): def onStopLoop(self):
""" """
@ -890,6 +894,8 @@ class SlideController(QtGui.QWidget):
if self.timer_id != 0: if self.timer_id != 0:
self.killTimer(self.timer_id) self.killTimer(self.timer_id)
self.timer_id = 0 self.timer_id = 0
self.Toolbar.actions[u'Start Loop'].setVisible(True)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
def timerEvent(self, event): def timerEvent(self, event):
""" """
@ -921,8 +927,7 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'SlideController onMediaStart') log.debug(u'SlideController onMediaStart')
if self.isLive: if self.isLive:
Receiver.send_message(u'videodisplay_start', Receiver.send_message(u'videodisplay_start', item)
[item, self.blankButton.isChecked()])
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()

View File

@ -35,7 +35,7 @@ from openlp.core.ui import AmendThemeForm
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.lib import OpenLPToolbar, context_menu_action, \ from openlp.core.lib import OpenLPToolbar, context_menu_action, \
ThemeXML, str_to_bool, get_text_file_string, build_icon, Receiver, \ ThemeXML, str_to_bool, get_text_file_string, build_icon, Receiver, \
context_menu_separator, SettingsManager, translate context_menu_separator, SettingsManager, translate, check_item_selected
from openlp.core.utils import AppLocation, get_filesystem_encoding from openlp.core.utils import AppLocation, get_filesystem_encoding
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -182,8 +182,9 @@ class ThemeManager(QtGui.QWidget):
Loads the settings for the theme that is to be edited and launches the Loads the settings for the theme that is to be edited and launches the
theme editing form so the user can make their changes. theme editing form so the user can make their changes.
""" """
if check_item_selected(self.ThemeListWidget, translate('ThemeManager',
'You must select a theme to edit.')):
item = self.ThemeListWidget.currentItem() item = self.ThemeListWidget.currentItem()
if item:
theme = self.getThemeData( theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
self.amendThemeForm.loadTheme(theme) self.amendThemeForm.loadTheme(theme)
@ -198,8 +199,9 @@ class ThemeManager(QtGui.QWidget):
self.global_theme = unicode(QtCore.QSettings().value( self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme', self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString()) QtCore.QVariant(u'')).toString())
if check_item_selected(self.ThemeListWidget, translate('ThemeManager',
'You must select a theme to delete.')):
item = self.ThemeListWidget.currentItem() item = self.ThemeListWidget.currentItem()
if item:
theme = unicode(item.text()) theme = unicode(item.text())
# should be the same unless default # should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
@ -398,7 +400,7 @@ class ThemeManager(QtGui.QWidget):
self, translate('ThemeManager', 'Error'), self, translate('ThemeManager', 'Error'),
translate('ThemeManager', 'File is not a valid theme.\n' translate('ThemeManager', 'File is not a valid theme.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
log.exception(u'Filename "%s" is not valid UTF-8' % \ log.exception(u'Filename "%s" is not valid UTF-8' %
file.decode(u'utf-8', u'replace')) file.decode(u'utf-8', u'replace'))
continue continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
@ -424,8 +426,8 @@ class ThemeManager(QtGui.QWidget):
xml_data = xml_data.decode(u'utf-8') xml_data = xml_data.decode(u'utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Theme XML is not UTF-8 ' log.exception(u'Theme XML is not UTF-8 '
'encoded.') u'encoded.')
break; break
if self.checkVersion1(xml_data): if self.checkVersion1(xml_data):
# upgrade theme xml # upgrade theme xml
filexml = self.migrateVersion122(xml_data) filexml = self.migrateVersion122(xml_data)

View File

@ -150,9 +150,9 @@ class ThemesTab(SettingsTab):
settings.setValue(u'global theme', settings.setValue(u'global theme',
QtCore.QVariant(self.global_theme)) QtCore.QVariant(self.global_theme))
settings.endGroup() settings.endGroup()
Receiver.send_message(u'theme_update_global', self.global_theme)
self.parent.RenderManager.set_global_theme( self.parent.RenderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
Receiver.send_message(u'theme_update_global', self.global_theme)
def postSetUp(self): def postSetUp(self):
Receiver.send_message(u'theme_update_global', self.global_theme) Receiver.send_message(u'theme_update_global', self.global_theme)

View File

@ -50,6 +50,7 @@ class AppLocation(object):
DataDir = 3 DataDir = 3
PluginsDir = 4 PluginsDir = 4
VersionDir = 5 VersionDir = 5
CacheDir = 6
@staticmethod @staticmethod
def get_directory(dir_type=1): def get_directory(dir_type=1):
@ -103,6 +104,20 @@ class AppLocation(object):
else: else:
plugin_path = os.path.split(openlp.__file__)[0] plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path return plugin_path
elif dir_type == AppLocation.CacheDir:
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', u'openlp')
else:
try:
from xdg import BaseDirectory
path = os.path.join(
BaseDirectory.xdg_cache_home, u'openlp')
except ImportError:
path = os.path.join(os.getenv(u'HOME'), u'.openlp')
return path
@staticmethod @staticmethod
def get_data_path(): def get_data_path():
@ -138,7 +153,6 @@ def check_latest_version(current_version):
settings.setValue(u'last version test', QtCore.QVariant(this_test)) settings.setValue(u'last version test', QtCore.QVariant(this_test))
settings.endGroup() settings.endGroup()
if last_test != this_test: if last_test != this_test:
version_string = u''
if current_version[u'build']: if current_version[u'build']:
req = urllib2.Request( req = urllib2.Request(
u'http://www.openlp.org/files/dev_version.txt') u'http://www.openlp.org/files/dev_version.txt')

View File

@ -22,7 +22,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`languagemanager` module provides all the translation settings and
language file loading for OpenLP.
"""
import logging import logging
import os import os
@ -42,50 +45,74 @@ class LanguageManager(object):
@staticmethod @staticmethod
def get_translator(language): def get_translator(language):
"""
Set up a translator to use in this instance of OpenLP
``language``
The language to load into the translator
"""
if LanguageManager.AutoLanguage: if LanguageManager.AutoLanguage:
language = QtCore.QLocale.system().name() language = QtCore.QLocale.system().name()
lang_Path = AppLocation.get_directory(AppLocation.AppDir) lang_Path = AppLocation.get_directory(AppLocation.AppDir)
lang_Path = os.path.join(lang_Path, u'resources', u'i18n') lang_Path = os.path.join(lang_Path, u'resources', u'i18n')
appTranslator = QtCore.QTranslator() app_translator = QtCore.QTranslator()
if appTranslator.load("openlp_" + language, lang_Path): if app_translator.load("openlp_" + language, lang_Path):
return appTranslator return app_translator
@staticmethod @staticmethod
def find_qm_files(): def find_qm_files():
"""
Find all available language files in this OpenLP install
"""
trans_dir = AppLocation.get_directory(AppLocation.AppDir) trans_dir = AppLocation.get_directory(AppLocation.AppDir)
trans_dir = QtCore.QDir(os.path.join(trans_dir, u'resources', u'i18n')) trans_dir = QtCore.QDir(os.path.join(trans_dir, u'resources', u'i18n'))
fileNames = trans_dir.entryList(QtCore.QStringList("*.qm"), file_names = trans_dir.entryList(QtCore.QStringList("*.qm"),
QtCore.QDir.Files, QtCore.QDir.Name) QtCore.QDir.Files, QtCore.QDir.Name)
for name in fileNames: for name in file_names:
fileNames.replaceInStrings(name, trans_dir.filePath(name)) file_names.replaceInStrings(name, trans_dir.filePath(name))
return fileNames return file_names
@staticmethod @staticmethod
def language_name(qmFile): def language_name(qm_file):
"""
Load the language name from a language file
``qm_file``
The file to obtain the name from
"""
translator = QtCore.QTranslator() translator = QtCore.QTranslator()
translator.load(qmFile) translator.load(qm_file)
return translator.translate('MainWindow', 'English') return translator.translate('MainWindow', 'English')
@staticmethod @staticmethod
def get_language(): def get_language():
"""
Retrieve a saved language to use from settings
"""
settings = QtCore.QSettings(u'OpenLP', u'OpenLP') settings = QtCore.QSettings(u'OpenLP', u'OpenLP')
language = unicode(settings.value( language = unicode(settings.value(
u'general/language', QtCore.QVariant(u'[en]')).toString()) u'general/language', QtCore.QVariant(u'[en]')).toString())
log.info(u'Language file: \'%s\' Loaded from conf file' % language) log.info(u'Language file: \'%s\' Loaded from conf file' % language)
regEx = QtCore.QRegExp("^\[(.*)\]") reg_ex = QtCore.QRegExp("^\[(.*)\]")
if regEx.exactMatch(language): if reg_ex.exactMatch(language):
LanguageManager.AutoLanguage = True LanguageManager.AutoLanguage = True
language = regEx.cap(1) language = reg_ex.cap(1)
return language return language
@staticmethod @staticmethod
def set_language(action): def set_language(action):
actionName = u'%s' % action.objectName() """
qmList = LanguageManager.get_qm_list() Set the language to translate OpenLP into
``action``
The language menu option
"""
action_name = u'%s' % action.objectName()
qm_list = LanguageManager.get_qm_list()
if LanguageManager.AutoLanguage: if LanguageManager.AutoLanguage:
language = u'[%s]' % qmList[actionName] language = u'[%s]' % qm_list[action_name]
else: else:
language = u'%s' % qmList[actionName] language = u'%s' % qm_list[action_name]
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
u'general/language', QtCore.QVariant(language)) u'general/language', QtCore.QVariant(language))
log.info(u'Language file: \'%s\' written to conf file' % language) log.info(u'Language file: \'%s\' written to conf file' % language)
@ -96,17 +123,23 @@ class LanguageManager(object):
@staticmethod @staticmethod
def init_qm_list(): def init_qm_list():
"""
Initialise the list of available translations
"""
LanguageManager.__qmList__ = {} LanguageManager.__qmList__ = {}
qmFiles = LanguageManager.find_qm_files() qm_files = LanguageManager.find_qm_files()
for i, qmf in enumerate(qmFiles): for i, qmf in enumerate(qm_files):
regEx = QtCore.QRegExp("^.*openlp_(.*).qm") reg_ex = QtCore.QRegExp("^.*openlp_(.*).qm")
if regEx.exactMatch(qmf): if reg_ex.exactMatch(qmf):
langName = regEx.cap(1) lang_name = reg_ex.cap(1)
LanguageManager.__qmList__[u'%#2i %s' % (i+1, LanguageManager.__qmList__[u'%#2i %s' % (i+1,
LanguageManager.language_name(qmf))] = langName LanguageManager.language_name(qmf))] = lang_name
@staticmethod @staticmethod
def get_qm_list(): def get_qm_list():
"""
Return the list of available translations
"""
if LanguageManager.__qmList__ is None: if LanguageManager.__qmList__ is None:
LanguageManager.init_qm_list() LanguageManager.init_qm_list()
return LanguageManager.__qmList__ return LanguageManager.__qmList__

View File

@ -24,5 +24,5 @@
############################################################################### ###############################################################################
""" """
The :mod:`alerts` module provides the Alerts plugin for producing impromptu The :mod:`alerts` module provides the Alerts plugin for producing impromptu
on-screen announcements during a service on-screen announcements during a service.
""" """

View File

@ -28,7 +28,9 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab, DBManager from openlp.core.lib.db import Manager
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
from openlp.plugins.alerts.lib.db import init_schema
from openlp.plugins.alerts.forms import AlertForm from openlp.plugins.alerts.forms import AlertForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -37,15 +39,18 @@ class alertsPlugin(Plugin):
log.info(u'Alerts Plugin loaded') log.info(u'Alerts Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Alerts', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Alerts', u'1.9.2', plugin_helpers)
self.weight = -3 self.weight = -3
self.icon = build_icon(u':/media/media_image.png') self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self) self.alertsmanager = AlertsManager(self)
self.manager = DBManager() self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self.manager, self) self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active self.status = PluginStatus.Active
def get_settings_tab(self): def get_settings_tab(self):
"""
Return the settings tab for the Alerts plugin
"""
self.alertsTab = AlertsTab(self) self.alertsTab = AlertsTab(self)
return self.alertsTab return self.alertsTab
@ -60,13 +65,13 @@ class alertsPlugin(Plugin):
""" """
log.info(u'add tools menu') log.info(u'add tools menu')
self.toolsAlertItem = QtGui.QAction(tools_menu) self.toolsAlertItem = QtGui.QAction(tools_menu)
AlertIcon = build_icon(u':/tools/tools_alert.png') AlertIcon = build_icon(u':/plugins/plugin_alerts.png')
self.toolsAlertItem.setIcon(AlertIcon) self.toolsAlertItem.setIcon(AlertIcon)
self.toolsAlertItem.setObjectName(u'toolsAlertItem') self.toolsAlertItem.setObjectName(u'toolsAlertItem')
self.toolsAlertItem.setText( self.toolsAlertItem.setText(
translate(u'AlertsPlugin', u'&Alert')) translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setStatusTip( self.toolsAlertItem.setStatusTip(
translate(u'AlertsPlugin', u'Show an alert message')) translate('AlertsPlugin', 'Show an alert message'))
self.toolsAlertItem.setShortcut(u'F7') self.toolsAlertItem.setShortcut(u'F7')
self.service_manager.parent.ToolsMenu.addAction(self.toolsAlertItem) self.service_manager.parent.ToolsMenu.addAction(self.toolsAlertItem)
QtCore.QObject.connect(self.toolsAlertItem, QtCore.QObject.connect(self.toolsAlertItem,
@ -94,7 +99,7 @@ class alertsPlugin(Plugin):
self.alertForm.exec_() self.alertForm.exec_()
def about(self): def about(self):
about_text = translate(u'AlertsPlugin', about_text = translate('AlertsPlugin',
u'<b>Alerts Plugin</b><br>This plugin ' '<b>Alerts Plugin</b><br>This plugin '
u'controls the displaying of alerts on the presentations screen') 'controls the displaying of alerts on the presentations screen')
return about_text return about_text

View File

@ -148,21 +148,20 @@ class Ui_AlertDialog(object):
def retranslateUi(self, AlertDialog): def retranslateUi(self, AlertDialog):
AlertDialog.setWindowTitle( AlertDialog.setWindowTitle(
translate(u'AlertsPlugin.AlertForm', u'Alert Message')) translate('AlertsPlugin.AlertForm', 'Alert Message'))
self.AlertEntryLabel.setText( self.AlertEntryLabel.setText(
translate(u'AlertsPlugin.AlertForm', u'Alert &text:')) translate('AlertsPlugin.AlertForm', 'Alert &text:'))
self.AlertParameter.setText( self.AlertParameter.setText(
translate(u'AlertsPlugin.AlertForm', u'&Parameter(s):')) translate('AlertsPlugin.AlertForm', '&Parameter(s):'))
self.NewButton.setText( self.NewButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&New')) translate('AlertsPlugin.AlertForm', '&New'))
self.SaveButton.setText( self.SaveButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&Save')) translate('AlertsPlugin.AlertForm', '&Save'))
self.DeleteButton.setText( self.DeleteButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&Delete')) translate('AlertsPlugin.AlertForm', '&Delete'))
self.DisplayButton.setText( self.DisplayButton.setText(
translate(u'AlertsPlugin.AlertForm', u'Displ&ay')) translate('AlertsPlugin.AlertForm', 'Displ&ay'))
self.DisplayCloseButton.setText( self.DisplayCloseButton.setText(
translate(u'AlertsPlugin.AlertForm', u'Display && Cl&ose')) translate('AlertsPlugin.AlertForm', 'Display && Cl&ose'))
self.CloseButton.setText( self.CloseButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&Close')) translate('AlertsPlugin.AlertForm', '&Close'))

View File

@ -25,8 +25,8 @@
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.plugins.alerts.lib.models import AlertItem
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.alerts.lib.db import AlertItem
from alertdialog import Ui_AlertDialog from alertdialog import Ui_AlertDialog
@ -62,7 +62,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def loadList(self): def loadList(self):
self.AlertListWidget.clear() self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts() alerts = self.manager.get_all_objects(AlertItem, AlertItem.text)
for alert in alerts: for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
@ -82,7 +82,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item = self.AlertListWidget.currentItem() item = self.AlertListWidget.currentItem()
if item: if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id) self.manager.delete_object(AlertItem, item_id)
row = self.AlertListWidget.row(item) row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row) self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'') self.AlertTextEdit.setText(u'')
@ -93,12 +93,12 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def onNewClick(self): def onNewClick(self):
if len(self.AlertTextEdit.text()) == 0: if len(self.AlertTextEdit.text()) == 0:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate(u'AlertsPlugin.AlertForm', u'Item selected to Add'), translate('AlertsPlugin.AlertForm', 'Item selected to Add'),
translate(u'AlertsPlugin.AlertForm', u'Missing data')) translate('AlertsPlugin.AlertForm', 'Missing data'))
else: else:
alert = AlertItem() alert = AlertItem()
alert.text = unicode(self.AlertTextEdit.text()) alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert) self.manager.save_object(alert)
self.AlertTextEdit.setText(u'') self.AlertTextEdit.setText(u'')
self.loadList() self.loadList()
@ -107,9 +107,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
Save an alert Save an alert
""" """
if self.item_id: if self.item_id:
alert = self.manager.get_alert(self.item_id) alert = self.manager.get_object(AlertItem, self.item_id)
alert.text = unicode(self.AlertTextEdit.text()) alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert) self.manager.save_object(alert)
self.item_id = None self.item_id = None
self.loadList() self.loadList()
else: else:
@ -153,4 +153,3 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.parent.alertsmanager.displayAlert(text) self.parent.alertsmanager.displayAlert(text)
return True return True
return False return False

View File

@ -25,4 +25,3 @@
from alertsmanager import AlertsManager from alertsmanager import AlertsManager
from alertstab import AlertsTab from alertstab import AlertsTab
from manager import DBManager

View File

@ -31,6 +31,15 @@ from openlp.core.lib import Receiver, translate
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
HTMLCODE = u"""
<p style=\"color:%s;
background-color:%s;
font-family:%s;
font-size: %spt; \">
%s
</p>
"""
class AlertsManager(QtCore.QObject): class AlertsManager(QtCore.QObject):
""" """
AlertsTab is the Alerts settings tab in the settings dialog. AlertsTab is the Alerts settings tab in the settings dialog.
@ -47,28 +56,6 @@ class AlertsManager(QtCore.QObject):
QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert) QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'alerts_text'), self.onAlertText) QtCore.SIGNAL(u'alerts_text'), self.onAlertText)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
def screenChanged(self):
log.debug(u'screen changed')
self.alertTab = self.parent.alertsTab
self.screen = self.parent.maindisplay.screens.current
self.font = QtGui.QFont()
self.font.setFamily(self.alertTab.font_face)
self.font.setBold(True)
self.font.setPointSize(self.alertTab.font_size)
self.metrics = QtGui.QFontMetrics(self.font)
self.alertHeight = self.metrics.height() + 4
if self.alertTab.location == 0:
self.alertScreenPosition = 0
else:
self.alertScreenPosition = self.screen[u'size'].height() \
- self.alertHeight
self.alertHeight = self.screen[u'size'].height() \
- self.alertScreenPosition
self.parent.maindisplay.setAlertSize(self.alertScreenPosition,
self.alertHeight)
def onAlertText(self, message): def onAlertText(self, message):
""" """
@ -88,49 +75,43 @@ class AlertsManager(QtCore.QObject):
display text display text
""" """
log.debug(u'display alert called %s' % text) log.debug(u'display alert called %s' % text)
if not self.screen:
self.screenChanged()
self.alertList.append(text) self.alertList.append(text)
if self.timer_id != 0: if self.timer_id != 0:
Receiver.send_message(u'maindisplay_status_text', Receiver.send_message(u'maindisplay_status_text',
translate(u'AlertsPlugin.AlertsManager', translate('AlertsPlugin.AlertsManager',
u'Alert message created and delayed')) 'Alert message created and delayed'))
return return
Receiver.send_message(u'maindisplay_status_text', u'') Receiver.send_message(u'maindisplay_status_text', u'')
self.generateAlert() self.generateAlert()
def generateAlert(self): def generateAlert(self):
"""
Format and request the Alert and start the timer
"""
log.debug(u'Generate Alert called') log.debug(u'Generate Alert called')
if len(self.alertList) == 0: if len(self.alertList) == 0:
return return
text = self.alertList.pop(0) text = self.alertList.pop(0)
alertTab = self.parent.alertsTab alertTab = self.parent.alertsTab
alertframe = \ text = HTMLCODE % (alertTab.font_color, alertTab.bg_color,
QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight) alertTab.font_face, alertTab.font_size, text)
alertframe.fill(QtCore.Qt.transparent) self.parent.preview_controller.parent.displayManager.addAlert(text, alertTab.location)
painter = QtGui.QPainter(alertframe)
painter.fillRect(alertframe.rect(), QtCore.Qt.transparent)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.fillRect(
QtCore.QRect(
0, 0, alertframe.rect().width(),
alertframe.rect().height()),
QtGui.QColor(self.alertTab.bg_color))
painter.setFont(self.font)
painter.setPen(QtGui.QColor(self.alertTab.font_color))
x, y = (0, 2)
painter.drawText(
x, y + self.metrics.height() - self.metrics.descent() - 1, text)
painter.end()
self.parent.maindisplay.addAlertImage(alertframe)
# check to see if we have a timer running # check to see if we have a timer running
if self.timer_id == 0: if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event): def timerEvent(self, event):
"""
Time has finished so if our time then request the next Alert
if there is one and reset the timer.
``event``
the QT event that has been triggered.
"""
log.debug(u'timer event') log.debug(u'timer event')
alertTab = self.parent.alertsTab
if event.timerId() == self.timer_id: if event.timerId() == self.timer_id:
self.parent.maindisplay.addAlertImage(None, True) self.parent.preview_controller.parent.displayManager.addAlert(u'', alertTab.location)
self.killTimer(self.timer_id) self.killTimer(self.timer_id)
self.timer_id = 0 self.timer_id = 0
self.generateAlert() self.generateAlert()

View File

@ -38,7 +38,7 @@ class AlertsTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'AlertsTab') self.setObjectName(u'AlertsTab')
self.tabTitleVisible = translate(u'AlertsPlugin.AlertsTab', u'Alerts') self.tabTitleVisible = translate('AlertsPlugin.AlertsTab', 'Alerts')
self.AlertsLayout = QtGui.QHBoxLayout(self) self.AlertsLayout = QtGui.QHBoxLayout(self)
self.AlertsLayout.setSpacing(8) self.AlertsLayout.setSpacing(8)
self.AlertsLayout.setMargin(8) self.AlertsLayout.setMargin(8)
@ -128,6 +128,7 @@ class AlertsTab(SettingsTab):
self.LocationComboBox = QtGui.QComboBox(self.LocationWidget) self.LocationComboBox = QtGui.QComboBox(self.LocationWidget)
self.LocationComboBox.addItem(QtCore.QString()) self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.addItem(QtCore.QString()) self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.setObjectName(u'LocationComboBox') self.LocationComboBox.setObjectName(u'LocationComboBox')
self.LocationLayout.addWidget(self.LocationComboBox) self.LocationLayout.addWidget(self.LocationComboBox)
self.LocationSpacer = QtGui.QSpacerItem(147, 20, self.LocationSpacer = QtGui.QSpacerItem(147, 20,
@ -187,31 +188,33 @@ class AlertsTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.FontGroupBox.setTitle( self.FontGroupBox.setTitle(
translate(u'AlertsPlugin.AlertsTab', u'Font')) translate('AlertsPlugin.AlertsTab', 'Font'))
self.FontLabel.setText( self.FontLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Name:')) translate('AlertsPlugin.AlertsTab', 'Font Name:'))
self.FontColorLabel.setText( self.FontColorLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Color:')) translate('AlertsPlugin.AlertsTab', 'Font Color:'))
self.BackgroundColorLabel.setText( self.BackgroundColorLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Background Color:')) translate('AlertsPlugin.AlertsTab', 'Background Color:'))
self.FontSizeLabel.setText( self.FontSizeLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Size:')) translate('AlertsPlugin.AlertsTab', 'Font Size:'))
self.FontSizeSpinBox.setSuffix( self.FontSizeSpinBox.setSuffix(
translate(u'AlertsPlugin.AlertsTab', u'pt')) translate('AlertsPlugin.AlertsTab', 'pt'))
self.TimeoutLabel.setText( self.TimeoutLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Alert timeout:')) translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix( self.TimeoutSpinBox.setSuffix(
translate(u'AlertsPlugin.AlertsTab', u's')) translate('AlertsPlugin.AlertsTab', 's'))
self.LocationLabel.setText( self.LocationLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Location:')) translate('AlertsPlugin.AlertsTab', 'Location:'))
self.PreviewGroupBox.setTitle( self.PreviewGroupBox.setTitle(
translate(u'AlertsPlugin.AlertsTab', u'Preview')) translate('AlertsPlugin.AlertsTab', 'Preview'))
self.FontPreview.setText( self.FontPreview.setText(
translate(u'AlertsPlugin.AlertsTab', u'openlp.org')) translate('AlertsPlugin.AlertsTab', 'openlp.org'))
self.LocationComboBox.setItemText(0, self.LocationComboBox.setItemText(0,
translate(u'AlertsPlugin.AlertsTab', u'Top')) translate('AlertsPlugin.AlertsTab', 'Top'))
self.LocationComboBox.setItemText(1, self.LocationComboBox.setItemText(1,
translate(u'AlertsPlugin.AlertsTab', u'Bottom')) translate('AlertsPlugin.AlertsTab', 'Middle'))
self.LocationComboBox.setItemText(2,
translate('AlertsPlugin.AlertsTab', 'Bottom'))
def onBackgroundColorButtonClicked(self): def onBackgroundColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor( new_color = QtGui.QColorDialog.getColor(
@ -294,5 +297,5 @@ class AlertsTab(SettingsTab):
font.setBold(True) font.setBold(True)
font.setPointSize(self.font_size) font.setPointSize(self.font_size)
self.FontPreview.setFont(font) self.FontPreview.setFont(font)
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' % \ self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
(self.bg_color, self.font_color)) (self.bg_color, self.font_color))

View File

@ -1,32 +0,0 @@
# -*- 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, 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 #
###############################################################################
from openlp.core.lib import BaseModel
class AlertItem(BaseModel):
"""
Custom Slide model
"""
pass

View File

@ -22,18 +22,36 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`db` module provides the database and schema that is the backend for
the Alerts plugin
"""
from sqlalchemy import create_engine from sqlalchemy import Column, Table, types
from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.orm import mapper
from openlp.plugins.alerts.lib.meta import metadata from openlp.core.lib.db import BaseModel, init_db
from openlp.plugins.alerts.lib.tables import *
from openlp.plugins.alerts.lib.classes import * class AlertItem(BaseModel):
"""
AlertItem model
"""
pass
def init_schema(url):
"""
Setup the alerts database connection and initialise the database schema
``url``
The database to setup
"""
session, metadata = init_db(url)
alerts_table = Table(u'alerts', metadata,
Column(u'id', types.Integer(), primary_key=True),
Column(u'text', types.UnicodeText, nullable=False))
def init_models(url):
engine = create_engine(url)
metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine))
mapper(AlertItem, alerts_table) mapper(AlertItem, alerts_table)
metadata.create_all(checkfirst=True)
return session return session

View File

@ -1,114 +0,0 @@
# -*- 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, 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 #
###############################################################################
import logging
from PyQt4 import QtCore
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.alerts.lib.models import init_models, metadata, AlertItem
log = logging.getLogger(__name__)
class DBManager(object):
"""
The Song Manager provides a central location for all database code. This
class takes care of connecting to the database and running all the queries.
"""
log.info(u'Alerts DB loaded')
def __init__(self):
"""
Creates the connection to the database, and creates the tables if they
don't exist.
"""
log.debug(u'Alerts Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'alerts')
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/alerts.sqlite' % \
AppLocation.get_section_data_path(u'alerts')
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True)
log.debug(u'Alerts Initialised')
def get_all_alerts(self):
"""
Returns the details of a Alert Show
"""
return self.session.query(AlertItem).order_by(AlertItem.text).all()
def save_alert(self, alert_item):
"""
Saves a Alert show to the database
"""
log.debug(u'Alert added')
try:
self.session.add(alert_item)
self.session.commit()
log.debug(u'Alert saved')
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Alert save failed')
return False
def get_alert(self, id=None):
"""
Returns the details of a Alert
"""
if id is None:
return AlertItem()
else:
return self.session.query(AlertItem).get(id)
def delete_alert(self, id):
"""
Delete a Alert show
"""
if id != 0:
alert_item = self.get_alert(id)
try:
self.session.delete(alert_item)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Alert deleton failed')
return False
else:
return True

View File

@ -1,38 +0,0 @@
# -*- 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, 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 #
###############################################################################
from sqlalchemy import MetaData
__all__ = ['session', 'metadata', 'engine']
# SQLAlchemy database engine. Updated by model.init_model()
engine = None
# SQLAlchemy session manager. Updated by model.init_model()
session = None
# Global metadata. If you have multiple databases with overlapping table
# names, you'll need a metadata for each database
metadata = MetaData()

View File

@ -1,33 +0,0 @@
# -*- 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, 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 #
###############################################################################
from sqlalchemy import Column, Table, types
from openlp.plugins.alerts.lib.meta import metadata
# Definition of the "alerts" table
alerts_table = Table(u'alerts', metadata,
Column(u'id', types.Integer(), primary_key=True),
Column(u'text', types.UnicodeText, nullable=False))

View File

@ -23,6 +23,6 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
""" """
The :mod:`bibles' modules provides the Bible plugin to enable OpenLP to display The :mod:`bibles' module provides the Bible plugin to enable OpenLP to display
scripture scripture.
""" """

View File

@ -36,7 +36,7 @@ class BiblePlugin(Plugin):
log.info(u'Bible Plugin loaded') log.info(u'Bible Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Bibles', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Bibles', u'1.9.2', plugin_helpers)
self.weight = -9 self.weight = -9
self.icon = build_icon(u':/media/media_bible.png') self.icon = build_icon(u':/media/media_bible.png')
#Register the bible Manager #Register the bible Manager
@ -71,7 +71,7 @@ class BiblePlugin(Plugin):
self.ImportBibleItem.setObjectName(u'ImportBibleItem') self.ImportBibleItem.setObjectName(u'ImportBibleItem')
import_menu.addAction(self.ImportBibleItem) import_menu.addAction(self.ImportBibleItem)
self.ImportBibleItem.setText( self.ImportBibleItem.setText(
translate(u'BiblePlugin', u'&Bible')) translate('BiblePlugin', '&Bible'))
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.ImportBibleItem, QtCore.QObject.connect(self.ImportBibleItem,
QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick) QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
@ -82,7 +82,7 @@ class BiblePlugin(Plugin):
self.ExportBibleItem.setObjectName(u'ExportBibleItem') self.ExportBibleItem.setObjectName(u'ExportBibleItem')
export_menu.addAction(self.ExportBibleItem) export_menu.addAction(self.ExportBibleItem)
self.ExportBibleItem.setText(translate( self.ExportBibleItem.setText(translate(
u'BiblePlugin', u'&Bible')) 'BiblePlugin', '&Bible'))
self.ExportBibleItem.setVisible(False) self.ExportBibleItem.setVisible(False)
def onBibleImportClick(self): def onBibleImportClick(self):
@ -90,10 +90,10 @@ class BiblePlugin(Plugin):
self.media_item.onImportClick() self.media_item.onImportClick()
def about(self): def about(self):
about_text = translate(u'BiblePlugin', about_text = translate('BiblePlugin',
u'<strong>Bible Plugin</strong><br />This ' '<strong>Bible Plugin</strong><br />This '
u'plugin allows bible verses from different sources to be ' 'plugin allows bible verses from different sources to be '
u'displayed on the screen during the service.') 'displayed on the screen during the service.')
return about_text return about_text
def can_delete_theme(self, theme): def can_delete_theme(self, theme):

View File

@ -309,77 +309,76 @@ class Ui_BibleImportWizard(object):
def retranslateUi(self, BibleImportWizard): def retranslateUi(self, BibleImportWizard):
BibleImportWizard.setWindowTitle( BibleImportWizard.setWindowTitle(
translate(u'BiblesPlugin.ImportWizardForm', u'Bible Import Wizard')) translate('BiblesPlugin.ImportWizardForm', 'Bible Import Wizard'))
self.TitleLabel.setText( self.TitleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \ u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Welcome to the Bible Import Wizard')) 'Welcome to the Bible Import Wizard'))
self.InformationLabel.setText( self.InformationLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'This wizard will help you to import Bibles from a ' 'This wizard will help you to import Bibles from a '
u'variety of formats. Click the next button below to start the ' 'variety of formats. Click the next button below to start the '
u'process by selecting a format to import from.')) 'process by selecting a format to import from.'))
self.SelectPage.setTitle(translate(u'BiblesPlugin.ImportWizardForm', self.SelectPage.setTitle(translate('BiblesPlugin.ImportWizardForm',
u'Select Import Source')) 'Select Import Source'))
self.SelectPage.setSubTitle( self.SelectPage.setSubTitle(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Select the import format, and where to import from.')) 'Select the import format, and where to import from.'))
self.FormatLabel.setText( self.FormatLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Format:')) translate('BiblesPlugin.ImportWizardForm', 'Format:'))
self.FormatComboBox.setItemText(0, self.FormatComboBox.setItemText(0,
translate(u'BiblesPlugin.ImportWizardForm', u'OSIS')) translate('BiblesPlugin.ImportWizardForm', 'OSIS'))
self.FormatComboBox.setItemText(1, self.FormatComboBox.setItemText(1,
translate(u'BiblesPlugin.ImportWizardForm', u'CSV')) translate('BiblesPlugin.ImportWizardForm', 'CSV'))
self.FormatComboBox.setItemText(2, self.FormatComboBox.setItemText(2,
translate(u'BiblesPlugin.ImportWizardForm', u'OpenSong')) translate('BiblesPlugin.ImportWizardForm', 'OpenSong'))
self.FormatComboBox.setItemText(3, self.FormatComboBox.setItemText(3,
translate(u'BiblesPlugin.ImportWizardForm', u'Web Download')) translate('BiblesPlugin.ImportWizardForm', 'Web Download'))
self.OsisLocationLabel.setText( self.OsisLocationLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'File Location:')) translate('BiblesPlugin.ImportWizardForm', 'File Location:'))
self.BooksLocationLabel.setText( self.BooksLocationLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Books Location:')) translate('BiblesPlugin.ImportWizardForm', 'Books Location:'))
self.VerseLocationLabel.setText( self.VerseLocationLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Verse Location:')) translate('BiblesPlugin.ImportWizardForm', 'Verse Location:'))
self.OpenSongFileLabel.setText( self.OpenSongFileLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Bible Filename:')) translate('BiblesPlugin.ImportWizardForm', 'Bible Filename:'))
self.LocationLabel.setText( self.LocationLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Location:')) translate('BiblesPlugin.ImportWizardForm', 'Location:'))
self.LocationComboBox.setItemText(0, self.LocationComboBox.setItemText(0,
translate(u'BiblesPlugin.ImportWizardForm', u'Crosswalk')) translate('BiblesPlugin.ImportWizardForm', 'Crosswalk'))
self.LocationComboBox.setItemText(1, self.LocationComboBox.setItemText(1,
translate(u'BiblesPlugin.ImportWizardForm', u'BibleGateway')) translate('BiblesPlugin.ImportWizardForm', 'BibleGateway'))
self.BibleLabel.setText( self.BibleLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Bible:')) translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
self.WebDownloadTabWidget.setTabText( self.WebDownloadTabWidget.setTabText(
self.WebDownloadTabWidget.indexOf(self.DownloadOptionsTab), self.WebDownloadTabWidget.indexOf(self.DownloadOptionsTab),
translate(u'BiblesPlugin.ImportWizardForm', u'Download Options')) translate('BiblesPlugin.ImportWizardForm', 'Download Options'))
self.AddressLabel.setText( self.AddressLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Server:')) translate('BiblesPlugin.ImportWizardForm', 'Server:'))
self.UsernameLabel.setText( self.UsernameLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Username:')) translate('BiblesPlugin.ImportWizardForm', 'Username:'))
self.PasswordLabel.setText( self.PasswordLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Password:')) translate('BiblesPlugin.ImportWizardForm', 'Password:'))
self.WebDownloadTabWidget.setTabText( self.WebDownloadTabWidget.setTabText(
self.WebDownloadTabWidget.indexOf(self.ProxyServerTab), self.WebDownloadTabWidget.indexOf(self.ProxyServerTab),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Proxy Server (Optional)')) 'Proxy Server (Optional)'))
self.LicenseDetailsPage.setTitle( self.LicenseDetailsPage.setTitle(
translate(u'BiblesPlugin.ImportWizardForm', u'License Details')) translate('BiblesPlugin.ImportWizardForm', 'License Details'))
self.LicenseDetailsPage.setSubTitle( self.LicenseDetailsPage.setSubTitle(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Set up the Bible\'s license details.')) 'Set up the Bible\'s license details.'))
self.VersionNameLabel.setText( self.VersionNameLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Version Name:')) translate('BiblesPlugin.ImportWizardForm', 'Version Name:'))
self.CopyrightLabel.setText( self.CopyrightLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Copyright:')) translate('BiblesPlugin.ImportWizardForm', 'Copyright:'))
self.PermissionLabel.setText( self.PermissionLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Permission:')) translate('BiblesPlugin.ImportWizardForm', 'Permission:'))
self.ImportPage.setTitle( self.ImportPage.setTitle(
translate(u'BiblesPlugin.ImportWizardForm', u'Importing')) translate('BiblesPlugin.ImportWizardForm', 'Importing'))
self.ImportPage.setSubTitle( self.ImportPage.setSubTitle(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Please wait while your Bible is imported.')) 'Please wait while your Bible is imported.'))
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Ready.')) translate('BiblesPlugin.ImportWizardForm', 'Ready.'))
self.ImportProgressBar.setFormat(u'%p%') self.ImportProgressBar.setFormat(u'%p%')

View File

@ -32,6 +32,7 @@ from PyQt4 import QtCore, QtGui
from bibleimportwizard import Ui_BibleImportWizard from bibleimportwizard import Ui_BibleImportWizard
from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.db import delete_database
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.manager import BibleFormat from openlp.plugins.bibles.lib.manager import BibleFormat
@ -123,32 +124,32 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS: if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
if self.field(u'osis_location').toString() == u'': if self.field(u'osis_location').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Invalid Bible Location'), 'Invalid Bible Location'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to specify a file to import your ' 'You need to specify a file to import your '
u'Bible from.'), 'Bible from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.OSISLocationEdit.setFocus() self.OSISLocationEdit.setFocus()
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if self.field(u'csv_booksfile').toString() == u'': if self.field(u'csv_booksfile').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Invalid Books File'), 'Invalid Books File'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to specify a file with books of ' 'You need to specify a file with books of '
u'the Bible to use in the import.'), 'the Bible to use in the import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.BooksLocationEdit.setFocus() self.BooksLocationEdit.setFocus()
return False return False
elif self.field(u'csv_versefile').toString() == u'': elif self.field(u'csv_versefile').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Invalid Verse File'), 'Invalid Verse File'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to specify a file of Bible ' 'You need to specify a file of Bible '
u'verses to import.'), 'verses to import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.CsvVerseLocationEdit.setFocus() self.CsvVerseLocationEdit.setFocus()
return False return False
@ -156,11 +157,11 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
BibleFormat.OpenSong: BibleFormat.OpenSong:
if self.field(u'opensong_file').toString() == u'': if self.field(u'opensong_file').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Invalid OpenSong Bible'), 'Invalid OpenSong Bible'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to specify an OpenSong Bible ' 'You need to specify an OpenSong Bible '
u'file to import.'), 'file to import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.OpenSongFileEdit.setFocus() self.OpenSongFileEdit.setFocus()
return False return False
@ -172,32 +173,32 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
unicode(self.field(u'license_copyright').toString()) unicode(self.field(u'license_copyright').toString())
if license_version == u'': if license_version == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Empty Version Name'), 'Empty Version Name'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to specify a version name for your ' 'You need to specify a version name for your '
u'Bible.'), 'Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False
elif license_copyright == u'': elif license_copyright == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Empty Copyright'), 'Empty Copyright'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'You need to set a copyright for your Bible! ' 'You need to set a copyright for your Bible! '
u'Bibles in the Public Domain need to be marked as ' 'Bibles in the Public Domain need to be marked as '
u'such.'), 'such.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.CopyrightEdit.setFocus() self.CopyrightEdit.setFocus()
return False return False
elif self.manager.exists(license_version): elif self.manager.exists(license_version):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Bible Exists'), 'Bible Exists'),
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'This Bible already exists! Please import ' 'This Bible already exists! Please import '
u'a different Bible or first delete the existing one.'), 'a different Bible or first delete the existing one.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False
@ -217,14 +218,14 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.BibleComboBox.clear() self.BibleComboBox.clear()
for bible in self.web_bible_list[index].keys(): for bible in self.web_bible_list[index].keys():
self.BibleComboBox.addItem(unicode( self.BibleComboBox.addItem(unicode(
translate(u'BiblesPlugin.ImportWizardForm', bible))) translate('BiblesPlugin.ImportWizardForm', bible)))
def onOsisFileButtonClicked(self): def onOsisFileButtonClicked(self):
""" """
Show the file open dialog for the OSIS file. Show the file open dialog for the OSIS file.
""" """
self.getFileName( self.getFileName(
translate(u'BiblesPlugin.ImportWizardForm', u'Open OSIS File'), translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
self.OSISLocationEdit) self.OSISLocationEdit)
def onBooksFileButtonClicked(self): def onBooksFileButtonClicked(self):
@ -232,24 +233,22 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
Show the file open dialog for the books CSV file. Show the file open dialog for the books CSV file.
""" """
self.getFileName( self.getFileName(
translate(u'BiblesPlugin.ImportWizardForm', u'Open Books CSV File'), translate('BiblesPlugin.ImportWizardForm', 'Open Books CSV File'),
self.BooksLocationEdit) self.BooksLocationEdit)
def onCsvVersesFileButtonClicked(self): def onCsvVersesFileButtonClicked(self):
""" """
Show the file open dialog for the verses CSV file. Show the file open dialog for the verses CSV file.
""" """
self.getFileName( self.getFileName(translate('BiblesPlugin.ImportWizardForm',
translate(u'BiblesPlugin.ImportWizardForm', 'Open Verses CSV File'), self.CsvVerseLocationEdit)
u'Open Verses CSV File'),
self.CsvVerseLocationEdit)
def onOpenSongBrowseButtonClicked(self): def onOpenSongBrowseButtonClicked(self):
""" """
Show the file open dialog for the OpenSong file. Show the file open dialog for the OpenSong file.
""" """
self.getFileName( self.getFileName(
translate(u'BiblesPlugin.ImportWizardForm', u'Open OpenSong Bible'), translate('BiblesPlugin.ImportWizardForm', 'Open OpenSong Bible'),
self.OpenSongFileEdit) self.OpenSongFileEdit)
def onCancelButtonClicked(self, checked): def onCancelButtonClicked(self, checked):
@ -389,7 +388,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setMaximum(1188)
self.ImportProgressBar.setValue(0) self.ImportProgressBar.setValue(0)
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', u'Starting import...')) translate('BiblesPlugin.ImportWizardForm', 'Starting import...'))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performImport(self):
@ -445,17 +444,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
license_copyright, license_permission) license_copyright, license_permission)
self.manager.reload_bibles() self.manager.reload_bibles()
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Finished import.')) 'Finished import.'))
else: else:
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
u'Your Bible import failed.')) 'Your Bible import failed.'))
importer.delete() delete_database(self.bibleplugin.settingsSection, importer.file)
def postImport(self): def postImport(self):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum()) self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
self.finishButton.setVisible(True) self.finishButton.setVisible(True)
self.cancelButton.setVisible(False) self.cancelButton.setVisible(False)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')

View File

@ -45,7 +45,7 @@ class BiblesTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'BiblesTab') self.setObjectName(u'BiblesTab')
self.tabTitleVisible = translate(u'BiblesPlugin,BiblesTab', u'Bibles') self.tabTitleVisible = translate('BiblesPlugin,BiblesTab', 'Bibles')
self.BibleLayout = QtGui.QHBoxLayout(self) self.BibleLayout = QtGui.QHBoxLayout(self)
self.BibleLayout.setSpacing(8) self.BibleLayout.setSpacing(8)
self.BibleLayout.setMargin(8) self.BibleLayout.setMargin(8)
@ -150,34 +150,34 @@ class BiblesTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.VerseDisplayGroupBox.setTitle( self.VerseDisplayGroupBox.setTitle(
translate(u'BiblesPlugin,BiblesTab', u'Verse Display')) translate('BiblesPlugin,BiblesTab', 'Verse Display'))
self.NewChaptersCheckBox.setText( self.NewChaptersCheckBox.setText(
translate(u'BiblesPlugin,BiblesTab', translate('BiblesPlugin,BiblesTab',
u'Only show new chapter numbers')) 'Only show new chapter numbers'))
self.LayoutStyleLabel.setText( self.LayoutStyleLabel.setText(
translate(u'BiblesPlugin,BiblesTab', u'Layout Style:')) translate('BiblesPlugin,BiblesTab', 'Layout Style:'))
self.DisplayStyleLabel.setText( self.DisplayStyleLabel.setText(
translate(u'BiblesPlugin,BiblesTab', u'Display Style:')) translate('BiblesPlugin,BiblesTab', 'Display Style:'))
self.BibleThemeLabel.setText( self.BibleThemeLabel.setText(
translate(u'BiblesPlugin,BiblesTab', u'Bible Theme:')) translate('BiblesPlugin,BiblesTab', 'Bible Theme:'))
self.LayoutStyleComboBox.setItemText(0, self.LayoutStyleComboBox.setItemText(0,
translate(u'BiblesPlugin,BiblesTab', u'verse per slide')) translate('BiblesPlugin,BiblesTab', 'verse per slide'))
self.LayoutStyleComboBox.setItemText(1, self.LayoutStyleComboBox.setItemText(1,
translate(u'BiblesPlugin,BiblesTab', u'verse per line')) translate('BiblesPlugin,BiblesTab', 'verse per line'))
self.LayoutStyleComboBox.setItemText(2, self.LayoutStyleComboBox.setItemText(2,
translate(u'BiblesPlugin,BiblesTab', u'continuous')) translate('BiblesPlugin,BiblesTab', 'continuous'))
self.DisplayStyleComboBox.setItemText(0, self.DisplayStyleComboBox.setItemText(0,
translate(u'BiblesPlugin,BiblesTab', u'No brackets')) translate('BiblesPlugin,BiblesTab', 'No brackets'))
self.DisplayStyleComboBox.setItemText(1, self.DisplayStyleComboBox.setItemText(1,
translate(u'BiblesPlugin,BiblesTab', u'( and )')) translate('BiblesPlugin,BiblesTab', '( and )'))
self.DisplayStyleComboBox.setItemText(2, self.DisplayStyleComboBox.setItemText(2,
translate(u'BiblesPlugin,BiblesTab', u'{ and }')) translate('BiblesPlugin,BiblesTab', '{ and }'))
self.DisplayStyleComboBox.setItemText(3, self.DisplayStyleComboBox.setItemText(3,
translate(u'BiblesPlugin,BiblesTab', u'[ and ]')) translate('BiblesPlugin,BiblesTab', '[ and ]'))
self.ChangeNoteLabel.setText(translate(u'BiblesPlugin.BiblesTab', self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
u'Note:\nChanges don\'t affect verses already in the service')) 'Note:\nChanges don\'t affect verses already in the service'))
self.BibleDualCheckBox.setText( self.BibleDualCheckBox.setText(
translate(u'BiblesPlugin,BiblesTab', u'Display Dual Bible Verses')) translate('BiblesPlugin,BiblesTab', 'Display Dual Bible Verses'))
def onBibleThemeComboBoxChanged(self): def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.BibleThemeComboBox.currentText() self.bible_theme = self.BibleThemeComboBox.currentText()

View File

@ -97,11 +97,11 @@ class CSVBible(BibleDB):
book_ptr = book.name book_ptr = book.name
self.wizard.incrementProgressBar( self.wizard.incrementProgressBar(
u'Importing %s %s' % (book.name, line[1])) u'Importing %s %s' % (book.name, line[1]))
self.commit() self.session.commit()
self.create_verse(book.id, line[1], line[2], self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding'])) unicode(line[3], details['encoding']))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.session.commit()
except IOError: except IOError:
log.exception(u'Loading verses from file failed') log.exception(u'Loading verses from file failed')
success = False success = False
@ -113,5 +113,3 @@ class CSVBible(BibleDB):
return False return False
else: else:
return success return success

View File

@ -23,20 +23,99 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import os
import logging import logging
import chardet import chardet
import re import re
from sqlalchemy import or_
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from sqlalchemy import Column, ForeignKey, or_, Table, types
from sqlalchemy.orm import class_mapper, mapper, relation
from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.bibles.lib.models import * from openlp.core.lib.db import BaseModel, init_db, Manager
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class BibleDB(QtCore.QObject): class BibleMeta(BaseModel):
"""
Bible Meta Data
"""
pass
class Testament(BaseModel):
"""
Bible Testaments
"""
pass
class Book(BaseModel):
"""
Song model
"""
pass
class Verse(BaseModel):
"""
Topic model
"""
pass
def init_schema(url):
"""
Setup a bible database connection and initialise the database schema
``url``
The database to setup
"""
session, metadata = init_db(url)
meta_table = Table(u'metadata', metadata,
Column(u'key', types.Unicode(255), primary_key=True, index=True),
Column(u'value', types.Unicode(255)),
)
testament_table = Table(u'testament', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'name', types.Unicode(50)),
)
book_table = Table(u'book', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
Column(u'name', types.Unicode(50), index=True),
Column(u'abbreviation', types.Unicode(5), index=True),
)
verse_table = Table(u'verse', metadata,
Column(u'id', types.Integer, primary_key=True, index=True),
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
Column(u'chapter', types.Integer, index=True),
Column(u'verse', types.Integer, index=True),
Column(u'text', types.UnicodeText, index=True),
)
try:
class_mapper(BibleMeta)
except UnmappedClassError:
mapper(BibleMeta, meta_table)
try:
class_mapper(Testament)
except UnmappedClassError:
mapper(Testament, testament_table,
properties={'books': relation(Book, backref='testament')})
try:
class_mapper(Book)
except UnmappedClassError:
mapper(Book, book_table,
properties={'verses': relation(Verse, backref='book')})
try:
class_mapper(Verse)
except UnmappedClassError:
mapper(Verse, verse_table)
metadata.create_all(checkfirst=True)
return session
class BibleDB(QtCore.QObject, Manager):
""" """
This class represents a database-bound Bible. It is used as a base class This class represents a database-bound Bible. It is used as a base class
for all the custom importers, so that the can implement their own import for all the custom importers, so that the can implement their own import
@ -73,26 +152,10 @@ class BibleDB(QtCore.QObject):
self.file = self.clean_filename(self.name) self.file = self.clean_filename(self.name)
if u'file' in kwargs: if u'file' in kwargs:
self.file = kwargs[u'file'] self.file = kwargs[u'file']
self.db_file = os.path.join(kwargs[u'path'], self.file) Manager.__init__(self, u'bibles', init_schema, self.file)
log.debug(u'Load bible %s on path %s', self.file, self.db_file)
settings = QtCore.QSettings()
settings.beginGroup(u'bibles')
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
db_url = u''
if db_type == u'sqlite':
db_url = u'sqlite:///' + self.db_file
else:
db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_models(db_url)
metadata.create_all(checkfirst=True)
if u'file' in kwargs: if u'file' in kwargs:
self.get_name() self.get_name()
self.wizard = None
def stop_import(self): def stop_import(self):
""" """
@ -105,7 +168,7 @@ class BibleDB(QtCore.QObject):
""" """
Returns the version name of the Bible. Returns the version name of the Bible.
""" """
version_name = self.get_meta(u'Version') version_name = self.get_object(BibleMeta, u'Version')
if version_name: if version_name:
self.name = version_name.value self.name = version_name.value
else: else:
@ -125,16 +188,6 @@ class BibleDB(QtCore.QObject):
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
return old_filename + u'.sqlite' return old_filename + u'.sqlite'
def delete(self):
"""
Remove the Bible database file. Used when a Bible import fails.
"""
try:
os.remove(self.db_file)
return True
except OSError:
return False
def register(self, wizard): def register(self, wizard):
""" """
This method basically just initialialises the database. It is called This method basically just initialialises the database. It is called
@ -146,36 +199,11 @@ class BibleDB(QtCore.QObject):
The actual Qt wizard form. The actual Qt wizard form.
""" """
self.wizard = wizard self.wizard = wizard
self.create_tables()
return self.name
def commit(self):
"""
Perform a database commit.
"""
log.debug('Committing...')
self.session.commit()
def create_tables(self):
"""
Create some initial metadata.
"""
log.debug(u'createTables')
self.create_meta(u'dbversion', u'2') self.create_meta(u'dbversion', u'2')
self.create_testament(u'Old Testament') self.save_object(Testament.populate(name=u'Old Testament'))
self.create_testament(u'New Testament') self.save_object(Testament.populate(name=u'New Testament'))
self.create_testament(u'Apocrypha') self.save_object(Testament.populate(name=u'Apocrypha'))
return self.name
def create_testament(self, testament):
"""
Add a testament to the database.
``testament``
The testament name.
"""
log.debug(u'BibleDB.create_testament("%s")', testament)
self.session.add(Testament.populate(name=testament))
self.commit()
def create_book(self, name, abbrev, testament=1): def create_book(self, name, abbrev, testament=1):
""" """
@ -193,8 +221,7 @@ class BibleDB(QtCore.QObject):
log.debug(u'create_book %s,%s', name, abbrev) log.debug(u'create_book %s,%s', name, abbrev)
book = Book.populate(name=name, abbreviation=abbrev, book = Book.populate(name=name, abbreviation=abbrev,
testament_id=testament) testament_id=testament)
self.session.add(book) self.save_object(book)
self.commit()
return book return book
def create_chapter(self, book_id, chapter, textlist): def create_chapter(self, book_id, chapter, textlist):
@ -221,7 +248,7 @@ class BibleDB(QtCore.QObject):
text = verse_text text = verse_text
) )
self.session.add(verse) self.session.add(verse)
self.commit() self.session.commit()
def create_verse(self, book_id, chapter, verse, text): def create_verse(self, book_id, chapter, verse, text):
""" """
@ -252,31 +279,32 @@ class BibleDB(QtCore.QObject):
return verse return verse
def create_meta(self, key, value): def create_meta(self, key, value):
log.debug(u'save_meta %s/%s', key, value) """
self.session.add(BibleMeta.populate(key=key, value=value)) Utility method to save BibleMeta objects in a Bible database
self.commit()
def get_books(self): ``key``
log.debug(u'BibleDB.get_books()') The key for this instance
return self.session.query(Book).order_by(Book.id).all()
``value``
The value for this instance
"""
log.debug(u'save_meta %s/%s', key, value)
self.save_object(BibleMeta.populate(key=key, value=value))
def get_book(self, book): def get_book(self, book):
log.debug(u'BibleDb.get_book("%s")', book) """
db_book = self.session.query(Book)\ Return a book object from the database
.filter(Book.name.like(book + u'%'))\
.first()
if db_book is None:
db_book = self.session.query(Book)\
.filter(Book.abbreviation.like(book + u'%'))\
.first()
return db_book
def get_chapter(self, id, chapter): ``book``
log.debug(u'BibleDB.get_chapter("%s", %s)', id, chapter) The name of the book to return
return self.session.query(Verse)\ """
.filter_by(chapter=chapter)\ log.debug(u'BibleDb.get_book("%s")', book)
.filter_by(book_id=id)\ db_book = self.session.query(Book).filter(
.first() Book.name.like(book + u'%')).first()
if db_book is None:
db_book = self.session.query(Book).filter(
Book.abbreviation.like(book + u'%')).first()
return db_book
def get_verses(self, reference_list): def get_verses(self, reference_list):
""" """
@ -316,11 +344,11 @@ class BibleDB(QtCore.QObject):
else: else:
log.debug(u'OpenLP failed to find book %s', book) log.debug(u'OpenLP failed to find book %s', book)
QtGui.QMessageBox.information(self.bible_plugin.media_item, QtGui.QMessageBox.information(self.bible_plugin.media_item,
translate(u'BibleDB', u'Book not found'), translate('BibleDB', 'Book not found'),
translate(u'BibleDB', u'The book you requested could not ' translate('BibleDB', u'The book you requested could not '
u'be found in this bible. Please check your spelling ' 'be found in this bible. Please check your spelling '
u'and that this is a complete bible not just one ' 'and that this is a complete bible not just one '
u'testament.')) 'testament.'))
return verse_list return verse_list
def verse_search(self, text): def verse_search(self, text):
@ -351,6 +379,12 @@ class BibleDB(QtCore.QObject):
return verses return verses
def get_chapter_count(self, book): def get_chapter_count(self, book):
"""
Return the number of chapters in a book
``book``
The book to get the chapter count for
"""
log.debug(u'BibleDB.get_chapter_count("%s")', book) log.debug(u'BibleDB.get_chapter_count("%s")', book)
count = self.session.query(Verse.chapter).join(Book)\ count = self.session.query(Verse.chapter).join(Book)\
.filter(Book.name==book)\ .filter(Book.name==book)\
@ -361,6 +395,15 @@ class BibleDB(QtCore.QObject):
return count return count
def get_verse_count(self, book, chapter): def get_verse_count(self, book, chapter):
"""
Return the number of verses in a chapter
``book``
The book containing the chapter
``chapter``
The chapter to get the verse count for
"""
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter) log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
count = self.session.query(Verse).join(Book)\ count = self.session.query(Verse).join(Book)\
.filter(Book.name==book)\ .filter(Book.name==book)\
@ -371,20 +414,10 @@ class BibleDB(QtCore.QObject):
else: else:
return count return count
def get_meta(self, key):
log.debug(u'get meta %s', key)
return self.session.query(BibleMeta).get(key)
def delete_meta(self, metakey):
biblemeta = self.get_meta(metakey)
try:
self.session.delete(biblemeta)
self.commit()
return True
except:
return False
def dump_bible(self): def dump_bible(self):
"""
Utility debugging method to dump the contents of a bible
"""
log.debug(u'.........Dumping Bible Database') log.debug(u'.........Dumping Bible Database')
log.debug('...............................Books ') log.debug('...............................Books ')
books = self.session.query(Book).all() books = self.session.query(Book).all()

View File

@ -35,8 +35,7 @@ from openlp.core.lib import Receiver
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \ from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \
unescape unescape
from openlp.plugins.bibles.lib.db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB, Book
from openlp.plugins.bibles.lib.models import Book
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -29,12 +29,12 @@ from PyQt4 import QtCore
from openlp.core.lib import SettingsManager from openlp.core.lib import SettingsManager
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB, Book, BibleMeta
from common import parse_reference from common import parse_reference
from opensong import OpenSongBible from opensong import OpenSongBible
from osis import OSISBible from osis import OSISBible
from csvbible import CSVBible from csvbible import CSVBible
from db import BibleDB
from http import HTTPBible from http import HTTPBible
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -137,11 +137,13 @@ class BibleManager(object):
log.debug(u'Bible Name: "%s"', name) log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible self.db_cache[name] = bible
# look to see if lazy load bible exists and get create getter. # look to see if lazy load bible exists and get create getter.
source = self.db_cache[name].get_meta(u'download source') source = self.db_cache[name].get_object(BibleMeta,
u'download source')
if source: if source:
download_name = \ download_name = self.db_cache[name].get_object(BibleMeta,
self.db_cache[name].get_meta(u'download name').value u'download name').value
meta_proxy = self.db_cache[name].get_meta(u'proxy url') meta_proxy = self.db_cache[name].get_object(BibleMeta,
u'proxy url')
web_bible = HTTPBible(self.parent, path=self.path, web_bible = HTTPBible(self.parent, path=self.path,
file=filename, download_source=source.value, file=filename, download_source=source.value,
download_name=download_name) download_name=download_name)
@ -196,7 +198,7 @@ class BibleManager(object):
u'name': book.name, u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(book.name) u'chapters': self.db_cache[bible].get_chapter_count(book.name)
} }
for book in self.db_cache[bible].get_books() for book in self.db_cache[bible].get_all_objects(Book, Book.id)
] ]
def get_chapter_count(self, bible, book): def get_chapter_count(self, bible, book):
@ -249,7 +251,7 @@ class BibleManager(object):
Returns the meta data for a given key Returns the meta data for a given key
""" """
log.debug(u'get_meta %s,%s', bible, key) log.debug(u'get_meta %s,%s', bible, key)
return self.db_cache[bible].get_meta(key) return self.db_cache[bible].get_object(BibleMeta, key)
def exists(self, name): def exists(self, name):
""" """

View File

@ -43,7 +43,8 @@ class BibleListView(BaseListWithDnD):
BaseListWithDnD.__init__(self, parent) BaseListWithDnD.__init__(self, parent)
def resizeEvent(self, event): def resizeEvent(self, event):
self.parent.onListViewResize(event.size().width(), event.size().width()) self.parent().onListViewResize(event.size().width(),
event.size().width())
class BibleMediaItem(MediaManagerItem): class BibleMediaItem(MediaManagerItem):
@ -70,7 +71,7 @@ class BibleMediaItem(MediaManagerItem):
return unicode(obj) return unicode(obj)
def initPluginNameVisible(self): def initPluginNameVisible(self):
self.PluginNameVisible = translate(u'BiblesPlugin.MediaItem', u'Bible') self.PluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -147,7 +148,7 @@ class BibleMediaItem(MediaManagerItem):
self.QuickMessage.setObjectName(u'QuickMessage') self.QuickMessage.setObjectName(u'QuickMessage')
self.QuickLayout.addWidget(self.QuickMessage, 6, 0, 1, 3) self.QuickLayout.addWidget(self.QuickMessage, 6, 0, 1, 3)
self.SearchTabWidget.addTab(self.QuickTab, self.SearchTabWidget.addTab(self.QuickTab,
translate(u'BiblesPlugin.MediaItem', u'Quick')) translate('BiblesPlugin.MediaItem', 'Quick'))
QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum, QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Expanding)
self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1) self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1)
@ -232,7 +233,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedMessage.setObjectName(u'AdvancedMessage') self.AdvancedMessage.setObjectName(u'AdvancedMessage')
self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3) self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3)
self.SearchTabWidget.addTab(self.AdvancedTab, self.SearchTabWidget.addTab(self.AdvancedTab,
translate(u'BiblesPlugin.MediaItem', u'Advanced')) translate('BiblesPlugin.MediaItem', 'Advanced'))
# Add the search tab widget to the page layout # Add the search tab widget to the page layout
self.PageLayout.addWidget(self.SearchTabWidget) self.PageLayout.addWidget(self.SearchTabWidget)
# Combo Boxes # Combo Boxes
@ -291,47 +292,47 @@ class BibleMediaItem(MediaManagerItem):
def retranslateUi(self): def retranslateUi(self):
log.debug(u'retranslateUi') log.debug(u'retranslateUi')
self.QuickVersionLabel.setText( self.QuickVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Version:')) translate('BiblesPlugin.MediaItem', 'Version:'))
self.QuickSecondVersionLabel.setText( self.QuickSecondVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Dual:')) translate('BiblesPlugin.MediaItem', 'Dual:'))
self.QuickSearchLabel.setText( self.QuickSearchLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Search Type:')) translate('BiblesPlugin.MediaItem', 'Search Type:'))
self.QuickSearchLabel.setText( self.QuickSearchLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Find:')) translate('BiblesPlugin.MediaItem', 'Find:'))
self.QuickSearchButton.setText( self.QuickSearchButton.setText(
translate(u'BiblesPlugin.MediaItem', u'Search')) translate('BiblesPlugin.MediaItem', 'Search'))
self.QuickClearLabel.setText( self.QuickClearLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Results:')) translate('BiblesPlugin.MediaItem', 'Results:'))
self.AdvancedVersionLabel.setText( self.AdvancedVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Version:')) translate('BiblesPlugin.MediaItem', 'Version:'))
self.AdvancedSecondBibleLabel.setText( self.AdvancedSecondBibleLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Dual:')) translate('BiblesPlugin.MediaItem', 'Dual:'))
self.AdvancedBookLabel.setText( self.AdvancedBookLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Book:')) translate('BiblesPlugin.MediaItem', 'Book:'))
self.AdvancedChapterLabel.setText( self.AdvancedChapterLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Chapter:')) translate('BiblesPlugin.MediaItem', 'Chapter:'))
self.AdvancedVerseLabel.setText( self.AdvancedVerseLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Verse:')) translate('BiblesPlugin.MediaItem', 'Verse:'))
self.AdvancedFromLabel.setText( self.AdvancedFromLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'From:')) translate('BiblesPlugin.MediaItem', 'From:'))
self.AdvancedToLabel.setText( self.AdvancedToLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'To:')) translate('BiblesPlugin.MediaItem', 'To:'))
self.AdvancedClearLabel.setText( self.AdvancedClearLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Results:')) translate('BiblesPlugin.MediaItem', 'Results:'))
self.AdvancedSearchButton.setText( self.AdvancedSearchButton.setText(
translate(u'BiblesPlugin.MediaItem', u'Search')) translate('BiblesPlugin.MediaItem', 'Search'))
self.QuickSearchComboBox.addItem( self.QuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Verse Search')) translate('BiblesPlugin.MediaItem', 'Verse Search'))
self.QuickSearchComboBox.addItem( self.QuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Text Search')) translate('BiblesPlugin.MediaItem', 'Text Search'))
self.ClearQuickSearchComboBox.addItem( self.ClearQuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Clear')) translate('BiblesPlugin.MediaItem', 'Clear'))
self.ClearQuickSearchComboBox.addItem( self.ClearQuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Keep')) translate('BiblesPlugin.MediaItem', 'Keep'))
self.ClearAdvancedSearchComboBox.addItem( self.ClearAdvancedSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Clear')) translate('BiblesPlugin.MediaItem', 'Clear'))
self.ClearAdvancedSearchComboBox.addItem( self.ClearAdvancedSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Keep')) translate('BiblesPlugin.MediaItem', 'Keep'))
def initialise(self): def initialise(self):
log.debug(u'bible manager initialise') log.debug(u'bible manager initialise')
@ -385,9 +386,9 @@ class BibleMediaItem(MediaManagerItem):
def onNoBookFound(self): def onNoBookFound(self):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.MediaItem', u'No Book Found'), translate('BiblesPlugin.MediaItem', 'No Book Found'),
translate(u'BiblesPlugin.MediaItem', translate('BiblesPlugin.MediaItem',
u'No matching book could be found in this Bible.'), 'No matching book could be found in this Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok QtGui.QMessageBox.Ok
) )
@ -556,9 +557,9 @@ class BibleMediaItem(MediaManagerItem):
if not service_item.title: if not service_item.title:
service_item.title = u'%s %s' % (book, verse_text) service_item.title = u'%s %s' % (book, verse_text)
elif service_item.title.find( elif service_item.title.find(
translate(u'BiblesPlugin.MediaItem', u'etc')) == -1: translate('BiblesPlugin.MediaItem', 'etc')) == -1:
service_item.title = u'%s, %s' % (service_item.title, service_item.title = u'%s, %s' % (service_item.title,
translate(u'BiblesPlugin.MediaItem', u'etc')) translate('BiblesPlugin.MediaItem', 'etc'))
if len(self.parent.settings_tab.bible_theme) == 0: if len(self.parent.settings_tab.bible_theme) == 0:
service_item.theme = None service_item.theme = None
else: else:
@ -612,7 +613,7 @@ class BibleMediaItem(MediaManagerItem):
if self.verses == 0: if self.verses == 0:
self.AdvancedSearchButton.setEnabled(False) self.AdvancedSearchButton.setEnabled(False)
self.AdvancedMessage.setText( self.AdvancedMessage.setText(
translate(u'BiblesPlugin.MediaItem', u'Bible not fully loaded')) translate('BiblesPlugin.MediaItem', 'Bible not fully loaded'))
else: else:
self.AdvancedSearchButton.setEnabled(True) self.AdvancedSearchButton.setEnabled(True)
self.AdvancedMessage.setText(u'') self.AdvancedMessage.setText(u'')
@ -660,4 +661,3 @@ class BibleMediaItem(MediaManagerItem):
def searchByReference(self, bible, search): def searchByReference(self, bible, search):
log.debug(u'searchByReference %s, %s', bible, search) log.debug(u'searchByReference %s, %s', bible, search)
self.search_results = self.parent.manager.get_verses(bible, search) self.search_results = self.parent.manager.get_verses(bible, search)

View File

@ -1,94 +0,0 @@
# -*- 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, 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 #
###############################################################################
from sqlalchemy import Column, Table, MetaData, ForeignKey, types, \
create_engine
from sqlalchemy.orm import mapper, relation, sessionmaker, scoped_session
from openlp.core.lib import BaseModel
class BibleMeta(BaseModel):
"""
Bible Meta Data
"""
pass
class Testament(BaseModel):
"""
Bible Testaments
"""
pass
class Book(BaseModel):
"""
Song model
"""
pass
class Verse(BaseModel):
"""
Topic model
"""
pass
def init_models(db_url):
engine = create_engine(db_url)
metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine))
return session
metadata = MetaData()
meta_table = Table(u'metadata', metadata,
Column(u'key', types.Unicode(255), primary_key=True, index=True),
Column(u'value', types.Unicode(255)),
)
testament_table = Table(u'testament', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'name', types.Unicode(50)),
)
book_table = Table(u'book', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
Column(u'name', types.Unicode(50), index=True),
Column(u'abbreviation', types.Unicode(5), index=True),
)
verse_table = Table(u'verse', metadata,
Column(u'id', types.Integer, primary_key=True, index=True),
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
Column(u'chapter', types.Integer, index=True),
Column(u'verse', types.Integer, index=True),
Column(u'text', types.UnicodeText, index=True),
)
mapper(BibleMeta, meta_table)
mapper(Testament, testament_table,
properties={'books': relation(Book, backref='testament')})
mapper(Book, book_table,
properties={'verses': relation(Verse, backref='book')})
mapper(Verse, verse_table)

View File

@ -88,9 +88,9 @@ class OpenSongBible(BibleDB):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar( self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % ( QtCore.QString('%s %s %s' % (
translate(u'BiblesPlugin.Opensong', u'Importing'), \ translate('BiblesPlugin.Opensong', 'Importing'), \
db_book.name, chapter.attrib[u'n']))) db_book.name, chapter.attrib[u'n'])))
self.commit() self.session.commit()
except IOError: except IOError:
log.exception(u'Loading bible from OpenSong file failed') log.exception(u'Loading bible from OpenSong file failed')
success = False success = False
@ -103,4 +103,3 @@ class OpenSongBible(BibleDB):
else: else:
return success return success

View File

@ -62,10 +62,14 @@ class OSISBible(BibleDB):
self.fi_regex = re.compile(r'<FI>(.*?)<Fi>') self.fi_regex = re.compile(r'<FI>(.*?)<Fi>')
self.rf_regex = re.compile(r'<RF>(.*?)<Rf>') self.rf_regex = re.compile(r'<RF>(.*?)<Rf>')
self.lb_regex = re.compile(r'<lb(.*?)>') self.lb_regex = re.compile(r'<lb(.*?)>')
self.lg_regex = re.compile(r'<lg(.*?)>')
self.l_regex = re.compile(r'<l (.*?)>') self.l_regex = re.compile(r'<l (.*?)>')
self.w_regex = re.compile(r'<w (.*?)>') self.w_regex = re.compile(r'<w (.*?)>')
self.q_regex = re.compile(r'<q (.*?)>') self.q1_regex = re.compile(r'<q(.*?)level="1"(.*?)>')
self.q2_regex = re.compile(r'<q(.*?)level="2"(.*?)>')
self.trans_regex = re.compile(r'<transChange(.*?)>(.*?)</transChange>') self.trans_regex = re.compile(r'<transChange(.*?)>(.*?)</transChange>')
self.divineName_regex = re.compile(
r'<divineName(.*?)>(.*?)</divineName>')
self.spaces_regex = re.compile(r'([ ]{2,})') self.spaces_regex = re.compile(r'([ ]{2,})')
self.books = {} self.books = {}
filepath = os.path.join( filepath = os.path.join(
@ -96,7 +100,7 @@ class OSISBible(BibleDB):
detect_file = None detect_file = None
try: try:
detect_file = open(self.filename, u'r') detect_file = open(self.filename, u'r')
details = chardet.detect(detect_file.read()) details = chardet.detect(detect_file.read(1048576))
except IOError: except IOError:
log.exception(u'Failed to detect OSIS file encoding') log.exception(u'Failed to detect OSIS file encoding')
return return
@ -136,7 +140,7 @@ class OSISBible(BibleDB):
self.wizard.ImportProgressBar.setMaximum(260) self.wizard.ImportProgressBar.setMaximum(260)
if last_chapter != chapter: if last_chapter != chapter:
if last_chapter != 0: if last_chapter != 0:
self.commit() self.session.commit()
self.wizard.incrementProgressBar( self.wizard.incrementProgressBar(
u'Importing %s %s...' % \ u'Importing %s %s...' % \
(self.books[match.group(1)][0], chapter)) (self.books[match.group(1)][0], chapter))
@ -151,10 +155,13 @@ class OSISBible(BibleDB):
verse_text = self.fi_regex.sub(u'', verse_text) verse_text = self.fi_regex.sub(u'', verse_text)
verse_text = self.rf_regex.sub(u'', verse_text) verse_text = self.rf_regex.sub(u'', verse_text)
verse_text = self.lb_regex.sub(u' ', verse_text) verse_text = self.lb_regex.sub(u' ', verse_text)
verse_text = self.lg_regex.sub(u'', verse_text)
verse_text = self.l_regex.sub(u'', verse_text) verse_text = self.l_regex.sub(u'', verse_text)
verse_text = self.w_regex.sub(u'', verse_text) verse_text = self.w_regex.sub(u'', verse_text)
verse_text = self.q_regex.sub(u'', verse_text) verse_text = self.q1_regex.sub(u'"', verse_text)
verse_text = self.q2_regex.sub(u'\'', verse_text)
verse_text = self.trans_regex.sub(u'', verse_text) verse_text = self.trans_regex.sub(u'', verse_text)
verse_text = self.divineName_regex.sub(u'', verse_text)
verse_text = verse_text.replace(u'</lb>', u'')\ verse_text = verse_text.replace(u'</lb>', u'')\
.replace(u'</l>', u'').replace(u'<lg>', u'')\ .replace(u'</l>', u'').replace(u'<lg>', u'')\
.replace(u'</lg>', u'').replace(u'</q>', u'')\ .replace(u'</lg>', u'').replace(u'</q>', u'')\
@ -162,7 +169,7 @@ class OSISBible(BibleDB):
verse_text = self.spaces_regex.sub(u' ', verse_text) verse_text = self.spaces_regex.sub(u' ', verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text) self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.session.commit()
self.wizard.incrementProgressBar(u'Finishing import...') self.wizard.incrementProgressBar(u'Finishing import...')
if match_count == 0: if match_count == 0:
success = False success = False

View File

@ -22,3 +22,8 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`custom` module provides the Custom plugin which allows custom,
themed, text based items to be displayed without having to misuse another item
type.
"""

View File

@ -26,8 +26,11 @@
import logging import logging
from forms import EditCustomForm from forms import EditCustomForm
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.plugins.custom.lib import CustomManager, CustomMediaItem, CustomTab from openlp.core.lib.db import Manager
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -43,9 +46,9 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded') log.info(u'Custom Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Custom', u'1.9.2', plugin_helpers)
self.weight = -5 self.weight = -5
self.custommanager = CustomManager() self.custommanager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.custommanager) self.edit_custom_form = EditCustomForm(self.custommanager)
self.icon = build_icon(u':/media/media_custom.png') self.icon = build_icon(u':/media/media_custom.png')
self.status = PluginStatus.Active self.status = PluginStatus.Active
@ -67,14 +70,16 @@ class CustomPlugin(Plugin):
self.remove_toolbox_item() self.remove_toolbox_item()
def about(self): def about(self):
about_text = translate(u'CustomPlugin', about_text = translate('CustomPlugin',
u'<b>Custom Plugin</b><br>This plugin ' '<b>Custom Plugin</b><br>This plugin '
u'allows slides to be displayed on the screen in the same way ' 'allows slides to be displayed on the screen in the same way '
u'songs are. This plugin provides greater freedom over the ' 'songs are. This plugin provides greater freedom over the '
u'songs plugin.<br>') 'songs plugin.<br>')
return about_text return about_text
def can_delete_theme(self, theme): def can_delete_theme(self, theme):
if len(self.custommanager.get_customs_for_theme(theme)) == 0: filter_string = u'theme_name=\'%s\'' % theme
if not self.custommanager.get_all_objects_filtered(CustomSlide,
filter_string):
return True return True
return False return False

View File

@ -43,6 +43,7 @@ class Ui_customEditDialog(object):
self.TitleLabel.setObjectName(u'TitleLabel') self.TitleLabel.setObjectName(u'TitleLabel')
self.horizontalLayout.addWidget(self.TitleLabel) self.horizontalLayout.addWidget(self.TitleLabel)
self.TitleEdit = QtGui.QLineEdit(customEditDialog) self.TitleEdit = QtGui.QLineEdit(customEditDialog)
self.TitleLabel.setBuddy(self.TitleEdit)
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)
@ -118,6 +119,7 @@ class Ui_customEditDialog(object):
self.ThemeLabel.setObjectName(u'ThemeLabel') self.ThemeLabel.setObjectName(u'ThemeLabel')
self.horizontalLayout_3.addWidget(self.ThemeLabel) self.horizontalLayout_3.addWidget(self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(customEditDialog) self.ThemeComboBox = QtGui.QComboBox(customEditDialog)
self.ThemeLabel.setBuddy(self.ThemeComboBox)
self.ThemeComboBox.setObjectName(u'ThemeComboBox') self.ThemeComboBox.setObjectName(u'ThemeComboBox')
self.horizontalLayout_3.addWidget(self.ThemeComboBox) self.horizontalLayout_3.addWidget(self.ThemeComboBox)
self.gridLayout.addLayout(self.horizontalLayout_3, 3, 0, 1, 1) self.gridLayout.addLayout(self.horizontalLayout_3, 3, 0, 1, 1)
@ -127,6 +129,7 @@ class Ui_customEditDialog(object):
self.CreditLabel.setObjectName(u'CreditLabel') self.CreditLabel.setObjectName(u'CreditLabel')
self.horizontalLayout_2.addWidget(self.CreditLabel) self.horizontalLayout_2.addWidget(self.CreditLabel)
self.CreditEdit = QtGui.QLineEdit(customEditDialog) self.CreditEdit = QtGui.QLineEdit(customEditDialog)
self.CreditLabel.setBuddy(self.CreditEdit)
self.CreditEdit.setObjectName(u'CreditEdit') self.CreditEdit.setObjectName(u'CreditEdit')
self.horizontalLayout_2.addWidget(self.CreditEdit) self.horizontalLayout_2.addWidget(self.CreditEdit)
self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
@ -162,7 +165,7 @@ class Ui_customEditDialog(object):
self.DownButton.setToolTip( self.DownButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down 1')) translate('CustomPlugin.EditCustomForm', 'Move slide down 1'))
self.TitleLabel.setText( self.TitleLabel.setText(
translate('CustomPlugin.EditCustomForm', 'Title:')) translate('CustomPlugin.EditCustomForm', '&Title:'))
self.AddButton.setText( self.AddButton.setText(
translate('CustomPlugin.EditCustomForm', 'Add New')) translate('CustomPlugin.EditCustomForm', 'Add New'))
self.AddButton.setToolTip( self.AddButton.setToolTip(
@ -192,7 +195,7 @@ class Ui_customEditDialog(object):
self.SplitButton.setToolTip( self.SplitButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add slide split')) translate('CustomPlugin.EditCustomForm', 'Add slide split'))
self.ThemeLabel.setText( self.ThemeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'Theme:')) translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.CreditLabel.setText( self.CreditLabel.setText(
translate('CustomPlugin.EditCustomForm', 'Credits:')) translate('CustomPlugin.EditCustomForm', '&Credits:'))

View File

@ -29,7 +29,7 @@ from PyQt4 import QtCore, QtGui
from editcustomdialog import Ui_customEditDialog from editcustomdialog import Ui_customEditDialog
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
from openlp.plugins.custom.lib.models import CustomSlide from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -85,9 +85,8 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
def onPreview(self, button): def onPreview(self, button):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == \ if button.text() == unicode(translate('CustomPlugin.EditCustomForm',
unicode(translate('CustomPlugin.EditCustomForm', 'Save && Preview')) \ 'Save && Preview')) and self.saveCustom():
and self.saveCustom():
Receiver.send_message(u'custom_preview') Receiver.send_message(u'custom_preview')
def initialise(self): def initialise(self):
@ -117,7 +116,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_custom(id) self.customSlide = self.custommanager.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)
songXML = SongXMLParser(self.customSlide.text) songXML = SongXMLParser(self.customSlide.text)
@ -167,8 +166,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
u'utf-8') u'utf-8')
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(), self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
u'utf-8') u'utf-8')
self.custommanager.save_slide(self.customSlide) return self.custommanager.save_object(self.customSlide)
return True
def onUpButtonPressed(self): def onUpButtonPressed(self):
selectedRow = self.VerseListView.currentRow() selectedRow = self.VerseListView.currentRow()

View File

@ -23,6 +23,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from manager import CustomManager
from mediaitem import CustomMediaItem from mediaitem import CustomMediaItem
from customtab import CustomTab from customtab import CustomTab

View File

@ -1,32 +0,0 @@
# -*- 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, 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 #
###############################################################################
from openlp.core.lib import BaseModel
class CustomSlide(BaseModel):
"""
Custom Slide model
"""
pass

View File

@ -36,7 +36,7 @@ class CustomTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'CustomTab') self.setObjectName(u'CustomTab')
self.tabTitleVisible = translate(u'CustomPlugin.CustomTab', u'Custom') self.tabTitleVisible = translate('CustomPlugin.CustomTab', 'Custom')
self.CustomLayout = QtGui.QFormLayout(self) self.CustomLayout = QtGui.QFormLayout(self)
self.CustomLayout.setObjectName(u'CustomLayout') self.CustomLayout.setObjectName(u'CustomLayout')
self.CustomModeGroupBox = QtGui.QGroupBox(self) self.CustomModeGroupBox = QtGui.QGroupBox(self)
@ -55,10 +55,10 @@ class CustomTab(SettingsTab):
self.onDisplayFooterCheckBoxChanged) self.onDisplayFooterCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.CustomModeGroupBox.setTitle(translate(u'CustomPlugin.CustomTab', self.CustomModeGroupBox.setTitle(translate('CustomPlugin.CustomTab',
u'Custom Display')) 'Custom Display'))
self.DisplayFooterCheckBox.setText( self.DisplayFooterCheckBox.setText(
translate(u'CustomPlugin.CustomTab', u'Display Footer')) translate('CustomPlugin.CustomTab', 'Display Footer'))
def onDisplayFooterCheckBoxChanged(self, check_state): def onDisplayFooterCheckBoxChanged(self, check_state):
self.displayFooter = False self.displayFooter = False

View File

@ -22,18 +22,40 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`db` module provides the database and schema that is the backend for
the Custom plugin
"""
from sqlalchemy import create_engine from sqlalchemy import Column, Table, types
from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.orm import mapper
from openlp.plugins.custom.lib.meta import metadata from openlp.core.lib.db import BaseModel, init_db
from openlp.plugins.custom.lib.tables import *
from openlp.plugins.custom.lib.classes import * class CustomSlide(BaseModel):
"""
CustomSlide model
"""
pass
def init_schema(url):
"""
Setup the custom database connection and initialise the database schema
``url``
The database to setup
"""
session, metadata = init_db(url)
custom_slide_table = Table(u'custom_slide', metadata,
Column(u'id', types.Integer(), primary_key=True),
Column(u'title', types.Unicode(255), nullable=False),
Column(u'text', types.UnicodeText, nullable=False),
Column(u'credits', types.UnicodeText),
Column(u'theme_name', types.Unicode(128))
)
def init_models(url):
engine = create_engine(url)
metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine))
mapper(CustomSlide, custom_slide_table) mapper(CustomSlide, custom_slide_table)
metadata.create_all(checkfirst=True)
return session return session

View File

@ -1,117 +0,0 @@
# -*- 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, 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 #
###############################################################################
import logging
from PyQt4 import QtCore
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.custom.lib.models import init_models, metadata, CustomSlide
log = logging.getLogger(__name__)
class CustomManager(object):
"""
The Song Manager provides a central location for all database code. This
class takes care of connecting to the database and running all the queries.
"""
log.info(u'Custom manager loaded')
def __init__(self):
"""
Creates the connection to the database, and creates the tables if they
don't exist.
"""
log.debug(u'Custom Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'custom')
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/custom.sqlite' % \
AppLocation.get_section_data_path(u'custom')
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True)
settings.endGroup()
log.debug(u'Custom Initialised')
def get_all_slides(self):
"""
Returns the details of a Custom Slide Show
"""
return self.session.query(CustomSlide).order_by(CustomSlide.title).all()
def save_slide(self, customslide):
"""
Saves a Custom slide show to the database
"""
log.debug(u'Custom Slide added')
try:
self.session.add(customslide)
self.session.commit()
log.debug(u'Custom Slide saved')
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Custom Slide save failed')
return False
def get_custom(self, id=None):
"""
Returns the details of a Custom Slide
"""
if id is None:
return CustomSlide()
else:
return self.session.query(CustomSlide).get(id)
def delete_custom(self, id):
"""
Delete a Custom slide show
"""
if id != 0:
customslide = self.get_custom(id)
try:
self.session.delete(customslide)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Custom Slide deleton failed')
return False
else:
return True
def get_customs_for_theme(self, theme):
return self.session.query(
CustomSlide).filter(CustomSlide.theme_name == theme).all()

View File

@ -28,7 +28,8 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \ from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
Receiver, ItemCapabilities, translate Receiver, ItemCapabilities, translate, check_item_selected
from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -66,13 +67,14 @@ class CustomMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def initPluginNameVisible(self): def initPluginNameVisible(self):
self.PluginNameVisible = translate(u'CustomPlugin.MediaItem', u'Custom') self.PluginNameVisible = translate('CustomPlugin.MediaItem', 'Custom')
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
def initialise(self): def initialise(self):
self.loadCustomListView(self.parent.custommanager.get_all_slides()) self.loadCustomListView(self.parent.custommanager.get_all_objects(
CustomSlide, 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
#Trigger it and clean up so it will not update again. #Trigger it and clean up so it will not update again.
@ -84,10 +86,10 @@ class CustomMediaItem(MediaManagerItem):
def loadCustomListView(self, list): def loadCustomListView(self, list):
self.ListView.clear() self.ListView.clear()
for CustomSlide in list: for customSlide in list:
custom_name = QtGui.QListWidgetItem(CustomSlide.title) custom_name = QtGui.QListWidgetItem(customSlide.title)
custom_name.setData( custom_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id)) QtCore.Qt.UserRole, QtCore.QVariant(customSlide.id))
self.ListView.addItem(custom_name) self.ListView.addItem(custom_name)
def onNewClick(self): def onNewClick(self):
@ -106,7 +108,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_custom(fields[1]) valid = self.parent.custommanager.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]
@ -118,8 +120,9 @@ class CustomMediaItem(MediaManagerItem):
""" """
Edit a custom item Edit a custom item
""" """
if self.checkItemSelected(translate(u'CustomPlugin.MediaItem', if check_item_selected(self.ListView,
u'You must select an item to edit.')): translate('CustomPlugin.MediaItem',
'You must select an item to edit.')):
item = self.ListView.currentItem() item = self.ListView.currentItem()
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.edit_custom_form.loadCustom(item_id, False) self.parent.edit_custom_form.loadCustom(item_id, False)
@ -130,12 +133,16 @@ class CustomMediaItem(MediaManagerItem):
""" """
Remove a custom item from the list and database Remove a custom item from the list and database
""" """
if self.checkItemSelected(translate(u'CustomPlugin.MediaItem', if check_item_selected(self.ListView,
u'You must select an item to delete.')): translate('CustomPlugin.MediaItem',
item = self.ListView.currentItem() 'You must select an item to delete.')):
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] row_list = [item.row() for item in self.ListView.selectedIndexes()]
self.parent.custommanager.delete_custom(item_id) row_list.sort(reverse=True)
row = self.ListView.row(item) id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]
for item in self.ListView.selectedIndexes()]
for id in id_list:
self.parent.custommanager.delete_custom(id)
for row in row_list:
self.ListView.takeItem(row) self.ListView.takeItem(row)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
@ -156,7 +163,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_custom(item_id) customSlide = self.parent.custommanager.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

@ -1,37 +0,0 @@
# -*- 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, 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 #
###############################################################################
from sqlalchemy import Column, Table, types
from openlp.plugins.custom.lib.meta import metadata
# Definition of the "custom slide" table
custom_slide_table = Table(u'custom_slide', metadata,
Column(u'id', types.Integer(), primary_key=True),
Column(u'title', types.Unicode(255), nullable=False),
Column(u'text', types.UnicodeText, nullable=False),
Column(u'credits', types.UnicodeText),
Column(u'theme_name', types.Unicode(128))
)

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`images` module provides the Images plugin. The Images plugin
provides the facility to display images from OpenLP.
"""

View File

@ -34,7 +34,7 @@ class ImagePlugin(Plugin):
log.info(u'Image Plugin loaded') log.info(u'Image Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Images', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Images', u'1.9.2', plugin_helpers)
self.weight = -7 self.weight = -7
self.icon = build_icon(u':/media/media_image.png') self.icon = build_icon(u':/media/media_image.png')
self.status = PluginStatus.Active self.status = PluginStatus.Active

View File

@ -29,7 +29,8 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
context_menu_action, ItemCapabilities, SettingsManager, translate context_menu_action, ItemCapabilities, SettingsManager, translate, \
check_item_selected
from openlp.core.utils import AppLocation, get_images_filter from openlp.core.utils import AppLocation, get_images_filter
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -116,11 +117,12 @@ class ImageMediaItem(MediaManagerItem):
""" """
Remove an image item from the list Remove an image item from the list
""" """
if self.checkItemSelected(translate('ImagePlugin.MediaItem', if check_item_selected(self.ListView, translate('ImagePlugin.MediaItem',
'You must select an item to delete.')): 'You must select an item to delete.')):
items = self.ListView.selectedIndexes() row_list = [item.row() for item in self.ListView.selectedIndexes()]
for item in items: row_list.sort(reverse=True)
text = self.ListView.item(item.row()) for row in row_list:
text = self.ListView.item(row)
if text: if text:
try: try:
os.remove(os.path.join(self.servicePath, os.remove(os.path.join(self.servicePath,
@ -128,7 +130,7 @@ class ImageMediaItem(MediaManagerItem):
except OSError: except OSError:
#if not present do not worry #if not present do not worry
pass pass
self.ListView.takeItem(item.row()) self.ListView.takeItem(row)
SettingsManager.set_list(self.settingsSection, SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())

View File

@ -22,3 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`media` module provides the Media plugin which allows OpenLP to
display videos. The media supported depends not only on the Python support
but also extensively on the codecs installed on the underlying operating system
being picked up and usable by Python.
"""

View File

@ -29,7 +29,7 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate ItemCapabilities, SettingsManager, translate, check_item_selected
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -141,10 +141,11 @@ class MediaMediaItem(MediaManagerItem):
""" """
Remove a media item from the list Remove a media item from the list
""" """
if self.checkItemSelected(translate('MediaPlugin.MediaItem', if check_item_selected(self.ListView, translate('MediaPlugin.MediaItem',
'You must select an item to delete.')): 'You must select an item to delete.')):
item = self.ListView.currentItem() row_list = [item.row() for item in self.ListView.selectedIndexes()]
row = self.ListView.row(item) row_list.sort(reverse=True)
for row in row_list:
self.ListView.takeItem(row) self.ListView.takeItem(row)
SettingsManager.set_list(self.settingsSection, SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())

View File

@ -36,7 +36,7 @@ class MediaPlugin(Plugin):
log.info(u'%s MediaPlugin loaded', __name__) log.info(u'%s MediaPlugin loaded', __name__)
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Media', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Media', u'1.9.2', plugin_helpers)
self.weight = -6 self.weight = -6
self.icon = build_icon(u':/media/media_video.png') self.icon = build_icon(u':/media/media_video.png')
# passed with drag and drop messages # passed with drag and drop messages
@ -85,4 +85,3 @@ class MediaPlugin(Plugin):
'<b>Media Plugin</b><br>This plugin ' '<b>Media Plugin</b><br>This plugin '
'allows the playing of audio and video media') 'allows the playing of audio and video media')
return about_text return about_text

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`presentations` module provides the Presentations plugin which allows
OpenLP to show presentations from most popular presentation packages.
"""

View File

@ -41,9 +41,14 @@ from openlp.core.lib import resize_image
if os.name == u'nt': if os.name == u'nt':
from win32com.client import Dispatch from win32com.client import Dispatch
import pywintypes
else: else:
try:
import uno import uno
from com.sun.star.beans import PropertyValue from com.sun.star.beans import PropertyValue
uno_available = True
except ImportError:
uno_available = False
from PyQt4 import QtCore from PyQt4 import QtCore
@ -78,9 +83,7 @@ class ImpressController(PresentationController):
if os.name == u'nt': if os.name == u'nt':
return self.get_com_servicemanager() is not None return self.get_com_servicemanager() is not None
else: else:
# If not windows, and we've got this far then probably return uno_available
# installed else the import uno would likely have failed
return True
def start_process(self): def start_process(self):
""" """
@ -132,18 +135,13 @@ class ImpressController(PresentationController):
def get_com_desktop(self): def get_com_desktop(self):
log.debug(u'get COM Desktop OpenOffice') log.debug(u'get COM Desktop OpenOffice')
try: return self.manager.createInstance(u'com.sun.star.frame.Desktop')
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
return desktop
except:
log.exception(u'Failed to get COM desktop')
return None
def get_com_servicemanager(self): def get_com_servicemanager(self):
log.debug(u'get_com_servicemanager openoffice') log.debug(u'get_com_servicemanager openoffice')
try: try:
return Dispatch(u'com.sun.star.ServiceManager') return Dispatch(u'com.sun.star.ServiceManager')
except: except pywintypes.com_error:
log.exception(u'Failed to get COM service manager') log.exception(u'Failed to get COM service manager')
return None return None
@ -327,11 +325,17 @@ class ImpressDocument(PresentationDocument):
Returns true if screen is blank Returns true if screen is blank
""" """
log.debug(u'is blank OpenOffice') log.debug(u'is blank OpenOffice')
if self.control:
return self.control.isPaused() return self.control.isPaused()
else:
return False
def stop_presentation(self): def stop_presentation(self):
log.debug(u'stop presentation OpenOffice') log.debug(u'stop presentation OpenOffice')
self.control.deactivate() # deactivate should hide the screen according to docs, but doesn't
#self.control.deactivate()
self.presentation.end()
self.control = None
def start_presentation(self): def start_presentation(self):
log.debug(u'start presentation OpenOffice') log.debug(u'start presentation OpenOffice')

View File

@ -29,7 +29,7 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
SettingsManager, translate SettingsManager, translate, check_item_selected
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
@ -61,14 +61,14 @@ class PresentationMediaItem(MediaManagerItem):
self.message_listener = MessageListener(self) self.message_listener = MessageListener(self)
def initPluginNameVisible(self): def initPluginNameVisible(self):
self.PluginNameVisible = translate(u'PresentationPlugin.MediaItem', self.PluginNameVisible = translate('PresentationPlugin.MediaItem',
u'Presentation') 'Presentation')
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = translate(u'PresentationPlugin.MediaItem', self.OnNewPrompt = translate('PresentationPlugin.MediaItem',
u'Select Presentation(s)') 'Select Presentation(s)')
self.Automatic = translate(u'PresentationPlugin.MediaItem', self.Automatic = translate('PresentationPlugin.MediaItem',
u'Automatic') 'Automatic')
fileType = u'' fileType = u''
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled: if self.controllers[controller].enabled:
@ -78,8 +78,8 @@ class PresentationMediaItem(MediaManagerItem):
if fileType.find(type) == -1: if fileType.find(type) == -1:
fileType += u'*%s ' % type fileType += u'*%s ' % type
self.parent.service_manager.supportedSuffixes(type) self.parent.service_manager.supportedSuffixes(type)
self.OnNewFileMasks = translate(u'PresentationPlugin.MediaItem', self.OnNewFileMasks = translate('PresentationPlugin.MediaItem',
u'Presentations (%s)' % fileType) 'Presentations (%s)' % fileType)
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -106,7 +106,7 @@ class PresentationMediaItem(MediaManagerItem):
self.DisplayTypeLabel.setObjectName(u'SearchTypeLabel') self.DisplayTypeLabel.setObjectName(u'SearchTypeLabel')
self.DisplayLayout.addWidget(self.DisplayTypeLabel, 0, 0, 1, 1) self.DisplayLayout.addWidget(self.DisplayTypeLabel, 0, 0, 1, 1)
self.DisplayTypeLabel.setText( self.DisplayTypeLabel.setText(
translate(u'PresentationPlugin.MediaItem', u'Present using:')) translate('PresentationPlugin.MediaItem', 'Present using:'))
# Add the Presentation widget to the page layout # Add the Presentation widget to the page layout
self.PageLayout.addWidget(self.PresentationWidget) self.PageLayout.addWidget(self.PresentationWidget)
@ -139,10 +139,10 @@ class PresentationMediaItem(MediaManagerItem):
filename = os.path.split(unicode(file))[1] filename = os.path.split(unicode(file))[1]
if titles.count(filename) > 0: if titles.count(filename) > 0:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'PresentationPlugin.MediaItem', self, translate('PresentationPlugin.MediaItem',
u'File exists'), 'File exists'),
translate(u'PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
u'A presentation with that filename already exists.'), 'A presentation with that filename already exists.'),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
else: else:
icon = None icon = None
@ -177,20 +177,25 @@ class PresentationMediaItem(MediaManagerItem):
""" """
Remove a presentation item from the list Remove a presentation item from the list
""" """
if self.checkItemSelected(translate(u'PresentationPlugin.MediaItem', if check_item_selected(self.ListView,
u'You must select an item to delete.')): translate('PresentationPlugin.MediaItem',
item = self.ListView.currentItem() 'You must select an item to delete.')):
row = self.ListView.row(item) items = self.ListView.selectedIndexes()
self.ListView.takeItem(row) row_list = [item.row() for item in items]
SettingsManager.set_list(self.settingsSection, row_list.sort(reverse=True)
self.settingsSection, self.getFileList()) for item in items:
filepath = unicode(item.data(QtCore.Qt.UserRole).toString()) filepath = unicode(item.data(
QtCore.Qt.UserRole).toString())
#not sure of this has errors #not sure of this has errors
#John please can you look at . #John please can you look at .
for cidx in self.controllers: for cidx in self.controllers:
doc = self.controllers[cidx].add_doc(filepath) doc = self.controllers[cidx].add_doc(filepath)
doc.presentation_deleted() doc.presentation_deleted()
doc.close_presentation() doc.close_presentation()
for row in row_list:
self.ListView.takeItem(row)
SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList())
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
items = self.ListView.selectedIndexes() items = self.ListView.selectedIndexes()

View File

@ -41,80 +41,80 @@ class Controller(object):
log.info(u'Controller loaded') log.info(u'Controller loaded')
def __init__(self, live): def __init__(self, live):
self.isLive = live self.is_live = live
self.doc = None self.doc = None
log.info(u'%s controller loaded' % live) log.info(u'%s controller loaded' % live)
def addHandler(self, controller, file, isBlank): def add_handler(self, controller, file, is_blank):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) log.debug(u'Live = %s, add_handler %s' % (self.is_live, file))
self.controller = controller self.controller = controller
if self.doc is not None: if self.doc is not None:
self.shutdown() self.shutdown()
self.doc = self.controller.add_doc(file) self.doc = self.controller.add_doc(file)
self.doc.load_presentation() self.doc.load_presentation()
if self.isLive: if self.is_live:
self.doc.start_presentation() self.doc.start_presentation()
if isBlank: if is_blank:
self.blank() self.blank()
Receiver.send_message(u'maindisplay_hide', HideMode.Screen) Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.doc.slidenumber = 0 self.doc.slidenumber = 0
def activate(self): def activate(self):
log.debug(u'Live = %s, activate' % self.isLive) log.debug(u'Live = %s, activate' % self.is_live)
if self.doc.is_active(): if self.doc.is_active():
return return
if not self.doc.is_loaded(): if not self.doc.is_loaded():
self.doc.load_presentation() self.doc.load_presentation()
if self.isLive: if self.is_live:
self.doc.start_presentation() self.doc.start_presentation()
if self.doc.slidenumber > 1: if self.doc.slidenumber > 1:
self.doc.goto_slide(self.doc.slidenumber) self.doc.goto_slide(self.doc.slidenumber)
def slide(self, slide, live): def slide(self, slide):
log.debug(u'Live = %s, slide' % live) log.debug(u'Live = %s, slide' % self.is_live)
if not live: if not self.is_live:
return return
if self.doc.is_blank(): if self.doc.is_blank():
self.doc.slidenumber = int(slide) + 1 self.doc.slidenumber = int(slide) + 1
return return
self.activate() self.activate()
self.doc.goto_slide(int(slide) + 1) self.doc.goto_slide(int(slide) + 1)
self.doc.poll_slidenumber(live) self.doc.poll_slidenumber(self.is_live)
def first(self): def first(self):
""" """
Based on the handler passed at startup triggers the first slide Based on the handler passed at startup triggers the first slide
""" """
log.debug(u'Live = %s, first' % self.isLive) log.debug(u'Live = %s, first' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if self.doc.is_blank(): if self.doc.is_blank():
self.doc.slidenumber = 1 self.doc.slidenumber = 1
return return
self.activate() self.activate()
self.doc.start_presentation() self.doc.start_presentation()
self.doc.poll_slidenumber(self.isLive) self.doc.poll_slidenumber(self.is_live)
def last(self): def last(self):
""" """
Based on the handler passed at startup triggers the first slide Based on the handler passed at startup triggers the first slide
""" """
log.debug(u'Live = %s, last' % self.isLive) log.debug(u'Live = %s, last' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if self.doc.is_blank(): if self.doc.is_blank():
self.doc.slidenumber = self.doc.get_slide_count() self.doc.slidenumber = self.doc.get_slide_count()
return return
self.activate() self.activate()
self.doc.goto_slide(self.doc.get_slide_count()) self.doc.goto_slide(self.doc.get_slide_count())
self.doc.poll_slidenumber(self.isLive) self.doc.poll_slidenumber(self.is_live)
def next(self): def next(self):
""" """
Based on the handler passed at startup triggers the next slide event Based on the handler passed at startup triggers the next slide event
""" """
log.debug(u'Live = %s, next' % self.isLive) log.debug(u'Live = %s, next' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if self.doc.is_blank(): if self.doc.is_blank():
if self.doc.slidenumber < self.doc.get_slide_count(): if self.doc.slidenumber < self.doc.get_slide_count():
@ -122,14 +122,14 @@ class Controller(object):
return return
self.activate() self.activate()
self.doc.next_step() self.doc.next_step()
self.doc.poll_slidenumber(self.isLive) self.doc.poll_slidenumber(self.is_live)
def previous(self): def previous(self):
""" """
Based on the handler passed at startup triggers the previous slide event Based on the handler passed at startup triggers the previous slide event
""" """
log.debug(u'Live = %s, previous' % self.isLive) log.debug(u'Live = %s, previous' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if self.doc.is_blank(): if self.doc.is_blank():
if self.doc.slidenumber > 1: if self.doc.slidenumber > 1:
@ -137,14 +137,14 @@ class Controller(object):
return return
self.activate() self.activate()
self.doc.previous_step() self.doc.previous_step()
self.doc.poll_slidenumber(self.isLive) self.doc.poll_slidenumber(self.is_live)
def shutdown(self): def shutdown(self):
""" """
Based on the handler passed at startup triggers slide show to shut down Based on the handler passed at startup triggers slide show to shut down
""" """
log.debug(u'Live = %s, shutdown' % self.isLive) log.debug(u'Live = %s, shutdown' % self.is_live)
if self.isLive: if self.is_live:
Receiver.send_message(u'maindisplay_show') Receiver.send_message(u'maindisplay_show')
self.doc.close_presentation() self.doc.close_presentation()
self.doc = None self.doc = None
@ -152,8 +152,8 @@ class Controller(object):
#self.timer.stop() #self.timer.stop()
def blank(self): def blank(self):
log.debug(u'Live = %s, blank' % self.isLive) log.debug(u'Live = %s, blank' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if not self.doc.is_loaded(): if not self.doc.is_loaded():
return return
@ -162,8 +162,8 @@ class Controller(object):
self.doc.blank_screen() self.doc.blank_screen()
def stop(self): def stop(self):
log.debug(u'Live = %s, stop' % self.isLive) log.debug(u'Live = %s, stop' % self.is_live)
if not self.isLive: if not self.is_live:
return return
if not self.doc.is_loaded(): if not self.doc.is_loaded():
return return
@ -172,8 +172,8 @@ class Controller(object):
self.doc.stop_presentation() self.doc.stop_presentation()
def unblank(self): def unblank(self):
log.debug(u'Live = %s, unblank' % self.isLive) log.debug(u'Live = %s, unblank' % self.is_live)
if not self.isLive: if not self.is_live:
return return
self.activate() self.activate()
if self.doc.slidenumber and \ if self.doc.slidenumber and \
@ -183,7 +183,7 @@ class Controller(object):
Receiver.send_message(u'maindisplay_hide', HideMode.Screen) Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
def poll(self): def poll(self):
self.doc.poll_slidenumber(self.isLive) self.doc.poll_slidenumber(self.is_live)
class MessageListener(object): class MessageListener(object):
""" """
@ -195,8 +195,8 @@ class MessageListener(object):
def __init__(self, mediaitem): def __init__(self, mediaitem):
self.controllers = mediaitem.controllers self.controllers = mediaitem.controllers
self.mediaitem = mediaitem self.mediaitem = mediaitem
self.previewHandler = Controller(False) self.preview_handler = Controller(False)
self.liveHandler = Controller(True) self.live_handler = Controller(True)
# messages are sent from core.ui.slidecontroller # messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup) QtCore.SIGNAL(u'presentations_start'), self.startup)
@ -228,9 +228,10 @@ class MessageListener(object):
Start of new presentation Start of new presentation
Save the handler as any new presentations start here Save the handler as any new presentations start here
""" """
isLive, item = self.decode_message(message) is_live = message[1]
item = message[0]
log.debug(u'Startup called with message %s' % message) log.debug(u'Startup called with message %s' % message)
isBlank = message[2] is_blank = message[2]
file = os.path.join(item.get_frame_path(), file = os.path.join(item.get_frame_path(),
item.get_frame_title()) item.get_frame_title())
self.handler = item.title self.handler = item.title
@ -238,75 +239,70 @@ class MessageListener(object):
self.handler = self.mediaitem.findControllerByType(file) self.handler = self.mediaitem.findControllerByType(file)
if not self.handler: if not self.handler:
return return
if isLive: if is_live:
controller = self.liveHandler controller = self.live_handler
else: else:
controller = self.previewHandler controller = self.preview_handler
controller.addHandler(self.controllers[self.handler], file, isBlank) controller.add_handler(self.controllers[self.handler], file, is_blank)
def decode_message(self, message):
if len(message) == 3:
return message[1], message[0], message[2]
else:
return message[1], message[0]
def slide(self, message): def slide(self, message):
isLive, item, slide = self.decode_message(message) is_live = message[1]
if isLive: slide = message[2]
self.liveHandler.slide(slide, isLive) if is_live:
self.live_handler.slide(slide)
else: else:
self.previewHandler.slide(slide, isLive) self.preview_handler.slide(slide)
def first(self, message): def first(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.first() self.live_handler.first()
else: else:
self.previewHandler.first() self.preview_handler.first()
def last(self, message): def last(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.last() self.live_handler.last()
else: else:
self.previewHandler.last() self.preview_handler.last()
def next(self, message): def next(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.next() self.live_handler.next()
else: else:
self.previewHandler.next() self.preview_handler.next()
def previous(self, message): def previous(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.previous() self.live_handler.previous()
else: else:
self.previewHandler.previous() self.preview_handler.previous()
def shutdown(self, message): def shutdown(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
Receiver.send_message(u'maindisplay_show') Receiver.send_message(u'maindisplay_show')
self.liveHandler.shutdown() self.live_handler.shutdown()
else: else:
self.previewHandler.shutdown() self.preview_handler.shutdown()
def hide(self, message): def hide(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.stop() self.live_handler.stop()
def blank(self, message): def blank(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.blank() self.live_handler.blank()
def unblank(self, message): def unblank(self, message):
isLive = self.decode_message(message)[0] is_live = message[1]
if isLive: if is_live:
self.liveHandler.unblank() self.live_handler.unblank()
def timeout(self): def timeout(self):
self.liveHandler.poll() self.live_handler.poll()

View File

@ -30,6 +30,7 @@ if os.name == u'nt':
from win32com.client import Dispatch from win32com.client import Dispatch
import _winreg import _winreg
import win32ui import win32ui
import pywintypes
from presentationcontroller import PresentationController, PresentationDocument from presentationcontroller import PresentationController, PresentationDocument
@ -65,7 +66,7 @@ class PowerpointController(PresentationController):
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
u'PowerPoint.Application').Close() u'PowerPoint.Application').Close()
return True return True
except: except WindowsError:
pass pass
return False return False
@ -91,7 +92,7 @@ class PowerpointController(PresentationController):
return return
try: try:
self.process.Quit() self.process.Quit()
except: except pywintypes.com_error:
pass pass
self.process = None self.process = None
@ -121,11 +122,8 @@ class PowerpointDocument(PresentationDocument):
log.debug(u'LoadPresentation') log.debug(u'LoadPresentation')
if not self.controller.process.Visible: if not self.controller.process.Visible:
self.controller.start_process() self.controller.start_process()
#try:
self.controller.process.Presentations.Open(self.filepath, False, False, self.controller.process.Presentations.Open(self.filepath, False, False,
True) True)
#except:
# return
self.presentation = self.controller.process.Presentations( self.presentation = self.controller.process.Presentations(
self.controller.process.Presentations.Count) self.controller.process.Presentations.Count)
self.create_thumbnails() self.create_thumbnails()
@ -154,7 +152,7 @@ class PowerpointDocument(PresentationDocument):
if self.presentation: if self.presentation:
try: try:
self.presentation.Close() self.presentation.Close()
except: except pywintypes.com_error:
pass pass
self.presentation = None self.presentation = None
self.controller.remove_doc(self) self.controller.remove_doc(self)
@ -170,7 +168,7 @@ class PowerpointDocument(PresentationDocument):
return False return False
if self.controller.process.Presentations.Count == 0: if self.controller.process.Presentations.Count == 0:
return False return False
except: except (AttributeError, pywintypes.com_error):
return False return False
return True return True
@ -186,7 +184,7 @@ class PowerpointDocument(PresentationDocument):
return False return False
if self.presentation.SlideShowWindow.View is None: if self.presentation.SlideShowWindow.View is None:
return False return False
except: except (AttributeError, pywintypes.com_error):
return False return False
return True return True
@ -208,7 +206,10 @@ class PowerpointDocument(PresentationDocument):
""" """
Returns true if screen is blank Returns true if screen is blank
""" """
if self.is_active():
return self.presentation.SlideShowWindow.View.State == 3 return self.presentation.SlideShowWindow.View.State == 3
else:
return False
def stop_presentation(self): def stop_presentation(self):
""" """
@ -224,11 +225,11 @@ class PowerpointDocument(PresentationDocument):
#SlideShowWindow measures its size/position by points, not pixels #SlideShowWindow measures its size/position by points, not pixels
try: try:
dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88)
except: except win32ui.error:
try: try:
dpi = \ dpi = \
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88) win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
except: except win32ui.error:
dpi = 96 dpi = 96
self.presentation.SlideShowSettings.Run() self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.GotoSlide(1) self.presentation.SlideShowWindow.View.GotoSlide(1)

View File

@ -58,10 +58,7 @@ class PptviewController(PresentationController):
log.debug(u'check_available') log.debug(u'check_available')
if os.name != u'nt': if os.name != u'nt':
return False return False
try:
return self.check_installed() return self.check_installed()
except:
return False
if os.name == u'nt': if os.name == u'nt':
def check_installed(self): def check_installed(self):
@ -72,7 +69,7 @@ class PptviewController(PresentationController):
try: try:
self.start_process() self.start_process()
return self.process.CheckInstalled() return self.process.CheckInstalled()
except: except WindowsError:
return False return False
def start_process(self): def start_process(self):
@ -84,6 +81,7 @@ class PptviewController(PresentationController):
log.debug(u'start PPTView') log.debug(u'start PPTView')
self.process = cdll.LoadLibrary( self.process = cdll.LoadLibrary(
r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
#self.process.SetDebug(1)
def kill(self): def kill(self):
""" """
@ -106,6 +104,7 @@ class PptviewDocument(PresentationDocument):
self.presentation = None self.presentation = None
self.pptid = None self.pptid = None
self.blanked = False self.blanked = False
self.hidden = False
def load_presentation(self): def load_presentation(self):
""" """
@ -123,13 +122,11 @@ class PptviewDocument(PresentationDocument):
rect = rendermanager.screens.current[u'size'] rect = rendermanager.screens.current[u'size']
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom()) rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
filepath = str(self.filepath.replace(u'/', u'\\')) filepath = str(self.filepath.replace(u'/', u'\\'))
try:
self.pptid = self.controller.process.OpenPPT(filepath, None, rect, self.pptid = self.controller.process.OpenPPT(filepath, None, rect,
str(os.path.join(self.thumbnailpath, str(os.path.join(self.thumbnailpath,
self.controller.thumbnailprefix))) self.controller.thumbnailprefix)))
if self.pptid:
self.stop_presentation() self.stop_presentation()
except:
log.exception(u'Failed to load presentation')
def close_presentation(self): def close_presentation(self):
""" """
@ -156,7 +153,7 @@ class PptviewDocument(PresentationDocument):
""" """
Returns true if a presentation is currently active Returns true if a presentation is currently active
""" """
return self.is_loaded() return self.is_loaded() and not self.hidden
def blank_screen(self): def blank_screen(self):
""" """
@ -183,12 +180,17 @@ class PptviewDocument(PresentationDocument):
""" """
Stops the current presentation and hides the output Stops the current presentation and hides the output
""" """
self.hidden = True
self.controller.process.Stop(self.pptid) self.controller.process.Stop(self.pptid)
def start_presentation(self): def start_presentation(self):
""" """
Starts a presentation from the beginning Starts a presentation from the beginning
""" """
if self.hidden:
self.hidden = False
self.controller.process.Resume(self.pptid)
else:
self.controller.process.RestartShow(self.pptid) self.controller.process.RestartShow(self.pptid)
def get_slide_number(self): def get_slide_number(self):

View File

@ -23,6 +23,8 @@ This README.TXT must be distributed with the pptviewlib.dll
This library has a limit of 50 PowerPoints which can be opened simultaneously. This library has a limit of 50 PowerPoints which can be opened simultaneously.
This project can be built with the free Microsoft Visual C++ 2008 Express Edition.
USAGE USAGE
----- -----
BOOL CheckInstalled(void); BOOL CheckInstalled(void);

View File

@ -150,7 +150,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp
pptviewobj[id].rect.bottom = rect.bottom; pptviewobj[id].rect.bottom = rect.bottom;
pptviewobj[id].rect.right = rect.right; pptviewobj[id].rect.right = rect.right;
} }
strcat_s(cmdline, MAX_PATH * 2, "/S \""); strcat_s(cmdline, MAX_PATH * 2, "/F /S \"");
strcat_s(cmdline, MAX_PATH * 2, filename); strcat_s(cmdline, MAX_PATH * 2, filename);
strcat_s(cmdline, MAX_PATH * 2, "\""); strcat_s(cmdline, MAX_PATH * 2, "\"");
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
@ -211,7 +211,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp
} }
DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps); DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps);
SavePPTInfo(id); SavePPTInfo(id);
if(pptviewobj[id].state==PPT_CLOSING){ if(pptviewobj[id].state==PPT_CLOSING||pptviewobj[id].slideCount<=0){
ClosePPT(id); ClosePPT(id);
id=-1; id=-1;
} }

View File

@ -37,8 +37,8 @@ class PresentationTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'PresentationTab') self.setObjectName(u'PresentationTab')
self.tabTitleVisible = translate(u'PresentationPlugin.PresentationTab', self.tabTitleVisible = translate('PresentationPlugin.PresentationTab',
u'Presentations') 'Presentations')
self.PresentationLayout = QtGui.QHBoxLayout(self) self.PresentationLayout = QtGui.QHBoxLayout(self)
self.PresentationLayout.setSpacing(8) self.PresentationLayout.setSpacing(8)
self.PresentationLayout.setMargin(8) self.PresentationLayout.setMargin(8)
@ -90,14 +90,14 @@ class PresentationTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.VerseDisplayGroupBox.setTitle( self.VerseDisplayGroupBox.setTitle(
translate(u'PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab',
u'Available Controllers')) 'Available Controllers'))
for key in self.controllers: for key in self.controllers:
controller = self.controllers[key] controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
checkbox.setText( checkbox.setText(
u'%s %s' % (controller.name, u'%s %s' % (controller.name,
translate(u'PresentationPlugin.PresentationTab', u'available'))) translate('PresentationPlugin.PresentationTab', 'available')))
def load(self): def load(self):
for key in self.controllers: for key in self.controllers:

View File

@ -38,7 +38,7 @@ class PresentationPlugin(Plugin):
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
log.debug(u'Initialised') log.debug(u'Initialised')
self.controllers = {} self.controllers = {}
Plugin.__init__(self, u'Presentations', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Presentations', u'1.9.2', plugin_helpers)
self.weight = -8 self.weight = -8
self.icon = build_icon(u':/media/media_presentation.png') self.icon = build_icon(u':/media/media_presentation.png')
self.status = PluginStatus.Active self.status = PluginStatus.Active
@ -108,10 +108,9 @@ class PresentationPlugin(Plugin):
return False return False
def about(self): def about(self):
about_text = translate(u'PresentationPlugin', about_text = translate('PresentationPlugin',
u'<b>Presentation Plugin</b> <br> Delivers ' '<b>Presentation Plugin</b> <br> Delivers '
u'the ability to show presentations using a number of different ' 'the ability to show presentations using a number of different '
u'programs. The choice of available presentation programs is ' 'programs. The choice of available presentation programs is '
u'available to the user in a drop down box.') 'available to the user in a drop down box.')
return about_text return about_text

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`remotes` plugin allows OpenLP to be controlled from another machine
over a network connection.
"""

View File

@ -36,7 +36,7 @@ class RemoteTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'RemoteTab') self.setObjectName(u'RemoteTab')
self.tabTitleVisible = translate(u'RemotePlugin.RemoteTab', u'Remotes') self.tabTitleVisible = translate('RemotePlugin.RemoteTab', 'Remotes')
self.RemoteLayout = QtGui.QFormLayout(self) self.RemoteLayout = QtGui.QFormLayout(self)
self.RemoteLayout.setObjectName(u'RemoteLayout') self.RemoteLayout.setObjectName(u'RemoteLayout')
self.RemoteModeGroupBox = QtGui.QGroupBox(self) self.RemoteModeGroupBox = QtGui.QGroupBox(self)
@ -54,7 +54,7 @@ class RemoteTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.RemoteModeGroupBox.setTitle( self.RemoteModeGroupBox.setTitle(
translate(u'RemotePlugin.RemoteTab', u'Remotes Receiver Port')) translate('RemotePlugin.RemoteTab', 'Remotes Receiver Port'))
def load(self): def load(self):
self.RemotePortSpinBox.setValue( self.RemotePortSpinBox.setValue(

View File

@ -25,7 +25,7 @@
import logging import logging
from openlp.core.lib import Plugin, translate from openlp.core.lib import Plugin, translate, build_icon
from openlp.plugins.remotes.lib import RemoteTab, HttpServer from openlp.plugins.remotes.lib import RemoteTab, HttpServer
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -37,7 +37,8 @@ class RemotesPlugin(Plugin):
""" """
remotes constructor remotes constructor
""" """
Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Remotes', u'1.9.2', plugin_helpers)
self.icon = build_icon(u':/plugins/plugin_remote.png')
self.weight = -1 self.weight = -1
self.server = None self.server = None
@ -69,9 +70,9 @@ class RemotesPlugin(Plugin):
""" """
Information about this plugin Information about this plugin
""" """
about_text = translate(u'RemotePlugin', about_text = translate('RemotePlugin',
u'<b>Remote Plugin</b><br>This plugin ' '<b>Remote Plugin</b><br>This plugin '
u'provides the ability to send messages to a running version of ' 'provides the ability to send messages to a running version of '
u'openlp on a different computer via a web browser or other app<br>' 'openlp on a different computer via a web browser or other app<br>'
u'The Primary use for this would be to send alerts from a creche') 'The Primary use for this would be to send alerts from a creche')
return about_text return about_text

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`songs` module provides the Songs plugin. The Songs plugin provides
the main lyric projection function of OpenLP.
"""

View File

@ -24,6 +24,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_AuthorsDialog(object): class Ui_AuthorsDialog(object):
@ -75,10 +76,10 @@ class Ui_AuthorsDialog(object):
def retranslateUi(self, AuthorsDialog): def retranslateUi(self, AuthorsDialog):
AuthorsDialog.setWindowTitle( AuthorsDialog.setWindowTitle(
translate(u'SongsPlugin.AuthorsForm', u'Author Maintenance')) translate('SongsPlugin.AuthorsForm', 'Author Maintenance'))
self.DisplayLabel.setText( self.DisplayLabel.setText(
translate(u'SongsPlugin.AuthorsForm', u'Display name:')) translate('SongsPlugin.AuthorsForm', 'Display name:'))
self.FirstNameLabel.setText( self.FirstNameLabel.setText(
translate(u'SongsPlugin.AuthorsForm', u'First name:')) translate('SongsPlugin.AuthorsForm', 'First name:'))
self.LastNameLabel.setText( self.LastNameLabel.setText(
translate(u'SongsPlugin.AuthorsForm', u'Last name:')) translate('SongsPlugin.AuthorsForm', 'Last name:'))

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui, QtCore
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
""" """
Class to control the Maintenance of Authors Dialog Class to control the Maintenance of Authors Dialog
@ -80,27 +79,27 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
def accept(self): def accept(self):
if not self.FirstNameEdit.text(): if not self.FirstNameEdit.text():
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'), self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate(u'SongsPlugin.AuthorsForm', translate('SongsPlugin.AuthorsForm',
u'You need to type in the first name of the author.'), 'You need to type in the first name of the author.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.FirstNameEdit.setFocus() self.FirstNameEdit.setFocus()
return False return False
elif not self.LastNameEdit.text(): elif not self.LastNameEdit.text():
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'), self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate(u'SongsPlugin.AuthorsForm', translate('SongsPlugin.AuthorsForm',
u'You need to type in the last name of the author.'), 'You need to type in the last name of the author.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.LastNameEdit.setFocus() self.LastNameEdit.setFocus()
return False return False
elif not self.DisplayEdit.text(): elif not self.DisplayEdit.text():
if QtGui.QMessageBox.critical( if QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'), self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate(u'SongsPlugin.AuthorsForm', translate('SongsPlugin.AuthorsForm',
u'You haven\'t set a display name for the ' 'You haven\'t set a display name for the '
u'author, would you like me to combine the first and ' 'author, would you like me to combine the first and '
u'last names for you?'), 'last names for you?'),
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
) == QtGui.QMessageBox.Yes: ) == QtGui.QMessageBox.Yes:

View File

@ -24,9 +24,8 @@
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.lib import build_icon from openlp.core.lib import build_icon, translate
class Ui_EditSongDialog(object): class Ui_EditSongDialog(object):
def setupUi(self, EditSongDialog): def setupUi(self, EditSongDialog):
@ -50,6 +49,7 @@ class Ui_EditSongDialog(object):
self.TitleLabel.setObjectName(u'TitleLabel') self.TitleLabel.setObjectName(u'TitleLabel')
self.LyricsTabLayout.addWidget(self.TitleLabel, 0, 0, 1, 1) self.LyricsTabLayout.addWidget(self.TitleLabel, 0, 0, 1, 1)
self.TitleEditItem = QtGui.QLineEdit(self.LyricsTab) self.TitleEditItem = QtGui.QLineEdit(self.LyricsTab)
self.TitleLabel.setBuddy(self.TitleEditItem)
sizePolicy = QtGui.QSizePolicy( sizePolicy = QtGui.QSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -63,6 +63,7 @@ class Ui_EditSongDialog(object):
self.AlternativeTitleLabel.setObjectName(u'AlternativeTitleLabel') self.AlternativeTitleLabel.setObjectName(u'AlternativeTitleLabel')
self.LyricsTabLayout.addWidget(self.AlternativeTitleLabel, 1, 0, 1, 1) self.LyricsTabLayout.addWidget(self.AlternativeTitleLabel, 1, 0, 1, 1)
self.AlternativeEdit = QtGui.QLineEdit(self.LyricsTab) self.AlternativeEdit = QtGui.QLineEdit(self.LyricsTab)
self.AlternativeTitleLabel.setBuddy(self.AlternativeEdit)
self.AlternativeEdit.setObjectName(u'AlternativeEdit') self.AlternativeEdit.setObjectName(u'AlternativeEdit')
self.LyricsTabLayout.addWidget(self.AlternativeEdit, 1, 1, 1, 2) self.LyricsTabLayout.addWidget(self.AlternativeEdit, 1, 1, 1, 2)
self.LyricsLabel = QtGui.QLabel(self.LyricsTab) self.LyricsLabel = QtGui.QLabel(self.LyricsTab)
@ -71,6 +72,7 @@ class Ui_EditSongDialog(object):
self.LyricsLabel.setObjectName(u'LyricsLabel') self.LyricsLabel.setObjectName(u'LyricsLabel')
self.LyricsTabLayout.addWidget(self.LyricsLabel, 2, 0, 1, 1) self.LyricsTabLayout.addWidget(self.LyricsLabel, 2, 0, 1, 1)
self.VerseListWidget = QtGui.QTableWidget(self.LyricsTab) self.VerseListWidget = QtGui.QTableWidget(self.LyricsTab)
self.LyricsLabel.setBuddy(self.VerseListWidget)
self.VerseListWidget.setColumnCount(1) self.VerseListWidget.setColumnCount(1)
self.VerseListWidget.horizontalHeader().setVisible(False) self.VerseListWidget.horizontalHeader().setVisible(False)
self.VerseListWidget.setSelectionBehavior(1) self.VerseListWidget.setSelectionBehavior(1)
@ -83,6 +85,7 @@ class Ui_EditSongDialog(object):
self.VerseOrderLabel.setObjectName(u'VerseOrderLabel') self.VerseOrderLabel.setObjectName(u'VerseOrderLabel')
self.LyricsTabLayout.addWidget(self.VerseOrderLabel, 4, 0, 1, 1) self.LyricsTabLayout.addWidget(self.VerseOrderLabel, 4, 0, 1, 1)
self.VerseOrderEdit = QtGui.QLineEdit(self.LyricsTab) self.VerseOrderEdit = QtGui.QLineEdit(self.LyricsTab)
self.VerseOrderLabel.setBuddy(self.VerseOrderEdit)
self.VerseOrderEdit.setObjectName(u'VerseOrderEdit') self.VerseOrderEdit.setObjectName(u'VerseOrderEdit')
self.LyricsTabLayout.addWidget(self.VerseOrderEdit, 4, 1, 1, 2) self.LyricsTabLayout.addWidget(self.VerseOrderEdit, 4, 1, 1, 2)
self.VerseButtonWidget = QtGui.QWidget(self.LyricsTab) self.VerseButtonWidget = QtGui.QWidget(self.LyricsTab)
@ -440,7 +443,7 @@ class Ui_EditSongDialog(object):
self.TitleLabel.setText( self.TitleLabel.setText(
translate('SongsPlugin.EditSongForm', '&Title:')) translate('SongsPlugin.EditSongForm', '&Title:'))
self.AlternativeTitleLabel.setText( self.AlternativeTitleLabel.setText(
translate('SongsPlugin.EditSongForm', 'Alt&ernative Title:')) translate('SongsPlugin.EditSongForm', 'Alt&ernate Title:'))
self.LyricsLabel.setText( self.LyricsLabel.setText(
translate('SongsPlugin.EditSongForm', '&Lyrics:')) translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.VerseOrderLabel.setText( self.VerseOrderLabel.setText(
@ -478,11 +481,11 @@ class Ui_EditSongDialog(object):
self.ThemeGroupBox.setTitle( self.ThemeGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Theme')) translate('SongsPlugin.EditSongForm', 'Theme'))
self.ThemeAddButton.setText( self.ThemeAddButton.setText(
translate('SongsPlugin.EditSongForm', 'Add a &Theme')) translate('SongsPlugin.EditSongForm', 'New &Theme'))
self.CopyrightGroupBox.setTitle( self.CopyrightGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Copyright Information')) translate('SongsPlugin.EditSongForm', 'Copyright Information'))
self.CopyrightInsertButton.setText( self.CopyrightInsertButton.setText(
translate('SongsPlugin.EditSongForm', u'\xa9')) translate('SongsPlugin.EditSongForm', '\xa9'))
self.CCLILabel.setText( self.CCLILabel.setText(
translate('SongsPlugin.EditSongForm', 'CCLI Number:')) translate('SongsPlugin.EditSongForm', 'CCLI Number:'))
self.CommentsGroupBox.setTitle( self.CommentsGroupBox.setTitle(

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
from openlp.plugins.songs.forms import EditVerseForm from openlp.plugins.songs.forms import EditVerseForm
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.models import Song, Author, Topic, Book from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
from editsongdialog import Ui_EditSongDialog from editsongdialog import Ui_EditSongDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -96,7 +96,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.previewButton = QtGui.QPushButton() self.previewButton = QtGui.QPushButton()
self.previewButton.setObjectName(u'previewButton') self.previewButton.setObjectName(u'previewButton')
self.previewButton.setText( self.previewButton.setText(
translate(u'SongsPlugin.EditSongForm', u'Save && Preview')) translate('SongsPlugin.EditSongForm', 'Save && Preview'))
self.ButtonBox.addButton( self.ButtonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole) self.previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.ButtonBox, QtCore.QObject.connect(self.ButtonBox,
@ -118,7 +118,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False) self.TopicRemoveButton.setEnabled(False)
def loadAuthors(self): def loadAuthors(self):
authors = self.songmanager.get_authors() authors = self.songmanager.get_all_objects(Author, Author.display_name)
self.AuthorsSelectionComboItem.clear() self.AuthorsSelectionComboItem.clear()
self.AuthorsSelectionComboItem.addItem(u'') self.AuthorsSelectionComboItem.addItem(u'')
for author in authors: for author in authors:
@ -128,7 +128,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
row, QtCore.QVariant(author.id)) row, QtCore.QVariant(author.id))
def loadTopics(self): def loadTopics(self):
topics = self.songmanager.get_topics() topics = self.songmanager.get_all_objects(Topic, Topic.name)
self.SongTopicCombo.clear() self.SongTopicCombo.clear()
self.SongTopicCombo.addItem(u'') self.SongTopicCombo.addItem(u'')
for topic in topics: for topic in topics:
@ -137,7 +137,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id)) self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id))
def loadBooks(self): def loadBooks(self):
books = self.songmanager.get_books() books = self.songmanager.get_all_objects(Book, Book.name)
self.SongbookCombo.clear() self.SongbookCombo.clear()
self.SongbookCombo.addItem(u'') self.SongbookCombo.addItem(u'')
for book in books: for book in books:
@ -178,11 +178,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.loadAuthors() self.loadAuthors()
self.loadTopics() self.loadTopics()
self.loadBooks() self.loadBooks()
self.song = self.songmanager.get_song(id) self.song = self.songmanager.get_object(Song, id)
self.TitleEditItem.setText(self.song.title) self.TitleEditItem.setText(self.song.title)
title = self.song.search_title.split(u'@') title = self.song.search_title.split(u'@')
if self.song.song_book_id != 0: if self.song.song_book_id != 0:
book_name = self.songmanager.get_book(self.song.song_book_id) book_name = self.songmanager.get_object(Book,
self.song.song_book_id)
id = self.SongbookCombo.findText( id = self.SongbookCombo.findText(
unicode(book_name.name), QtCore.Qt.MatchExactly) unicode(book_name.name), QtCore.Qt.MatchExactly)
if id == -1: if id == -1:
@ -289,7 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
author = Author.populate(first_name=text.rsplit(u' ', 1)[0], author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
last_name=text.rsplit(u' ', 1)[1], display_name=text) last_name=text.rsplit(u' ', 1)[1], display_name=text)
self.songmanager.save_author(author) self.songmanager.save_object(author)
self.song.authors.append(author) self.song.authors.append(author)
author_item = QtGui.QListWidgetItem( author_item = QtGui.QListWidgetItem(
unicode(author.display_name)) unicode(author.display_name))
@ -302,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return return
elif item > 0: elif item > 0:
item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0] item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0]
author = self.songmanager.get_author(item_id) author = self.songmanager.get_object(Author, item_id)
self.song.authors.append(author) self.song.authors.append(author)
author_item = QtGui.QListWidgetItem(unicode(author.display_name)) author_item = QtGui.QListWidgetItem(unicode(author.display_name))
author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id))
@ -325,7 +326,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.AuthorRemoveButton.setEnabled(False) self.AuthorRemoveButton.setEnabled(False)
item = self.AuthorsListView.currentItem() item = self.AuthorsListView.currentItem()
author_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] author_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
author = self.songmanager.get_author(author_id) author = self.songmanager.get_object(Author, author_id)
self.song.authors.remove(author) self.song.authors.remove(author)
row = self.AuthorsListView.row(item) row = self.AuthorsListView.row(item)
self.AuthorsListView.takeItem(row) self.AuthorsListView.takeItem(row)
@ -341,7 +342,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
topic = Topic.populate(name=text) topic = Topic.populate(name=text)
self.songmanager.save_topic(topic) self.songmanager.save_object(topic)
self.song.topics.append(topic) self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, topic_item.setData(QtCore.Qt.UserRole,
@ -353,7 +354,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return return
elif item > 0: elif item > 0:
item_id = (self.SongTopicCombo.itemData(item)).toInt()[0] item_id = (self.SongTopicCombo.itemData(item)).toInt()[0]
topic = self.songmanager.get_topic(item_id) topic = self.songmanager.get_object(Topic, item_id)
self.song.topics.append(topic) self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -375,7 +376,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False) self.TopicRemoveButton.setEnabled(False)
item = self.TopicsListView.currentItem() item = self.TopicsListView.currentItem()
topic_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] topic_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
topic = self.songmanager.get_topic(topic_id) topic = self.songmanager.get_object(Topic, topic_id)
self.song.topics.remove(topic) self.song.topics.remove(topic)
row = self.TopicsListView.row(item) row = self.TopicsListView.row(item)
self.TopicsListView.takeItem(row) self.TopicsListView.takeItem(row)
@ -391,12 +392,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
book = Book.populate(name=text) book = Book.populate(name=text)
self.songmanager.save_book(book) self.songmanager.save_object(book)
self.song.book = book self.song.book = book
self.loadBooks() self.loadBooks()
else: else:
return return
elif item > 1: elif item >= 1:
item = int(self.SongbookCombo.currentIndex()) item = int(self.SongbookCombo.currentIndex())
self.song.song_book_id = \ self.song.song_book_id = \
(self.SongbookCombo.itemData(item)).toInt()[0] (self.SongbookCombo.itemData(item)).toInt()[0]
@ -516,26 +517,26 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.TitleEditItem.setFocus() self.TitleEditItem.setFocus()
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'), translate('SongsPlugin.EditSongForm', 'Error'),
translate(u'SongsPlugin.EditSongForm', translate('SongsPlugin.EditSongForm',
u'You need to enter a song title.')) 'You need to type in a song title.'))
return False return False
if self.VerseListWidget.rowCount() == 0: if self.VerseListWidget.rowCount() == 0:
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.VerseListWidget.setFocus() self.VerseListWidget.setFocus()
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'), translate('SongsPlugin.EditSongForm', 'Error'),
translate('uSongsPlugin.EditSongForm', translate('SongsPlugin.EditSongForm',
u'You need to enter some verses.')) 'You need to type in at least one verse.'))
return False return False
if self.AuthorsListView.count() == 0: if self.AuthorsListView.count() == 0:
self.SongTabWidget.setCurrentIndex(1) self.SongTabWidget.setCurrentIndex(1)
self.AuthorsListView.setFocus() self.AuthorsListView.setFocus()
answer = QtGui.QMessageBox.warning(self, answer = QtGui.QMessageBox.warning(self,
translate(u'SongsPlugin.EditSongForm', u'Warning'), translate('SongsPlugin.EditSongForm', 'Warning'),
translate('SongsPlugin.EditSongForm', translate('SongsPlugin.EditSongForm',
'You have set no author.\n' 'You have not added any authors for this song. Do you '
'Do you want to add now a author?'), 'want to add an author now?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.Yes: if answer == QtGui.QMessageBox.Yes:
return False return False
@ -564,7 +565,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for verse in verses: for verse in verses:
valid = valid + u', ' + verse valid = valid + u', ' + verse
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'), translate('SongsPlugin.EditSongForm', 'Error'),
unicode(translate('SongsPlugin.EditSongForm', unicode(translate('SongsPlugin.EditSongForm',
'The verse order is invalid. There is no verse ' 'The verse order is invalid. There is no verse '
'corresponding to %s. Valid entries are %s.')) % \ 'corresponding to %s. Valid entries are %s.')) % \
@ -575,10 +576,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.VerseOrderEdit.setFocus() self.VerseOrderEdit.setFocus()
answer = QtGui.QMessageBox.warning(self, answer = QtGui.QMessageBox.warning(self,
translate(u'SongsPlugin.EditSongForm', u'Warning'), translate('SongsPlugin.EditSongForm', 'Warning'),
unicode(translate('SongsPlugin.EditSongForm', unicode(translate('SongsPlugin.EditSongForm',
'%s is not addressed in the verse order.\n' 'You have not used %s anywhere in the verse '
'Do you want to save anyhow?')) % \ 'order. Are you sure you want to save the song '
'like this?')) % \
verse_names[count].replace(u':', u' '), verse_names[count].replace(u':', u' '),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No: if answer == QtGui.QMessageBox.No:
@ -588,7 +590,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def onCopyrightInsertButtonTriggered(self): def onCopyrightInsertButtonTriggered(self):
text = self.CopyrightEditItem.text() text = self.CopyrightEditItem.text()
pos = self.CopyrightEditItem.cursorPosition() pos = self.CopyrightEditItem.cursorPosition()
text = text[:pos] + u'\xa9' + text[pos:] text = text[:pos] + '\xa9' + text[pos:]
self.CopyrightEditItem.setText(text) self.CopyrightEditItem.setText(text)
self.CopyrightEditItem.setFocus() self.CopyrightEditItem.setFocus()
self.CopyrightEditItem.setCursorPosition(pos + 1) self.CopyrightEditItem.setCursorPosition(pos + 1)
@ -629,7 +631,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if self._validate_song(): if self._validate_song():
self.processLyrics() self.processLyrics()
self.processTitle() self.processTitle()
self.songmanager.save_song(self.song) self.songmanager.save_object(self.song)
return True return True
return False return False
@ -654,7 +656,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8') self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for verse in multiple: for verse in multiple:
self.song.verse_order = re.sub(u'([' + verse.upper() + self.song.verse_order = re.sub(u'([' + verse.upper() +
verse.lower() + u'])(\W|$)', r'\g<1>1\2', self.song.verse_order) verse.lower() + u'])(\W|$)', r'\g<1>1\2',
self.song.verse_order)
except: except:
log.exception(u'Problem processing song Lyrics \n%s', log.exception(u'Problem processing song Lyrics \n%s',
sxml.dump_xml()) sxml.dump_xml())

View File

@ -87,9 +87,9 @@ class Ui_EditVerseDialog(object):
def retranslateUi(self, EditVerseDialog): def retranslateUi(self, EditVerseDialog):
EditVerseDialog.setWindowTitle( EditVerseDialog.setWindowTitle(
translate(u'SongsPlugin.EditVerseForm', u'Edit Verse')) translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
self.VerseTypeLabel.setText( self.VerseTypeLabel.setText(
translate(u'SongsPlugin.EditVerseForm', u'Verse Type:')) translate('SongsPlugin.EditVerseForm', '&Verse type:'))
self.VerseTypeComboBox.setItemText(0, self.VerseTypeComboBox.setItemText(0,
VerseType.to_string(VerseType.Verse)) VerseType.to_string(VerseType.Verse))
self.VerseTypeComboBox.setItemText(1, self.VerseTypeComboBox.setItemText(1,
@ -105,5 +105,5 @@ class Ui_EditVerseDialog(object):
self.VerseTypeComboBox.setItemText(6, self.VerseTypeComboBox.setItemText(6,
VerseType.to_string(VerseType.Other)) VerseType.to_string(VerseType.Other))
self.InsertButton.setText( self.InsertButton.setText(
translate(u'SongsPlugin.EditVerseForm', u'Insert')) translate('SongsPlugin.EditVerseForm', '&Insert'))

View File

@ -24,6 +24,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_SongBookDialog(object): class Ui_SongBookDialog(object):
@ -67,7 +68,7 @@ class Ui_SongBookDialog(object):
def retranslateUi(self, SongBookDialog): def retranslateUi(self, SongBookDialog):
SongBookDialog.setWindowTitle( SongBookDialog.setWindowTitle(
translate(u'SongsPlugin.SongBookForm', u'Edit Book')) translate('SongsPlugin.SongBookForm', 'Edit Book'))
self.NameLabel.setText(translate(u'SongsPlugin.SongBookForm', u'Name:')) self.NameLabel.setText(translate('SongsPlugin.SongBookForm', '&Name:'))
self.PublisherLabel.setText( self.PublisherLabel.setText(
translate(u'SongsPlugin.SongBookForm', u'Publisher:')) translate('SongsPlugin.SongBookForm', '&Publisher:'))

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
""" """
Class documentation goes here. Class documentation goes here.
@ -50,9 +49,9 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
def accept(self): def accept(self):
if not self.NameEdit.text(): if not self.NameEdit.text():
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongBookForm', u'Error'), self, translate('SongsPlugin.SongBookForm', 'Error'),
translate(u'SongsPlugin.SongBookForm', translate('SongsPlugin.SongBookForm',
u'You need to type in a book name!'), 'You need to type in a name for the book.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.NameEdit.setFocus() self.NameEdit.setFocus()
return False return False

View File

@ -104,43 +104,43 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
if source_format == SongFormat.OpenLyrics: if source_format == SongFormat.OpenLyrics:
if self.OpenLyricsFileListWidget.count() == 0: if self.OpenLyricsFileListWidget.count() == 0:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'No OpenLyrics Files Selected'), 'No OpenLyrics Files Selected'),
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'You need to add at least one OpenLyrics ' 'You need to add at least one OpenLyrics '
u'song file to import from.'), 'song file to import from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.OpenLyricsAddButton.setFocus() self.OpenLyricsAddButton.setFocus()
return False return False
elif source_format == SongFormat.OpenSong: elif source_format == SongFormat.OpenSong:
if self.OpenSongFileListWidget.count() == 0: if self.OpenSongFileListWidget.count() == 0:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'No OpenSong Files Selected'), 'No OpenSong Files Selected'),
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'You need to add at least one OpenSong ' 'You need to add at least one OpenSong '
u'song file to import from.'), 'song file to import from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.OpenSongAddButton.setFocus() self.OpenSongAddButton.setFocus()
return False return False
elif source_format == SongFormat.CCLI: elif source_format == SongFormat.CCLI:
if self.CCLIFileListWidget.count() == 0: if self.CCLIFileListWidget.count() == 0:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'No CCLI Files Selected'), 'No CCLI Files Selected'),
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'You need to add at least one CCLI file ' 'You need to add at least one CCLI file '
u'to import from.'), 'to import from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.CCLIAddButton.setFocus() self.CCLIAddButton.setFocus()
return False return False
elif source_format == SongFormat.CSV: elif source_format == SongFormat.CSV:
if self.CSVFilenameEdit.text().isEmpty(): if self.CSVFilenameEdit.text().isEmpty():
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'No CSV File Selected'), 'No CSV File Selected'),
translate(u'SongsPlugin.SongImportForm', translate('SongsPlugin.ImportWizardForm',
u'You need to specify a CSV file to import from.'), 'You need to specify a CSV file to import from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.CSVFilenameEdit.setFocus() self.CSVFilenameEdit.setFocus()
return False return False
@ -192,7 +192,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setMaximum(1188)
self.ImportProgressBar.setValue(0) self.ImportProgressBar.setValue(0)
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'SongsPlugin.SongImportForm', u'Starting import...')) translate('SongsPlugin.ImportWizardForm', 'Starting import...'))
Receiver.send_message(u'process_events') Receiver.send_message(u'process_events')
def performImport(self): def performImport(self):
@ -243,10 +243,10 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
# self.manager.save_meta_data(license_version, license_version, # self.manager.save_meta_data(license_version, license_version,
# license_copyright, license_permission) # license_copyright, license_permission)
# self.manager.reload_bibles() # self.manager.reload_bibles()
# self.ImportProgressLabel.setText(translate(u'SongsPlugin.SongImportForm', u'Finished import.')) # self.ImportProgressLabel.setText(translate('SongsPlugin.SongImportForm', 'Finished import.'))
# else: # else:
# self.ImportProgressLabel.setText( # self.ImportProgressLabel.setText(
# translate(u'SongsPlugin.SongImportForm', u'Your Bible import failed.')) # translate('SongsPlugin.SongImportForm', 'Your Bible import failed.'))
# importer.delete() # importer.delete()
def postImport(self): def postImport(self):

View File

@ -230,54 +230,54 @@ class Ui_SongImportWizard(object):
def retranslateUi(self, SongImportWizard): def retranslateUi(self, SongImportWizard):
SongImportWizard.setWindowTitle( SongImportWizard.setWindowTitle(
translate(u'SongsPlugin.SongImportWizard', u'Song Import Wizard')) translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
self.TitleLabel.setText( self.TitleLabel.setText(
'<span style="font-size:14pt; font-weight:600;">%s</span>' % \ u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate(u'SongsPlugin.SongImportWizard', translate('SongsPlugin.ImportWizardForm',
u'Welcome to the Song Import Wizard')) 'Welcome to the Song Import Wizard'))
self.InformationLabel.setText( self.InformationLabel.setText(
translate(u'SongsPlugin.SongImportWizard', translate('SongsPlugin.ImportWizardForm',
u'This wizard will help you to import songs from a variety of ' 'This wizard will help you to import songs from a variety of '
u'formats. Click the next button below to start the process by ' 'formats. Click the next button below to start the process by '
u'selecting a format to import from.')) 'selecting a format to import from.'))
self.SourcePage.setTitle( self.SourcePage.setTitle(
translate(u'SongsPlugin.SongImportWizard', u'Select Import Source')) translate('SongsPlugin.ImportWizardForm', 'Select Import Source'))
self.SourcePage.setSubTitle( self.SourcePage.setSubTitle(
translate(u'SongsPlugin.SongImportWizard', translate('SongsPlugin.ImportWizardForm',
u'Select the import format, and where to import from.')) 'Select the import format, and where to import from.'))
self.FormatLabel.setText( self.FormatLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Format:')) translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.FormatComboBox.setItemText(0, self.FormatComboBox.setItemText(0,
translate(u'SongsPlugin.SongImportWizard', u'OpenLyrics')) translate('SongsPlugin.ImportWizardForm', 'OpenLyrics'))
self.FormatComboBox.setItemText(1, self.FormatComboBox.setItemText(1,
translate(u'SongsPlugin.SongImportWizard', u'OpenSong')) translate('SongsPlugin.ImportWizardForm', 'OpenSong'))
self.FormatComboBox.setItemText(2, self.FormatComboBox.setItemText(2,
translate(u'SongsPlugin.SongImportWizard', u'CCLI')) translate('SongsPlugin.ImportWizardForm', 'CCLI'))
self.FormatComboBox.setItemText(3, self.FormatComboBox.setItemText(3,
translate(u'SongsPlugin.SongImportWizard', u'CSV')) translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.OpenLyricsAddButton.setText( self.OpenLyricsAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.OpenLyricsRemoveButton.setText( self.OpenLyricsRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.OpenSongAddButton.setText( self.OpenSongAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.OpenSongRemoveButton.setText( self.OpenSongRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.CCLIAddButton.setText( self.CCLIAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.CCLIRemoveButton.setText( self.CCLIRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.CSVFilenameLabel.setText( self.CSVFilenameLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Filename:')) translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.CSVBrowseButton.setText( self.CSVBrowseButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Browse...')) translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.ImportPage.setTitle( self.ImportPage.setTitle(
translate(u'SongsPlugin.SongImportWizard', u'Importing')) translate('SongsPlugin.ImportWizardForm', 'Importing'))
self.ImportPage.setSubTitle( self.ImportPage.setSubTitle(
translate(u'SongsPlugin.SongImportWizard', translate('SongsPlugin.ImportWizardForm',
u'Please wait while your songs are imported.')) 'Please wait while your songs are imported.'))
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Ready.')) translate('SongsPlugin.ImportWizardForm', 'Ready.'))
self.ImportProgressBar.setFormat( self.ImportProgressBar.setFormat(
translate(u'SongsPlugin.SongImportWizard', u'%p%')) translate('SongsPlugin.ImportWizardForm', '%p%'))

View File

@ -25,12 +25,10 @@
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.plugins.songs.lib.classes import Author, Book, Topic
from songmaintenancedialog import Ui_SongMaintenanceDialog
from authorsform import AuthorsForm
from topicsform import TopicsForm
from songbookform import SongBookForm
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm
from openlp.plugins.songs.lib.db import Author, Book, Topic
from songmaintenancedialog import Ui_SongMaintenanceDialog
class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
@ -81,17 +79,17 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
else: else:
return -1 return -1
def _deleteItem(self, list_widget, get_func, del_func, reset_func, def _deleteItem(self, item_class, list_widget, reset_func, dlg_title,
dlg_title, del_text, err_text, sel_text): del_text, err_text, sel_text):
item_id = self._getCurrentItemId(list_widget) item_id = self._getCurrentItemId(list_widget)
if item_id != -1: if item_id != -1:
item = get_func(item_id) item = self.songmanager.get_object(item_class, item_id)
if item and len(item.songs) == 0: if item and len(item.songs) == 0:
if QtGui.QMessageBox.warning(self, dlg_title, del_text, if QtGui.QMessageBox.warning(self, dlg_title, del_text,
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes) QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
) == QtGui.QMessageBox.Yes: ) == QtGui.QMessageBox.Yes:
del_func(item.id) self.songmanager.delete_object(item_class, item.id)
reset_func() reset_func()
else: else:
QtGui.QMessageBox.critical(self, dlg_title, err_text) QtGui.QMessageBox.critical(self, dlg_title, err_text)
@ -100,7 +98,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetAuthors(self): def resetAuthors(self):
self.AuthorsListWidget.clear() self.AuthorsListWidget.clear()
authors = self.songmanager.get_authors() authors = self.songmanager.get_all_objects(Author, Author.display_name)
for author in authors: for author in authors:
if author.display_name: if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name) author_name = QtGui.QListWidgetItem(author.display_name)
@ -112,7 +110,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetTopics(self): def resetTopics(self):
self.TopicsListWidget.clear() self.TopicsListWidget.clear()
topics = self.songmanager.get_topics() topics = self.songmanager.get_all_objects(Topic, Topic.name)
for topic in topics: for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name) topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -120,7 +118,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetBooks(self): def resetBooks(self):
self.BooksListWidget.clear() self.BooksListWidget.clear()
books = self.songmanager.get_books() books = self.songmanager.get_all_objects(Book, Book.name)
for book in books: for book in books:
book_name = QtGui.QListWidgetItem(book.name) book_name = QtGui.QListWidgetItem(book.name)
book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id)) book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id))
@ -133,45 +131,45 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
first_name=unicode(self.authorform.FirstNameEdit.text()), first_name=unicode(self.authorform.FirstNameEdit.text()),
last_name=unicode(self.authorform.LastNameEdit.text()), last_name=unicode(self.authorform.LastNameEdit.text()),
display_name=unicode(self.authorform.DisplayEdit.text())) display_name=unicode(self.authorform.DisplayEdit.text()))
if self.songmanager.save_author(author): if self.songmanager.save_object(author):
self.resetAuthors() self.resetAuthors()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your author.')) 'Couldn\'t add your author.'))
def onTopicAddButtonClick(self): def onTopicAddButtonClick(self):
if self.topicform.exec_(): if self.topicform.exec_():
topic = Topic.populate(name=unicode(self.topicform.NameEdit.text())) topic = Topic.populate(name=unicode(self.topicform.NameEdit.text()))
if self.songmanager.save_topic(topic): if self.songmanager.save_object(topic):
self.resetTopics() self.resetTopics()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your topic.')) 'Couldn\'t add your topic.'))
def onBookAddButtonClick(self): def onBookAddButtonClick(self):
if self.bookform.exec_(): if self.bookform.exec_():
book = Book.populate( book = Book.populate(
name=unicode(self.bookform.NameEdit.text()), name=unicode(self.bookform.NameEdit.text()),
publisher=unicode(self.bookform.PublisherEdit.text())) publisher=unicode(self.bookform.PublisherEdit.text()))
if self.songmanager.save_book(book): if self.songmanager.save_object(book):
self.resetBooks() self.resetBooks()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your book.')) 'Couldn\'t add your book.'))
def onAuthorEditButtonClick(self): def onAuthorEditButtonClick(self):
author_id = self._getCurrentItemId(self.AuthorsListWidget) author_id = self._getCurrentItemId(self.AuthorsListWidget)
if author_id != -1: if author_id != -1:
author = self.songmanager.get_author(author_id) author = self.songmanager.get_object(Author, author_id)
# Just make sure none of the fields is None # Just make sure none of the fields is None
if author.first_name is None: if author.first_name is None:
author.first_name = u'' author.first_name = u''
@ -189,92 +187,86 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
author.last_name = unicode(self.authorform.LastNameEdit.text()) author.last_name = unicode(self.authorform.LastNameEdit.text())
author.display_name = unicode( author.display_name = unicode(
self.authorform.DisplayEdit.text()) self.authorform.DisplayEdit.text())
if self.songmanager.save_author(author): if self.songmanager.save_object(author):
self.resetAuthors() self.resetAuthors()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your author.')) 'Couldn\'t save your author.'))
def onTopicEditButtonClick(self): def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.TopicsListWidget) topic_id = self._getCurrentItemId(self.TopicsListWidget)
if topic_id != -1: if topic_id != -1:
topic = self.songmanager.get_topic(topic_id) topic = self.songmanager.get_object(Topic, topic_id)
self.topicform.NameEdit.setText(topic.name) self.topicform.NameEdit.setText(topic.name)
if self.topicform.exec_(False): if self.topicform.exec_(False):
topic.name = unicode(self.topicform.NameEdit.text()) topic.name = unicode(self.topicform.NameEdit.text())
if self.songmanager.save_topic(topic): if self.songmanager.save_object(topic):
self.resetTopics() self.resetTopics()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your topic.')) 'Couldn\'t save your topic.'))
def onBookEditButtonClick(self): def onBookEditButtonClick(self):
book_id = self._getCurrentItemId(self.BooksListWidget) book_id = self._getCurrentItemId(self.BooksListWidget)
if book_id != -1: if book_id != -1:
book = self.songmanager.get_book(book_id) book = self.songmanager.get_object(Book, book_id)
self.bookform.NameEdit.setText(book.name) self.bookform.NameEdit.setText(book.name)
self.bookform.PublisherEdit.setText(book.publisher) self.bookform.PublisherEdit.setText(book.publisher)
if self.bookform.exec_(False): if self.bookform.exec_(False):
book.name = unicode(self.bookform.NameEdit.text()) book.name = unicode(self.bookform.NameEdit.text())
book.publisher = unicode(self.bookform.PublisherEdit.text()) book.publisher = unicode(self.bookform.PublisherEdit.text())
if self.songmanager.save_book(book): if self.songmanager.save_object(book):
self.resetBooks() self.resetBooks()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm', self, translate('SongsPlugin.SongMaintenanceForm',
u'Error'), 'Error'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your book.')) 'Couldn\'t save your book.'))
def onAuthorDeleteButtonClick(self): def onAuthorDeleteButtonClick(self):
""" """
Delete the author if the author is not attached to any songs Delete the author if the author is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Author, self.AuthorsListWidget, self.resetAuthors,
self.AuthorsListWidget, self.songmanager.get_author, translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
self.songmanager.delete_author, self.resetAuthors, translate('SongsPlugin.SongMaintenanceForm',
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Author'), 'Are you sure you want to delete the selected author?'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected author?'), 'This author can\'t be deleted, they are currently '
translate(u'SongsPlugin.SongMaintenanceForm', 'assigned to at least one song.'),
u'This author can\'t be deleted, they are currently ' translate('SongsPlugin.SongMaintenanceForm',
u'assigned to at least one song.'), 'No author selected!'))
translate(u'SongsPlugin.SongMaintenanceForm',
u'No author selected!'))
def onTopicDeleteButtonClick(self): def onTopicDeleteButtonClick(self):
""" """
Delete the Book is the Book is not attached to any songs Delete the Book is the Book is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Topic, self.TopicsListWidget, self.resetTopics,
self.TopicsListWidget, self.songmanager.get_topic, translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
self.songmanager.delete_topic, self.resetTopics, translate('SongsPlugin.SongMaintenanceForm',
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Topic'), 'Are you sure you want to delete the selected topic?'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected topic?'), 'This topic can\'t be deleted, it is currently '
translate(u'SongsPlugin.SongMaintenanceForm', 'assigned to at least one song.'),
u'This topic can\'t be deleted, it is currently ' translate('SongsPlugin.SongMaintenanceForm',
u'assigned to at least one song.'), 'No topic selected!'))
translate(u'SongsPlugin.SongMaintenanceForm',
u'No topic selected!'))
def onBookDeleteButtonClick(self): def onBookDeleteButtonClick(self):
""" """
Delete the Book is the Book is not attached to any songs Delete the Book is the Book is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Book, self.BooksListWidget, self.resetBooks,
self.BooksListWidget, self.songmanager.get_book, translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
self.songmanager.delete_book, self.resetBooks, translate('SongsPlugin.SongMaintenanceForm',
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Book'), 'Are you sure you want to delete the selected book?'),
translate(u'SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected book?'), 'This book can\'t be deleted, it is currently '
translate(u'SongsPlugin.SongMaintenanceForm', 'assigned to at least one song.'),
u'This book can\'t be deleted, it is currently ' translate('SongsPlugin.SongMaintenanceForm', u'No book selected!'))
u'assigned to at least one song.'),
translate(u'SongsPlugin.SongMaintenanceForm', u'No book selected!'))

View File

@ -24,6 +24,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_TopicsDialog(object): class Ui_TopicsDialog(object):
@ -61,6 +62,6 @@ class Ui_TopicsDialog(object):
def retranslateUi(self, TopicsDialog): def retranslateUi(self, TopicsDialog):
TopicsDialog.setWindowTitle( TopicsDialog.setWindowTitle(
translate(u'SongsPlugin.TopicsForm', u'Topic Maintenance')) translate('SongsPlugin.TopicsForm', 'Topic Maintenance'))
self.NameLabel.setText( self.NameLabel.setText(
translate(u'SongsPlugin.TopicsForm', u'Topic name:')) translate('SongsPlugin.TopicsForm', 'Topic name:'))

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
""" """
Class documentation goes here. Class documentation goes here.
@ -49,9 +48,9 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def accept(self): def accept(self):
if not self.NameEdit.text(): if not self.NameEdit.text():
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.TopicsForm', u'Error'), self, translate('SongsPlugin.TopicsForm', 'Error'),
translate(u'SongsPlugin.TopicsForm', translate('SongsPlugin.TopicsForm',
u'You need to type in a topic name!'), 'You need to type in a topic name!'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.NameEdit.setFocus() self.NameEdit.setFocus()
return False return False

View File

@ -47,19 +47,19 @@ class VerseType(object):
The type to return a string for The type to return a string for
""" """
if verse_type == VerseType.Verse: if verse_type == VerseType.Verse:
return translate(u'VerseType', u'Verse') return translate('VerseType', 'Verse')
elif verse_type == VerseType.Chorus: elif verse_type == VerseType.Chorus:
return translate(u'VerseType', u'Chorus') return translate('VerseType', 'Chorus')
elif verse_type == VerseType.Bridge: elif verse_type == VerseType.Bridge:
return translate(u'VerseType', u'Bridge') return translate('VerseType', 'Bridge')
elif verse_type == VerseType.PreChorus: elif verse_type == VerseType.PreChorus:
return translate(u'VerseType', u'Pre-Chorus') return translate('VerseType', 'Pre-Chorus')
elif verse_type == VerseType.Intro: elif verse_type == VerseType.Intro:
return translate(u'VerseType', u'Intro') return translate('VerseType', 'Intro')
elif verse_type == VerseType.Ending: elif verse_type == VerseType.Ending:
return translate(u'VerseType', u'Ending') return translate('VerseType', 'Ending')
elif verse_type == VerseType.Other: elif verse_type == VerseType.Other:
return translate(u'VerseType', u'Other') return translate('VerseType', 'Other')
@staticmethod @staticmethod
def from_string(verse_type): def from_string(verse_type):
@ -94,6 +94,10 @@ class VerseType(object):
from manager import SongManager from manager import SongManager
from songstab import SongsTab from songstab import SongsTab
from mediaitem import SongMediaItem from mediaitem import SongMediaItem
from songimport import SongImport
try:
from sofimport import SofImport from sofimport import SofImport
from oooimport import OooImport from oooimport import OooImport
from songimport import SongImport except ImportError:
pass

Some files were not shown because too many files have changed in this diff Show More