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
_eric4project
.pylint.d
*.qm
openlp/core/resources.py.old

View File

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

View File

@ -163,7 +163,7 @@ def main():
parser.add_option("-s", "--style", dest="style",
help="Set the Qt4 style (passed directly to Qt4).")
# Set up logging
log_path = AppLocation.get_directory(AppLocation.ConfigDir)
log_path = AppLocation.get_directory(AppLocation.CacheDir)
if not os.path.exists(log_path):
os.makedirs(log_path)
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 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`lib` module contains most of the components and libraries that make
OpenLP work.
@ -49,7 +48,8 @@ def translate(context, text, comment=None, count=-1):
The text to put into the translation tables for translation.
``comment``
A optional comment for translators.
An identifying string for when the same text is used in different roles
within the same context.
``count``
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):
"""
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)
if icon:
@ -132,6 +144,15 @@ def context_menu_action(base, icon, text, slot):
def context_menu(base, icon, text):
"""
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.setIcon(build_icon(icon))
@ -140,6 +161,9 @@ def context_menu(base, icon, text):
def context_menu_separator(base):
"""
Add a separator to a context menu
``base``
The menu object to add the separator to
"""
action = QtGui.QAction(u'', base)
action.setSeparator(True)
@ -166,6 +190,22 @@ def resize_image(image, width, height):
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
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):
"""
@ -191,5 +231,4 @@ from themexmlhandler import ThemeXML
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
from basemodel import BaseModel
from baselistwithdnd import BaseListWithDnD

View File

@ -22,17 +22,20 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Extend QListWidget to handle drag and drop functionality
"""
from PyQt4 import QtCore, QtGui
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):
"""
Initialise the list widget
"""
QtGui.QListWidget.__init__(self, parent)
self.parent = parent
# this must be set by the class which is inheriting
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 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Provide additional functionality required by OpenLP from the inherited
QDockWidget.
"""
import logging
from PyQt4 import QtGui

View File

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

View File

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

View File

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

View File

@ -22,7 +22,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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
from PyQt4 import QtGui, QtCore

View File

@ -90,7 +90,7 @@ class ServiceItem(object):
self.from_plugin = False
self.capabilities = []
self.is_valid = True
self.cache = []
self.cache = {}
self.icon = None
def add_capability(self, capability):
@ -129,7 +129,7 @@ class ServiceItem(object):
"""
log.debug(u'Render called')
self._display_frames = []
self.cache = []
self.clear_cache()
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
if self.theme is None:
@ -149,7 +149,8 @@ class ServiceItem(object):
self._display_frames.append({u'title': title,
u'text': lines.rstrip(),
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))
elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames:
@ -172,8 +173,7 @@ class ServiceItem(object):
else:
self.render_manager.set_override_theme(self.theme)
format = self._display_frames[row][u'text'].split(u'\n')
#if screen blank then do not display footer
if len(self.cache) > 0 and self.cache[row] is not None:
if self.cache.get(row):
frame = self.cache[row]
else:
if format[0]:
@ -304,7 +304,7 @@ class ServiceItem(object):
def merge(self, other):
"""
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.
"""
self._uuid = other._uuid
@ -385,3 +385,8 @@ class ServiceItem(object):
"""
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 #
# 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
from PyQt4 import QtCore
@ -56,6 +61,9 @@ class SettingsManager(object):
u'user interface/preview panel', QtCore.QVariant(True)).toBool()
def togglePreviewPanel(self, isVisible):
"""
Toggle the preview panel visibility.
"""
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(isVisible))

View File

@ -22,7 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Provide the theme XML and handling functions for OpenLP v2 themes.
"""
import os
from xml.dom.minidom import Document
@ -339,7 +341,8 @@ class ThemeXML(object):
"""
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):
"""
@ -364,7 +367,8 @@ class ThemeXML(object):
``xml``
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()
master = u''
for element in xml_iter:

View File

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

View File

@ -168,14 +168,15 @@ class Theme(object):
theme_strings.append(u'_%s_' % (getattr(self, key)))
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
``xml``
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()
for element in xml_iter:
delphi_color_change = False

View File

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

View File

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

View File

@ -45,18 +45,67 @@ class DisplayManager(QtGui.QWidget):
QtGui.QWidget.__init__(self)
self.screens = screens
self.videoDisplay = VideoDisplay(self, screens)
self.audioPlayer = AudioPlayer(self)
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):
self.videoDisplay.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):
"""
Handles the closure of the displays
"""
self.videoDisplay.close()
self.audioPlayer.close()
self.mainDisplay.close()
class DisplayWidget(QtGui.QWidget):
class DisplayWidget(QtGui.QGraphicsView):
"""
Customised version of QTableWidget which can respond to keyboard
events.
@ -117,32 +166,26 @@ class MainDisplay(DisplayWidget):
log.debug(u'Initialisation started')
DisplayWidget.__init__(self, parent)
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.setWindowTitle(u'OpenLP Display')
# WA_TranslucentBackground is not available in QT4.4
try:
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
except AttributeError:
pass
self.screens = screens
self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self)
self.display_text.setScaledContents(True)
self.display_alert = QtGui.QLabel(self)
self.display_alert.setScaledContents(True)
self.setupScene()
self.setupImage()
self.setupText()
self.setupAlert()
self.setupBlank()
self.primary = True
self.blankFrame = None
self.frame = None
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_start'), self.hideDisplayForVideo)
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_background'), self.hideDisplayForVideo)
#Hide desktop for now untill we know where to put it
#and what size it should be.
self.setVisible(False)
def setup(self):
"""
@ -153,12 +196,8 @@ class MainDisplay(DisplayWidget):
self.setVisible(False)
self.screen = self.screens.current
#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.scene.setSceneRect(0,0,self.size().width(), self.size().height())
#Build a custom splash screen
self.InitialFrame = QtGui.QImage(
self.screen[u'size'].width(),
@ -186,30 +225,58 @@ class MainDisplay(DisplayWidget):
self.transparent = QtGui.QPixmap(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
self.frameView(self.transparent)
# self.display_text.setPixmap(self.transparent)
#self.frameView(self.transparent)
# To display or not to display?
if not self.screen[u'primary']:
self.showFullScreen()
self.setVisible(True)
self.primary = False
else:
self.setVisible(False)
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):
log.debug(u'resetDisplay')
Receiver.send_message(u'slidecontroller_live_stop_loop')
if self.primary:
self.setVisible(False)
else:
self.showFullScreen()
self.setVisible(True)
def hideDisplayForVideo(self):
"""
Hides the main display if for the video to be played
"""
self.hideDisplay(HideMode.Screen)
# def hideDisplayForVideo(self):
# """
# Hides the main display if for the video to be played
# """
# self.hideDisplay(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
"""
log.debug(u'hideDisplay mode = %d', mode)
self.storeImage = QtGui.QPixmap(self.display_image.pixmap())
self.storeText = QtGui.QPixmap(self.display_text.pixmap())
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
#self.display_text.setPixmap(self.transparent)
if mode == HideMode.Screen:
self.display_image.setPixmap(self.transparent)
#self.display_image.setPixmap(self.transparent)
self.setVisible(False)
elif mode == HideMode.Blank:
self.display_image.setPixmap(
self.display_blank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
else:
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))
else:
self.display_image.setPixmap(
self.display_blank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
self.moveToTop()
def moveToTop(self):
log.debug(u'moveToTop')
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
self.show()
def showDisplay(self):
def showDisplay(self, message=u''):
"""
Show the stored layers so the screen reappears as it was
originally.
Make the stored images None to release memory.
"""
log.debug(u'showDisplay')
if self.storeImage:
self.display_image.setPixmap(self.storeImage)
self.display_alert.setPixmap(self.transparent)
if self.storeText:
self.display_text.setPixmap(self.storeText)
self.storeImage = None
self.store = None
self.moveToTop()
self.display_blank.setPixmap(self.transparent)
#Trigger actions when display is active again
Receiver.send_message(u'maindisplay_active')
def addImageWithText(self, frame):
@ -263,21 +315,24 @@ class MainDisplay(DisplayWidget):
frame = resize_image(
frame, self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
self.moveToTop()
def setAlertSize(self, top, height):
log.debug(u'setAlertSize')
self.display_alert.setGeometry(
QtCore.QRect(0, top,
self.screen[u'size'].width(), height))
def addAlertImage(self, frame, blank=False):
def addAlert(self, message, location):
"""
Places the Alert text on the display at the correct location
``messgae``
Text to be displayed
``location``
Where on the screen the text should be. From the AlertTab
Combo box.
"""
log.debug(u'addAlertImage')
if blank:
self.display_alert.setPixmap(self.transparent)
if location == 0:
self.alertText.setPos(0, 0)
elif location == 1:
self.alertText.setPos(0,self.size().height()/2)
else:
self.display_alert.setPixmap(frame)
self.moveToTop()
self.alertText.setPos(0,self.size().height() - 76)
self.alertText.setHtml(message)
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
``frame``
Image frame to be rendered
``transition``
Are transitions required.
"""
log.debug(u'frameView %d' % (display))
log.debug(u'frameView %d' % display)
if display:
if transition:
if self.frame is not None:
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(self.frame))
self.repaint()
self.update()
self.frame = None
if frame[u'trans'] is not None:
self.display_text.setPixmap(
@ -311,7 +368,6 @@ class MainDisplay(DisplayWidget):
self.display_frame = frame
if not self.isVisible() and self.screens.display:
self.setVisible(True)
self.showFullScreen()
else:
self.storeText = QtGui.QPixmap.fromImage(frame[u'main'])
@ -339,37 +395,29 @@ class VideoDisplay(Phonon.VideoWidget):
self.screens = screens
self.hidden = False
self.message = None
self.mediaActive = False
self.mediaObject = Phonon.MediaObject()
self.setAspectRatio(aspect)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.audioObject)
flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog
# WindowsStaysOnBottomHint is not available in QT4.4
try:
flags = flags | QtCore.Qt.WindowStaysOnBottomHint
except AttributeError:
pass
## # WindowsStaysOnBottomHint is not available in QT4.4
# try:
# flags = flags | QtCore.Qt.WindowStaysOnBottomHint
# except AttributeError:
# pass
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.SIGNAL(u'videodisplay_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_stop'), self.onMediaStop)
QtCore.QObject.connect(Receiver.get_receiver(),
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.SIGNAL(u'config_updated'), self.setup)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaBackground)
QtCore.SIGNAL(u'finished()'), self.onMediaStop)
self.setVisible(False)
def keyPressEvent(self, event):
@ -392,38 +440,48 @@ class VideoDisplay(Phonon.VideoWidget):
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
# To display or not to display?
if not self.screen[u'primary'] and self.isVisible():
self.showFullScreen()
if not self.screen[u'primary']: # and self.isVisible():
#self.showFullScreen()
self.setVisible(False)
self.primary = False
else:
self.setVisible(False)
self.primary = True
def onMediaBackground(self, message=None):
def closeEvent(self, event):
"""
Play a video triggered from the video plugin with the
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
Shutting down so clean up connections
"""
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()
self.onMediaStop()
for pth in self.outputPaths():
disconnected = pth.disconnect()
# def onMediaBackground(self, message=None):
# """
# Play a video triggered from the video plugin with the
# 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)
# #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):
"""
Set up a video to play from the serviceitem.
"""
log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(),
message[0].get_frame_title())
file = os.path.join(message.get_frame_path(),
message.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.mediaActive = True
self._play()
def onMediaPlay(self):
@ -442,7 +500,6 @@ class VideoDisplay(Phonon.VideoWidget):
log.debug(u'VideoDisplay _play called')
self.mediaObject.play()
self.setVisible(True)
self.showFullScreen()
def onMediaPause(self):
"""
@ -458,6 +515,7 @@ class VideoDisplay(Phonon.VideoWidget):
"""
log.debug(u'VideoDisplay Media stopped by user')
self.message = None
self.mediaActive = False
self.mediaObject.stop()
self.onMediaFinish()
@ -469,7 +527,7 @@ class VideoDisplay(Phonon.VideoWidget):
self.mediaObject.clearQueue()
self.setVisible(False)
def mediaHide(self):
def mediaHide(self, message=u''):
"""
Hide the video display
"""
@ -477,10 +535,90 @@ class VideoDisplay(Phonon.VideoWidget):
self.hidden = True
self.setVisible(False)
def mediaShow(self):
def mediaShow(self, message=''):
"""
Show the video disaply if it was already hidden
"""
if self.hidden:
self.hidden = False
if self.mediaActive:
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.app_version = app_version
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):
"""
@ -79,14 +79,14 @@ class VersionThread(QtCore.QThread):
remote_version[u'major'] = int(match.group(1))
remote_version[u'minor'] = int(match.group(2))
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))
match = self.version_splitter.match(self.app_version[u'full'])
if match:
local_version[u'major'] = int(match.group(1))
local_version[u'minor'] = int(match.group(2))
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))
if remote_version[u'major'] > local_version[u'major'] 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)
for dock_index in range(0, self.media_dock.count()):
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.removeItem(dock_index)

View File

@ -73,6 +73,14 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
for frame in self.itemList:
item_name = QtGui.QListWidgetItem(frame[u'title'])
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):
"""
@ -83,6 +91,10 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
row = self.listWidget.row(item)
self.itemList.remove(self.itemList[row])
self.loadData()
if row == self.listWidget.count():
self.listWidget.setCurrentRow(row - 1)
else:
self.listWidget.setCurrentRow(row)
def onItemUp(self):
"""

View File

@ -33,7 +33,7 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
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.utils import AppLocation
@ -134,15 +134,13 @@ class ServiceManager(QtGui.QWidget):
self.ThemeLabel = QtGui.QLabel(translate('ServiceManager', 'Theme:'),
self)
self.ThemeLabel.setMargin(3)
self.Toolbar.addWidget(self.ThemeLabel)
self.Toolbar.addToolbarWidget(u'ThemeLabel', self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(self.Toolbar)
self.ThemeComboBox.setToolTip(translate('ServiceManager',
'Select a theme for the service'))
self.ThemeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
self.ThemeWidget.setDefaultWidget(self.ThemeComboBox)
self.Toolbar.addAction(self.ThemeWidget)
self.Toolbar.addToolbarWidget(u'ThemeWidget', self.ThemeComboBox)
self.Layout.addWidget(self.Toolbar)
# Create the service manager list
self.ServiceManagerList = ServiceManagerList(self)
@ -214,6 +212,8 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
QtCore.QObject.connect(Receiver.get_receiver(),
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
self.service_theme = unicode(QtCore.QSettings().value(
self.parent.serviceSettingsSection + u'/service theme',
@ -661,9 +661,8 @@ class ServiceManager(QtGui.QWidget):
filename = unicode(filename)
name = filename.split(os.path.sep)
if filename:
SettingsManager.set_last_dir(
self.parent.serviceSettingsSection,
os.path.split(filename)[0])
SettingsManager.set_last_dir(self.parent.serviceSettingsSection,
name[0])
zip = None
file_to = None
try:
@ -677,7 +676,7 @@ class ServiceManager(QtGui.QWidget):
translate('ServiceManager',
'File is not a valid service.\n'
'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'))
continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
@ -697,7 +696,7 @@ class ServiceManager(QtGui.QWidget):
self.onNewService()
for item in items:
serviceitem = ServiceItem()
serviceitem.RenderManager = self.parent.RenderManager
serviceitem.render_manager = self.parent.RenderManager
serviceitem.set_from_service(item, self.servicePath)
self.validateItem(serviceitem)
self.addServiceItem(serviceitem)
@ -757,6 +756,18 @@ class ServiceManager(QtGui.QWidget):
QtCore.QVariant(self.service_theme))
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):
"""
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.loopList = [
u'Start Loop',
u'Stop Loop',
u'Loop Separator',
u'Image SpinBox'
]
@ -196,18 +195,25 @@ class SlideController(QtGui.QWidget):
self.onSlideSelectedLast)
if self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.blankButton = self.Toolbar.addToolbarButton(
u'Blank Screen', u':/slides/slide_blank.png',
translate('SlideController', 'Blank Screen'),
self.onBlankDisplay, True)
self.themeButton = self.Toolbar.addToolbarButton(
u'Display Theme', u':/slides/slide_theme.png',
translate('SlideController', 'Theme Screen'),
self.onThemeDisplay, True)
self.hideButton = self.Toolbar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png',
translate('SlideController', 'Hide Screen'),
self.onHideDisplay, True)
self.HideMenu = QtGui.QToolButton(self.Toolbar)
self.HideMenu.setText(translate('SlideController', 'Hide'))
self.HideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.Toolbar.addToolbarWidget(u'Hide Menu', self.HideMenu)
self.HideMenu.setMenu(QtGui.QMenu(
translate('SlideController', 'Hide'), self.Toolbar))
self.BlankScreen = QtGui.QAction(QtGui.QIcon( u':/slides/slide_blank.png'), u'Blank Screen', self.HideMenu)
self.BlankScreen.setCheckable(True)
QtCore.QObject.connect(self.BlankScreen, QtCore.SIGNAL("triggered(bool)"), self.onBlankDisplay)
self.ThemeScreen = QtGui.QAction(QtGui.QIcon(u':/slides/slide_theme.png'), u'Blank to Theme', self.HideMenu)
self.ThemeScreen.setCheckable(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:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
@ -252,19 +258,6 @@ class SlideController(QtGui.QWidget):
u'Media Stop', u':/slides/media_playback_stop.png',
translate('SlideController', 'Start playing media'),
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:
self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
@ -340,6 +333,7 @@ class SlideController(QtGui.QWidget):
self.receiveSpinDelay)
if isLive:
self.Toolbar.makeWidgetsInvisible(self.loopList)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
else:
self.Toolbar.makeWidgetsInvisible(self.songEditList)
self.Mediabar.setVisible(False)
@ -436,8 +430,8 @@ class SlideController(QtGui.QWidget):
self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
self.Toolbar.makeWidgetsInvisible(self.loopList)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.loopList)
if QtCore.QSettings().value(
self.parent.songsSettingsSection + u'/show songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
@ -520,16 +514,20 @@ class SlideController(QtGui.QWidget):
log.debug(u'processManagerItem')
self.onStopLoop()
#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()
if serviceItem.is_media():
self.onMediaStart(serviceItem)
if self.isLive:
blanked = self.blankButton.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno])
# if self.isLive:
# blanked = self.blankButton.isChecked()
# else:
# blanked = False
# Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
# [serviceItem, self.isLive, blanked, slideno])
self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at
@ -537,7 +535,7 @@ class SlideController(QtGui.QWidget):
before = time.time()
#Clear the old serviceItem cache to release memory
if self.serviceItem and self.serviceItem is not serviceItem:
self.serviceItem.cache = []
self.serviceItem.clear_cache()
self.serviceItem = serviceItem
self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0)
@ -655,7 +653,9 @@ class SlideController(QtGui.QWidget):
"""
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):
"""
@ -671,56 +671,57 @@ class SlideController(QtGui.QWidget):
def onBlankDisplay(self, checked):
"""
Handle the blank screen button
Handle the blank screen button actions
"""
log.debug(u'onBlankDisplay %d' % checked)
self.hideButton.setChecked(False)
self.themeButton.setChecked(False)
self.canDisplay = not checked
log.debug(u'onBlankDisplay %s' % checked)
self.HideMenu.setDefaultAction(self.BlankScreen)
self.BlankScreen.setChecked(checked)
self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(False)
QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(checked))
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
self.blankPlugin(True)
else:
Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False)
self.blankPlugin(checked)
def onThemeDisplay(self, checked):
"""
Handle the Theme screen button
"""
log.debug(u'onThemeDisplay %d' % checked)
self.blankButton.setChecked(False)
self.hideButton.setChecked(False)
self.canDisplay = False
log.debug(u'onThemeDisplay %s' % checked)
self.HideMenu.setDefaultAction(self.ThemeScreen)
self.BlankScreen.setChecked(False)
self.ThemeScreen.setChecked(checked)
self.DesktopScreen.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
self.blankPlugin(True)
else:
Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False)
self.blankPlugin(checked)
def onHideDisplay(self, checked):
"""
Handle the Hide screen button
"""
log.debug(u'onHideDisplay %d' % checked)
self.blankButton.setChecked(False)
self.themeButton.setChecked(False)
self.canDisplay = False
log.debug(u'onHideDisplay %s' % checked)
self.HideMenu.setDefaultAction(self.DesktopScreen)
self.BlankScreen.setChecked(False)
self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(checked)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.hidePlugin(True)
else:
Receiver.send_message(u'maindisplay_show')
self.hidePlugin(False)
self.hidePlugin(checked)
def blankPlugin(self, blank):
"""
Blank the display screen within a plugin if required.
"""
log.debug(u'blankPlugin %s ', blank)
if self.serviceItem is not None:
if blank:
Receiver.send_message(u'%s_blank'
@ -733,8 +734,9 @@ class SlideController(QtGui.QWidget):
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 hide:
Receiver.send_message(u'%s_hide'
@ -779,7 +781,7 @@ class SlideController(QtGui.QWidget):
log.log(
15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive:
self.mainDisplay.frameView(frame, True, self.canDisplay)
self.mainDisplay.frameView(frame, True)#, self.canDisplay)
self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)
@ -824,7 +826,7 @@ class SlideController(QtGui.QWidget):
return
Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
if self.serviceItem.is_command() and self.isLive:
self.updatePreview()
else:
row = self.PreviewListWidget.currentRow() + 1
@ -848,7 +850,7 @@ class SlideController(QtGui.QWidget):
return
Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
if self.serviceItem.is_command() and self.isLive:
self.updatePreview()
else:
row = self.PreviewListWidget.currentRow() - 1
@ -882,6 +884,8 @@ class SlideController(QtGui.QWidget):
if self.PreviewListWidget.rowCount() > 1:
self.timer_id = self.startTimer(
int(self.DelaySpinBox.value()) * 1000)
self.Toolbar.actions[u'Stop Loop'].setVisible(True)
self.Toolbar.actions[u'Start Loop'].setVisible(False)
def onStopLoop(self):
"""
@ -890,6 +894,8 @@ class SlideController(QtGui.QWidget):
if self.timer_id != 0:
self.killTimer(self.timer_id)
self.timer_id = 0
self.Toolbar.actions[u'Start Loop'].setVisible(True)
self.Toolbar.actions[u'Stop Loop'].setVisible(False)
def timerEvent(self, event):
"""
@ -921,8 +927,7 @@ class SlideController(QtGui.QWidget):
"""
log.debug(u'SlideController onMediaStart')
if self.isLive:
Receiver.send_message(u'videodisplay_start',
[item, self.blankButton.isChecked()])
Receiver.send_message(u'videodisplay_start', item)
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()

View File

@ -35,7 +35,7 @@ from openlp.core.ui import AmendThemeForm
from openlp.core.theme import Theme
from openlp.core.lib import OpenLPToolbar, context_menu_action, \
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
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
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()
if item:
theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString()))
self.amendThemeForm.loadTheme(theme)
@ -198,8 +199,9 @@ class ThemeManager(QtGui.QWidget):
self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
if check_item_selected(self.ThemeListWidget, translate('ThemeManager',
'You must select a theme to delete.')):
item = self.ThemeListWidget.currentItem()
if item:
theme = unicode(item.text())
# should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
@ -398,7 +400,7 @@ class ThemeManager(QtGui.QWidget):
self, translate('ThemeManager', 'Error'),
translate('ThemeManager', 'File is not a valid theme.\n'
'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'))
continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
@ -424,8 +426,8 @@ class ThemeManager(QtGui.QWidget):
xml_data = xml_data.decode(u'utf-8')
except UnicodeDecodeError:
log.exception(u'Theme XML is not UTF-8 '
'encoded.')
break;
u'encoded.')
break
if self.checkVersion1(xml_data):
# upgrade theme xml
filexml = self.migrateVersion122(xml_data)

View File

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

View File

@ -50,6 +50,7 @@ class AppLocation(object):
DataDir = 3
PluginsDir = 4
VersionDir = 5
CacheDir = 6
@staticmethod
def get_directory(dir_type=1):
@ -103,6 +104,20 @@ class AppLocation(object):
else:
plugin_path = os.path.split(openlp.__file__)[0]
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
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.endGroup()
if last_test != this_test:
version_string = u''
if current_version[u'build']:
req = urllib2.Request(
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 #
# 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 os
@ -42,50 +45,74 @@ class LanguageManager(object):
@staticmethod
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:
language = QtCore.QLocale.system().name()
lang_Path = AppLocation.get_directory(AppLocation.AppDir)
lang_Path = os.path.join(lang_Path, u'resources', u'i18n')
appTranslator = QtCore.QTranslator()
if appTranslator.load("openlp_" + language, lang_Path):
return appTranslator
app_translator = QtCore.QTranslator()
if app_translator.load("openlp_" + language, lang_Path):
return app_translator
@staticmethod
def find_qm_files():
"""
Find all available language files in this OpenLP install
"""
trans_dir = AppLocation.get_directory(AppLocation.AppDir)
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)
for name in fileNames:
fileNames.replaceInStrings(name, trans_dir.filePath(name))
return fileNames
for name in file_names:
file_names.replaceInStrings(name, trans_dir.filePath(name))
return file_names
@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.load(qmFile)
translator.load(qm_file)
return translator.translate('MainWindow', 'English')
@staticmethod
def get_language():
"""
Retrieve a saved language to use from settings
"""
settings = QtCore.QSettings(u'OpenLP', u'OpenLP')
language = unicode(settings.value(
u'general/language', QtCore.QVariant(u'[en]')).toString())
log.info(u'Language file: \'%s\' Loaded from conf file' % language)
regEx = QtCore.QRegExp("^\[(.*)\]")
if regEx.exactMatch(language):
reg_ex = QtCore.QRegExp("^\[(.*)\]")
if reg_ex.exactMatch(language):
LanguageManager.AutoLanguage = True
language = regEx.cap(1)
language = reg_ex.cap(1)
return language
@staticmethod
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:
language = u'[%s]' % qmList[actionName]
language = u'[%s]' % qm_list[action_name]
else:
language = u'%s' % qmList[actionName]
language = u'%s' % qm_list[action_name]
QtCore.QSettings().setValue(
u'general/language', QtCore.QVariant(language))
log.info(u'Language file: \'%s\' written to conf file' % language)
@ -96,17 +123,23 @@ class LanguageManager(object):
@staticmethod
def init_qm_list():
"""
Initialise the list of available translations
"""
LanguageManager.__qmList__ = {}
qmFiles = LanguageManager.find_qm_files()
for i, qmf in enumerate(qmFiles):
regEx = QtCore.QRegExp("^.*openlp_(.*).qm")
if regEx.exactMatch(qmf):
langName = regEx.cap(1)
qm_files = LanguageManager.find_qm_files()
for i, qmf in enumerate(qm_files):
reg_ex = QtCore.QRegExp("^.*openlp_(.*).qm")
if reg_ex.exactMatch(qmf):
lang_name = reg_ex.cap(1)
LanguageManager.__qmList__[u'%#2i %s' % (i+1,
LanguageManager.language_name(qmf))] = langName
LanguageManager.language_name(qmf))] = lang_name
@staticmethod
def get_qm_list():
"""
Return the list of available translations
"""
if LanguageManager.__qmList__ is None:
LanguageManager.init_qm_list()
return LanguageManager.__qmList__

View File

@ -24,5 +24,5 @@
###############################################################################
"""
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 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
log = logging.getLogger(__name__)
@ -37,15 +39,18 @@ class alertsPlugin(Plugin):
log.info(u'Alerts Plugin loaded')
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.icon = build_icon(u':/media/media_image.png')
self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self)
self.manager = DBManager()
self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active
def get_settings_tab(self):
"""
Return the settings tab for the Alerts plugin
"""
self.alertsTab = AlertsTab(self)
return self.alertsTab
@ -60,13 +65,13 @@ class alertsPlugin(Plugin):
"""
log.info(u'add 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.setObjectName(u'toolsAlertItem')
self.toolsAlertItem.setText(
translate(u'AlertsPlugin', u'&Alert'))
translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setStatusTip(
translate(u'AlertsPlugin', u'Show an alert message'))
translate('AlertsPlugin', 'Show an alert message'))
self.toolsAlertItem.setShortcut(u'F7')
self.service_manager.parent.ToolsMenu.addAction(self.toolsAlertItem)
QtCore.QObject.connect(self.toolsAlertItem,
@ -94,7 +99,7 @@ class alertsPlugin(Plugin):
self.alertForm.exec_()
def about(self):
about_text = translate(u'AlertsPlugin',
u'<b>Alerts Plugin</b><br>This plugin '
u'controls the displaying of alerts on the presentations screen')
about_text = translate('AlertsPlugin',
'<b>Alerts Plugin</b><br>This plugin '
'controls the displaying of alerts on the presentations screen')
return about_text

View File

@ -148,21 +148,20 @@ class Ui_AlertDialog(object):
def retranslateUi(self, AlertDialog):
AlertDialog.setWindowTitle(
translate(u'AlertsPlugin.AlertForm', u'Alert Message'))
translate('AlertsPlugin.AlertForm', 'Alert Message'))
self.AlertEntryLabel.setText(
translate(u'AlertsPlugin.AlertForm', u'Alert &text:'))
translate('AlertsPlugin.AlertForm', 'Alert &text:'))
self.AlertParameter.setText(
translate(u'AlertsPlugin.AlertForm', u'&Parameter(s):'))
translate('AlertsPlugin.AlertForm', '&Parameter(s):'))
self.NewButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&New'))
translate('AlertsPlugin.AlertForm', '&New'))
self.SaveButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&Save'))
translate('AlertsPlugin.AlertForm', '&Save'))
self.DeleteButton.setText(
translate(u'AlertsPlugin.AlertForm', u'&Delete'))
translate('AlertsPlugin.AlertForm', '&Delete'))
self.DisplayButton.setText(
translate(u'AlertsPlugin.AlertForm', u'Displ&ay'))
translate('AlertsPlugin.AlertForm', 'Displ&ay'))
self.DisplayCloseButton.setText(
translate(u'AlertsPlugin.AlertForm', u'Display && Cl&ose'))
translate('AlertsPlugin.AlertForm', 'Display && Cl&ose'))
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 openlp.plugins.alerts.lib.models import AlertItem
from openlp.core.lib import translate
from openlp.plugins.alerts.lib.db import AlertItem
from alertdialog import Ui_AlertDialog
@ -62,7 +62,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def loadList(self):
self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts()
alerts = self.manager.get_all_objects(AlertItem, AlertItem.text)
for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
@ -82,7 +82,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item = self.AlertListWidget.currentItem()
if item:
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)
self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'')
@ -93,12 +93,12 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def onNewClick(self):
if len(self.AlertTextEdit.text()) == 0:
QtGui.QMessageBox.information(self,
translate(u'AlertsPlugin.AlertForm', u'Item selected to Add'),
translate(u'AlertsPlugin.AlertForm', u'Missing data'))
translate('AlertsPlugin.AlertForm', 'Item selected to Add'),
translate('AlertsPlugin.AlertForm', 'Missing data'))
else:
alert = AlertItem()
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
self.manager.save_object(alert)
self.AlertTextEdit.setText(u'')
self.loadList()
@ -107,9 +107,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
Save an alert
"""
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())
self.manager.save_alert(alert)
self.manager.save_object(alert)
self.item_id = None
self.loadList()
else:
@ -153,4 +153,3 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.parent.alertsmanager.displayAlert(text)
return True
return False

View File

@ -25,4 +25,3 @@
from alertsmanager import AlertsManager
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__)
HTMLCODE = u"""
<p style=\"color:%s;
background-color:%s;
font-family:%s;
font-size: %spt; \">
%s
</p>
"""
class AlertsManager(QtCore.QObject):
"""
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.QObject.connect(Receiver.get_receiver(),
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):
"""
@ -88,49 +75,43 @@ class AlertsManager(QtCore.QObject):
display text
"""
log.debug(u'display alert called %s' % text)
if not self.screen:
self.screenChanged()
self.alertList.append(text)
if self.timer_id != 0:
Receiver.send_message(u'maindisplay_status_text',
translate(u'AlertsPlugin.AlertsManager',
u'Alert message created and delayed'))
translate('AlertsPlugin.AlertsManager',
'Alert message created and delayed'))
return
Receiver.send_message(u'maindisplay_status_text', u'')
self.generateAlert()
def generateAlert(self):
"""
Format and request the Alert and start the timer
"""
log.debug(u'Generate Alert called')
if len(self.alertList) == 0:
return
text = self.alertList.pop(0)
alertTab = self.parent.alertsTab
alertframe = \
QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight)
alertframe.fill(QtCore.Qt.transparent)
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)
text = HTMLCODE % (alertTab.font_color, alertTab.bg_color,
alertTab.font_face, alertTab.font_size, text)
self.parent.preview_controller.parent.displayManager.addAlert(text, alertTab.location)
# check to see if we have a timer running
if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
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')
alertTab = self.parent.alertsTab
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.timer_id = 0
self.generateAlert()

View File

@ -38,7 +38,7 @@ class AlertsTab(SettingsTab):
def setupUi(self):
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.setSpacing(8)
self.AlertsLayout.setMargin(8)
@ -128,6 +128,7 @@ class AlertsTab(SettingsTab):
self.LocationComboBox = QtGui.QComboBox(self.LocationWidget)
self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.setObjectName(u'LocationComboBox')
self.LocationLayout.addWidget(self.LocationComboBox)
self.LocationSpacer = QtGui.QSpacerItem(147, 20,
@ -187,31 +188,33 @@ class AlertsTab(SettingsTab):
def retranslateUi(self):
self.FontGroupBox.setTitle(
translate(u'AlertsPlugin.AlertsTab', u'Font'))
translate('AlertsPlugin.AlertsTab', 'Font'))
self.FontLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Name:'))
translate('AlertsPlugin.AlertsTab', 'Font Name:'))
self.FontColorLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Color:'))
translate('AlertsPlugin.AlertsTab', 'Font Color:'))
self.BackgroundColorLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Background Color:'))
translate('AlertsPlugin.AlertsTab', 'Background Color:'))
self.FontSizeLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Font Size:'))
translate('AlertsPlugin.AlertsTab', 'Font Size:'))
self.FontSizeSpinBox.setSuffix(
translate(u'AlertsPlugin.AlertsTab', u'pt'))
translate('AlertsPlugin.AlertsTab', 'pt'))
self.TimeoutLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Alert timeout:'))
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix(
translate(u'AlertsPlugin.AlertsTab', u's'))
translate('AlertsPlugin.AlertsTab', 's'))
self.LocationLabel.setText(
translate(u'AlertsPlugin.AlertsTab', u'Location:'))
translate('AlertsPlugin.AlertsTab', 'Location:'))
self.PreviewGroupBox.setTitle(
translate(u'AlertsPlugin.AlertsTab', u'Preview'))
translate('AlertsPlugin.AlertsTab', 'Preview'))
self.FontPreview.setText(
translate(u'AlertsPlugin.AlertsTab', u'openlp.org'))
translate('AlertsPlugin.AlertsTab', 'openlp.org'))
self.LocationComboBox.setItemText(0,
translate(u'AlertsPlugin.AlertsTab', u'Top'))
translate('AlertsPlugin.AlertsTab', 'Top'))
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):
new_color = QtGui.QColorDialog.getColor(
@ -294,5 +297,5 @@ class AlertsTab(SettingsTab):
font.setBold(True)
font.setPointSize(self.font_size)
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))

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 #
# 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.orm import scoped_session, sessionmaker, mapper
from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.plugins.alerts.lib.meta import metadata
from openlp.plugins.alerts.lib.tables import *
from openlp.plugins.alerts.lib.classes import *
from openlp.core.lib.db import BaseModel, init_db
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)
metadata.create_all(checkfirst=True)
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 #
###############################################################################
"""
The :mod:`bibles' modules provides the Bible plugin to enable OpenLP to display
scripture
The :mod:`bibles' module provides the Bible plugin to enable OpenLP to display
scripture.
"""

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,20 +23,99 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import logging
import chardet
import re
from sqlalchemy import or_
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.plugins.bibles.lib.models import *
from openlp.core.lib.db import BaseModel, init_db, Manager
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
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)
if u'file' in kwargs:
self.file = kwargs[u'file']
self.db_file = os.path.join(kwargs[u'path'], 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)
Manager.__init__(self, u'bibles', init_schema, self.file)
if u'file' in kwargs:
self.get_name()
self.wizard = None
def stop_import(self):
"""
@ -105,7 +168,7 @@ class BibleDB(QtCore.QObject):
"""
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:
self.name = version_name.value
else:
@ -125,16 +188,6 @@ class BibleDB(QtCore.QObject):
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
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):
"""
This method basically just initialialises the database. It is called
@ -146,36 +199,11 @@ class BibleDB(QtCore.QObject):
The actual Qt wizard form.
"""
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_testament(u'Old Testament')
self.create_testament(u'New Testament')
self.create_testament(u'Apocrypha')
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()
self.save_object(Testament.populate(name=u'Old Testament'))
self.save_object(Testament.populate(name=u'New Testament'))
self.save_object(Testament.populate(name=u'Apocrypha'))
return self.name
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)
book = Book.populate(name=name, abbreviation=abbrev,
testament_id=testament)
self.session.add(book)
self.commit()
self.save_object(book)
return book
def create_chapter(self, book_id, chapter, textlist):
@ -221,7 +248,7 @@ class BibleDB(QtCore.QObject):
text = verse_text
)
self.session.add(verse)
self.commit()
self.session.commit()
def create_verse(self, book_id, chapter, verse, text):
"""
@ -252,31 +279,32 @@ class BibleDB(QtCore.QObject):
return verse
def create_meta(self, key, value):
log.debug(u'save_meta %s/%s', key, value)
self.session.add(BibleMeta.populate(key=key, value=value))
self.commit()
"""
Utility method to save BibleMeta objects in a Bible database
def get_books(self):
log.debug(u'BibleDB.get_books()')
return self.session.query(Book).order_by(Book.id).all()
``key``
The key for this instance
``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):
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.session.query(Book)\
.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
"""
Return a book object from the database
def get_chapter(self, id, chapter):
log.debug(u'BibleDB.get_chapter("%s", %s)', id, chapter)
return self.session.query(Verse)\
.filter_by(chapter=chapter)\
.filter_by(book_id=id)\
.first()
``book``
The name of the book to return
"""
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.session.query(Book).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_verses(self, reference_list):
"""
@ -316,11 +344,11 @@ class BibleDB(QtCore.QObject):
else:
log.debug(u'OpenLP failed to find book %s', book)
QtGui.QMessageBox.information(self.bible_plugin.media_item,
translate(u'BibleDB', u'Book not found'),
translate(u'BibleDB', u'The book you requested could not '
u'be found in this bible. Please check your spelling '
u'and that this is a complete bible not just one '
u'testament.'))
translate('BibleDB', 'Book not found'),
translate('BibleDB', u'The book you requested could not '
'be found in this bible. Please check your spelling '
'and that this is a complete bible not just one '
'testament.'))
return verse_list
def verse_search(self, text):
@ -351,6 +379,12 @@ class BibleDB(QtCore.QObject):
return verses
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)
count = self.session.query(Verse.chapter).join(Book)\
.filter(Book.name==book)\
@ -361,6 +395,15 @@ class BibleDB(QtCore.QObject):
return count
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)
count = self.session.query(Verse).join(Book)\
.filter(Book.name==book)\
@ -371,20 +414,10 @@ class BibleDB(QtCore.QObject):
else:
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):
"""
Utility debugging method to dump the contents of a bible
"""
log.debug(u'.........Dumping Bible Database')
log.debug('...............................Books ')
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.plugins.bibles.lib.common import BibleCommon, SearchResults, \
unescape
from openlp.plugins.bibles.lib.db import BibleDB
from openlp.plugins.bibles.lib.models import Book
from openlp.plugins.bibles.lib.db import BibleDB, Book
log = logging.getLogger(__name__)

View File

@ -29,12 +29,12 @@ from PyQt4 import QtCore
from openlp.core.lib import SettingsManager
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB, Book, BibleMeta
from common import parse_reference
from opensong import OpenSongBible
from osis import OSISBible
from csvbible import CSVBible
from db import BibleDB
from http import HTTPBible
log = logging.getLogger(__name__)
@ -137,11 +137,13 @@ class BibleManager(object):
log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible
# 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:
download_name = \
self.db_cache[name].get_meta(u'download name').value
meta_proxy = self.db_cache[name].get_meta(u'proxy url')
download_name = self.db_cache[name].get_object(BibleMeta,
u'download name').value
meta_proxy = self.db_cache[name].get_object(BibleMeta,
u'proxy url')
web_bible = HTTPBible(self.parent, path=self.path,
file=filename, download_source=source.value,
download_name=download_name)
@ -196,7 +198,7 @@ class BibleManager(object):
u'name': 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):
@ -249,7 +251,7 @@ class BibleManager(object):
Returns the meta data for a given 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):
"""

View File

@ -43,7 +43,8 @@ class BibleListView(BaseListWithDnD):
BaseListWithDnD.__init__(self, parent)
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):
@ -70,7 +71,7 @@ class BibleMediaItem(MediaManagerItem):
return unicode(obj)
def initPluginNameVisible(self):
self.PluginNameVisible = translate(u'BiblesPlugin.MediaItem', u'Bible')
self.PluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
@ -147,7 +148,7 @@ class BibleMediaItem(MediaManagerItem):
self.QuickMessage.setObjectName(u'QuickMessage')
self.QuickLayout.addWidget(self.QuickMessage, 6, 0, 1, 3)
self.SearchTabWidget.addTab(self.QuickTab,
translate(u'BiblesPlugin.MediaItem', u'Quick'))
translate('BiblesPlugin.MediaItem', 'Quick'))
QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1)
@ -232,7 +233,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedMessage.setObjectName(u'AdvancedMessage')
self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3)
self.SearchTabWidget.addTab(self.AdvancedTab,
translate(u'BiblesPlugin.MediaItem', u'Advanced'))
translate('BiblesPlugin.MediaItem', 'Advanced'))
# Add the search tab widget to the page layout
self.PageLayout.addWidget(self.SearchTabWidget)
# Combo Boxes
@ -291,47 +292,47 @@ class BibleMediaItem(MediaManagerItem):
def retranslateUi(self):
log.debug(u'retranslateUi')
self.QuickVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Version:'))
translate('BiblesPlugin.MediaItem', 'Version:'))
self.QuickSecondVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Dual:'))
translate('BiblesPlugin.MediaItem', 'Dual:'))
self.QuickSearchLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Search Type:'))
translate('BiblesPlugin.MediaItem', 'Search Type:'))
self.QuickSearchLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Find:'))
translate('BiblesPlugin.MediaItem', 'Find:'))
self.QuickSearchButton.setText(
translate(u'BiblesPlugin.MediaItem', u'Search'))
translate('BiblesPlugin.MediaItem', 'Search'))
self.QuickClearLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Results:'))
translate('BiblesPlugin.MediaItem', 'Results:'))
self.AdvancedVersionLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Version:'))
translate('BiblesPlugin.MediaItem', 'Version:'))
self.AdvancedSecondBibleLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Dual:'))
translate('BiblesPlugin.MediaItem', 'Dual:'))
self.AdvancedBookLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Book:'))
translate('BiblesPlugin.MediaItem', 'Book:'))
self.AdvancedChapterLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Chapter:'))
translate('BiblesPlugin.MediaItem', 'Chapter:'))
self.AdvancedVerseLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Verse:'))
translate('BiblesPlugin.MediaItem', 'Verse:'))
self.AdvancedFromLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'From:'))
translate('BiblesPlugin.MediaItem', 'From:'))
self.AdvancedToLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'To:'))
translate('BiblesPlugin.MediaItem', 'To:'))
self.AdvancedClearLabel.setText(
translate(u'BiblesPlugin.MediaItem', u'Results:'))
translate('BiblesPlugin.MediaItem', 'Results:'))
self.AdvancedSearchButton.setText(
translate(u'BiblesPlugin.MediaItem', u'Search'))
translate('BiblesPlugin.MediaItem', 'Search'))
self.QuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Verse Search'))
translate('BiblesPlugin.MediaItem', 'Verse Search'))
self.QuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Text Search'))
translate('BiblesPlugin.MediaItem', 'Text Search'))
self.ClearQuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Clear'))
translate('BiblesPlugin.MediaItem', 'Clear'))
self.ClearQuickSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Keep'))
translate('BiblesPlugin.MediaItem', 'Keep'))
self.ClearAdvancedSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Clear'))
translate('BiblesPlugin.MediaItem', 'Clear'))
self.ClearAdvancedSearchComboBox.addItem(
translate(u'BiblesPlugin.MediaItem', u'Keep'))
translate('BiblesPlugin.MediaItem', 'Keep'))
def initialise(self):
log.debug(u'bible manager initialise')
@ -385,9 +386,9 @@ class BibleMediaItem(MediaManagerItem):
def onNoBookFound(self):
QtGui.QMessageBox.critical(self,
translate(u'BiblesPlugin.MediaItem', u'No Book Found'),
translate(u'BiblesPlugin.MediaItem',
u'No matching book could be found in this Bible.'),
translate('BiblesPlugin.MediaItem', 'No Book Found'),
translate('BiblesPlugin.MediaItem',
'No matching book could be found in this Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok
)
@ -556,9 +557,9 @@ class BibleMediaItem(MediaManagerItem):
if not service_item.title:
service_item.title = u'%s %s' % (book, verse_text)
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,
translate(u'BiblesPlugin.MediaItem', u'etc'))
translate('BiblesPlugin.MediaItem', 'etc'))
if len(self.parent.settings_tab.bible_theme) == 0:
service_item.theme = None
else:
@ -612,7 +613,7 @@ class BibleMediaItem(MediaManagerItem):
if self.verses == 0:
self.AdvancedSearchButton.setEnabled(False)
self.AdvancedMessage.setText(
translate(u'BiblesPlugin.MediaItem', u'Bible not fully loaded'))
translate('BiblesPlugin.MediaItem', 'Bible not fully loaded'))
else:
self.AdvancedSearchButton.setEnabled(True)
self.AdvancedMessage.setText(u'')
@ -660,4 +661,3 @@ class BibleMediaItem(MediaManagerItem):
def searchByReference(self, bible, search):
log.debug(u'searchByReference %s, %s', 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')
self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % (
translate(u'BiblesPlugin.Opensong', u'Importing'), \
translate('BiblesPlugin.Opensong', 'Importing'), \
db_book.name, chapter.attrib[u'n'])))
self.commit()
self.session.commit()
except IOError:
log.exception(u'Loading bible from OpenSong file failed')
success = False
@ -103,4 +103,3 @@ class OpenSongBible(BibleDB):
else:
return success

View File

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

View File

@ -22,3 +22,8 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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
from forms import EditCustomForm
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__)
@ -43,9 +46,9 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded')
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.custommanager = CustomManager()
self.custommanager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.custommanager)
self.icon = build_icon(u':/media/media_custom.png')
self.status = PluginStatus.Active
@ -67,14 +70,16 @@ class CustomPlugin(Plugin):
self.remove_toolbox_item()
def about(self):
about_text = translate(u'CustomPlugin',
u'<b>Custom Plugin</b><br>This plugin '
u'allows slides to be displayed on the screen in the same way '
u'songs are. This plugin provides greater freedom over the '
u'songs plugin.<br>')
about_text = translate('CustomPlugin',
'<b>Custom Plugin</b><br>This plugin '
'allows slides to be displayed on the screen in the same way '
'songs are. This plugin provides greater freedom over the '
'songs plugin.<br>')
return about_text
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 False

View File

@ -43,6 +43,7 @@ class Ui_customEditDialog(object):
self.TitleLabel.setObjectName(u'TitleLabel')
self.horizontalLayout.addWidget(self.TitleLabel)
self.TitleEdit = QtGui.QLineEdit(customEditDialog)
self.TitleLabel.setBuddy(self.TitleEdit)
self.TitleEdit.setObjectName(u'TitleEdit')
self.horizontalLayout.addWidget(self.TitleEdit)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
@ -118,6 +119,7 @@ class Ui_customEditDialog(object):
self.ThemeLabel.setObjectName(u'ThemeLabel')
self.horizontalLayout_3.addWidget(self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(customEditDialog)
self.ThemeLabel.setBuddy(self.ThemeComboBox)
self.ThemeComboBox.setObjectName(u'ThemeComboBox')
self.horizontalLayout_3.addWidget(self.ThemeComboBox)
self.gridLayout.addLayout(self.horizontalLayout_3, 3, 0, 1, 1)
@ -127,6 +129,7 @@ class Ui_customEditDialog(object):
self.CreditLabel.setObjectName(u'CreditLabel')
self.horizontalLayout_2.addWidget(self.CreditLabel)
self.CreditEdit = QtGui.QLineEdit(customEditDialog)
self.CreditLabel.setBuddy(self.CreditEdit)
self.CreditEdit.setObjectName(u'CreditEdit')
self.horizontalLayout_2.addWidget(self.CreditEdit)
self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
@ -162,7 +165,7 @@ class Ui_customEditDialog(object):
self.DownButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down 1'))
self.TitleLabel.setText(
translate('CustomPlugin.EditCustomForm', 'Title:'))
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.AddButton.setText(
translate('CustomPlugin.EditCustomForm', 'Add New'))
self.AddButton.setToolTip(
@ -192,7 +195,7 @@ class Ui_customEditDialog(object):
self.SplitButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add slide split'))
self.ThemeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'Theme:'))
translate('CustomPlugin.EditCustomForm', 'The&me:'))
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 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__)
@ -85,9 +85,8 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
def onPreview(self, button):
log.debug(u'onPreview')
if button.text() == \
unicode(translate('CustomPlugin.EditCustomForm', 'Save && Preview')) \
and self.saveCustom():
if button.text() == unicode(translate('CustomPlugin.EditCustomForm',
'Save && Preview')) and self.saveCustom():
Receiver.send_message(u'custom_preview')
def initialise(self):
@ -117,7 +116,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.customSlide = CustomSlide()
self.initialise()
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.CreditEdit.setText(self.customSlide.credits)
songXML = SongXMLParser(self.customSlide.text)
@ -167,8 +166,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
u'utf-8')
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
u'utf-8')
self.custommanager.save_slide(self.customSlide)
return True
return self.custommanager.save_object(self.customSlide)
def onUpButtonPressed(self):
selectedRow = self.VerseListView.currentRow()

View File

@ -23,6 +23,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from manager import CustomManager
from mediaitem import CustomMediaItem
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):
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.setObjectName(u'CustomLayout')
self.CustomModeGroupBox = QtGui.QGroupBox(self)
@ -55,10 +55,10 @@ class CustomTab(SettingsTab):
self.onDisplayFooterCheckBoxChanged)
def retranslateUi(self):
self.CustomModeGroupBox.setTitle(translate(u'CustomPlugin.CustomTab',
u'Custom Display'))
self.CustomModeGroupBox.setTitle(translate('CustomPlugin.CustomTab',
'Custom Display'))
self.DisplayFooterCheckBox.setText(
translate(u'CustomPlugin.CustomTab', u'Display Footer'))
translate('CustomPlugin.CustomTab', 'Display Footer'))
def onDisplayFooterCheckBoxChanged(self, check_state):
self.displayFooter = False

View File

@ -22,18 +22,40 @@
# 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 database and schema that is the backend for
the Custom plugin
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.plugins.custom.lib.meta import metadata
from openlp.plugins.custom.lib.tables import *
from openlp.plugins.custom.lib.classes import *
from openlp.core.lib.db import BaseModel, init_db
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)
metadata.create_all(checkfirst=True)
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 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__)
@ -66,13 +67,14 @@ class CustomMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def initPluginNameVisible(self):
self.PluginNameVisible = translate(u'CustomPlugin.MediaItem', u'Custom')
self.PluginNameVisible = translate('CustomPlugin.MediaItem', 'Custom')
def requiredIcons(self):
MediaManagerItem.requiredIcons(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
#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.
@ -84,10 +86,10 @@ class CustomMediaItem(MediaManagerItem):
def loadCustomListView(self, list):
self.ListView.clear()
for CustomSlide in list:
custom_name = QtGui.QListWidgetItem(CustomSlide.title)
for customSlide in list:
custom_name = QtGui.QListWidgetItem(customSlide.title)
custom_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id))
QtCore.Qt.UserRole, QtCore.QVariant(customSlide.id))
self.ListView.addItem(custom_name)
def onNewClick(self):
@ -106,7 +108,7 @@ class CustomMediaItem(MediaManagerItem):
type of display is required.
"""
fields = customid.split(u':')
valid = self.parent.custommanager.get_custom(fields[1])
valid = self.parent.custommanager.get_object(CustomSlide, fields[1])
if valid:
self.remoteCustom = fields[1]
self.remoteTriggered = fields[0]
@ -118,8 +120,9 @@ class CustomMediaItem(MediaManagerItem):
"""
Edit a custom item
"""
if self.checkItemSelected(translate(u'CustomPlugin.MediaItem',
u'You must select an item to edit.')):
if check_item_selected(self.ListView,
translate('CustomPlugin.MediaItem',
'You must select an item to edit.')):
item = self.ListView.currentItem()
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
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
"""
if self.checkItemSelected(translate(u'CustomPlugin.MediaItem',
u'You must select an item to delete.')):
item = self.ListView.currentItem()
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.custommanager.delete_custom(item_id)
row = self.ListView.row(item)
if check_item_selected(self.ListView,
translate('CustomPlugin.MediaItem',
'You must select an item to delete.')):
row_list = [item.row() for item in self.ListView.selectedIndexes()]
row_list.sort(reverse=True)
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)
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.AllowsPreview)
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
credit = customSlide.credits
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 #
# 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')
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.icon = build_icon(u':/media/media_image.png')
self.status = PluginStatus.Active

View File

@ -29,7 +29,8 @@ import os
from PyQt4 import QtCore, QtGui
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
log = logging.getLogger(__name__)
@ -116,11 +117,12 @@ class ImageMediaItem(MediaManagerItem):
"""
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.')):
items = self.ListView.selectedIndexes()
for item in items:
text = self.ListView.item(item.row())
row_list = [item.row() for item in self.ListView.selectedIndexes()]
row_list.sort(reverse=True)
for row in row_list:
text = self.ListView.item(row)
if text:
try:
os.remove(os.path.join(self.servicePath,
@ -128,7 +130,7 @@ class ImageMediaItem(MediaManagerItem):
except OSError:
#if not present do not worry
pass
self.ListView.takeItem(item.row())
self.ListView.takeItem(row)
SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList())

View File

@ -22,3 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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 openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate
ItemCapabilities, SettingsManager, translate, check_item_selected
log = logging.getLogger(__name__)
@ -141,10 +141,11 @@ class MediaMediaItem(MediaManagerItem):
"""
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.')):
item = self.ListView.currentItem()
row = self.ListView.row(item)
row_list = [item.row() for item in self.ListView.selectedIndexes()]
row_list.sort(reverse=True)
for row in row_list:
self.ListView.takeItem(row)
SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList())

View File

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

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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':
from win32com.client import Dispatch
import pywintypes
else:
try:
import uno
from com.sun.star.beans import PropertyValue
uno_available = True
except ImportError:
uno_available = False
from PyQt4 import QtCore
@ -78,9 +83,7 @@ class ImpressController(PresentationController):
if os.name == u'nt':
return self.get_com_servicemanager() is not None
else:
# If not windows, and we've got this far then probably
# installed else the import uno would likely have failed
return True
return uno_available
def start_process(self):
"""
@ -132,18 +135,13 @@ class ImpressController(PresentationController):
def get_com_desktop(self):
log.debug(u'get COM Desktop OpenOffice')
try:
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
return desktop
except:
log.exception(u'Failed to get COM desktop')
return None
return self.manager.createInstance(u'com.sun.star.frame.Desktop')
def get_com_servicemanager(self):
log.debug(u'get_com_servicemanager openoffice')
try:
return Dispatch(u'com.sun.star.ServiceManager')
except:
except pywintypes.com_error:
log.exception(u'Failed to get COM service manager')
return None
@ -327,11 +325,17 @@ class ImpressDocument(PresentationDocument):
Returns true if screen is blank
"""
log.debug(u'is blank OpenOffice')
if self.control:
return self.control.isPaused()
else:
return False
def stop_presentation(self):
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):
log.debug(u'start presentation OpenOffice')

View File

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

View File

@ -41,80 +41,80 @@ class Controller(object):
log.info(u'Controller loaded')
def __init__(self, live):
self.isLive = live
self.is_live = live
self.doc = None
log.info(u'%s controller loaded' % live)
def addHandler(self, controller, file, isBlank):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
def add_handler(self, controller, file, is_blank):
log.debug(u'Live = %s, add_handler %s' % (self.is_live, file))
self.controller = controller
if self.doc is not None:
self.shutdown()
self.doc = self.controller.add_doc(file)
self.doc.load_presentation()
if self.isLive:
if self.is_live:
self.doc.start_presentation()
if isBlank:
if is_blank:
self.blank()
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.doc.slidenumber = 0
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():
return
if not self.doc.is_loaded():
self.doc.load_presentation()
if self.isLive:
if self.is_live:
self.doc.start_presentation()
if self.doc.slidenumber > 1:
self.doc.goto_slide(self.doc.slidenumber)
def slide(self, slide, live):
log.debug(u'Live = %s, slide' % live)
if not live:
def slide(self, slide):
log.debug(u'Live = %s, slide' % self.is_live)
if not self.is_live:
return
if self.doc.is_blank():
self.doc.slidenumber = int(slide) + 1
return
self.activate()
self.doc.goto_slide(int(slide) + 1)
self.doc.poll_slidenumber(live)
self.doc.poll_slidenumber(self.is_live)
def first(self):
"""
Based on the handler passed at startup triggers the first slide
"""
log.debug(u'Live = %s, first' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, first' % self.is_live)
if not self.is_live:
return
if self.doc.is_blank():
self.doc.slidenumber = 1
return
self.activate()
self.doc.start_presentation()
self.doc.poll_slidenumber(self.isLive)
self.doc.poll_slidenumber(self.is_live)
def last(self):
"""
Based on the handler passed at startup triggers the first slide
"""
log.debug(u'Live = %s, last' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, last' % self.is_live)
if not self.is_live:
return
if self.doc.is_blank():
self.doc.slidenumber = self.doc.get_slide_count()
return
self.activate()
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):
"""
Based on the handler passed at startup triggers the next slide event
"""
log.debug(u'Live = %s, next' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, next' % self.is_live)
if not self.is_live:
return
if self.doc.is_blank():
if self.doc.slidenumber < self.doc.get_slide_count():
@ -122,14 +122,14 @@ class Controller(object):
return
self.activate()
self.doc.next_step()
self.doc.poll_slidenumber(self.isLive)
self.doc.poll_slidenumber(self.is_live)
def previous(self):
"""
Based on the handler passed at startup triggers the previous slide event
"""
log.debug(u'Live = %s, previous' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, previous' % self.is_live)
if not self.is_live:
return
if self.doc.is_blank():
if self.doc.slidenumber > 1:
@ -137,14 +137,14 @@ class Controller(object):
return
self.activate()
self.doc.previous_step()
self.doc.poll_slidenumber(self.isLive)
self.doc.poll_slidenumber(self.is_live)
def shutdown(self):
"""
Based on the handler passed at startup triggers slide show to shut down
"""
log.debug(u'Live = %s, shutdown' % self.isLive)
if self.isLive:
log.debug(u'Live = %s, shutdown' % self.is_live)
if self.is_live:
Receiver.send_message(u'maindisplay_show')
self.doc.close_presentation()
self.doc = None
@ -152,8 +152,8 @@ class Controller(object):
#self.timer.stop()
def blank(self):
log.debug(u'Live = %s, blank' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, blank' % self.is_live)
if not self.is_live:
return
if not self.doc.is_loaded():
return
@ -162,8 +162,8 @@ class Controller(object):
self.doc.blank_screen()
def stop(self):
log.debug(u'Live = %s, stop' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, stop' % self.is_live)
if not self.is_live:
return
if not self.doc.is_loaded():
return
@ -172,8 +172,8 @@ class Controller(object):
self.doc.stop_presentation()
def unblank(self):
log.debug(u'Live = %s, unblank' % self.isLive)
if not self.isLive:
log.debug(u'Live = %s, unblank' % self.is_live)
if not self.is_live:
return
self.activate()
if self.doc.slidenumber and \
@ -183,7 +183,7 @@ class Controller(object):
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
def poll(self):
self.doc.poll_slidenumber(self.isLive)
self.doc.poll_slidenumber(self.is_live)
class MessageListener(object):
"""
@ -195,8 +195,8 @@ class MessageListener(object):
def __init__(self, mediaitem):
self.controllers = mediaitem.controllers
self.mediaitem = mediaitem
self.previewHandler = Controller(False)
self.liveHandler = Controller(True)
self.preview_handler = Controller(False)
self.live_handler = Controller(True)
# messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup)
@ -228,9 +228,10 @@ class MessageListener(object):
Start of new presentation
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)
isBlank = message[2]
is_blank = message[2]
file = os.path.join(item.get_frame_path(),
item.get_frame_title())
self.handler = item.title
@ -238,75 +239,70 @@ class MessageListener(object):
self.handler = self.mediaitem.findControllerByType(file)
if not self.handler:
return
if isLive:
controller = self.liveHandler
if is_live:
controller = self.live_handler
else:
controller = self.previewHandler
controller.addHandler(self.controllers[self.handler], file, isBlank)
def decode_message(self, message):
if len(message) == 3:
return message[1], message[0], message[2]
else:
return message[1], message[0]
controller = self.preview_handler
controller.add_handler(self.controllers[self.handler], file, is_blank)
def slide(self, message):
isLive, item, slide = self.decode_message(message)
if isLive:
self.liveHandler.slide(slide, isLive)
is_live = message[1]
slide = message[2]
if is_live:
self.live_handler.slide(slide)
else:
self.previewHandler.slide(slide, isLive)
self.preview_handler.slide(slide)
def first(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.first()
is_live = message[1]
if is_live:
self.live_handler.first()
else:
self.previewHandler.first()
self.preview_handler.first()
def last(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.last()
is_live = message[1]
if is_live:
self.live_handler.last()
else:
self.previewHandler.last()
self.preview_handler.last()
def next(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.next()
is_live = message[1]
if is_live:
self.live_handler.next()
else:
self.previewHandler.next()
self.preview_handler.next()
def previous(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.previous()
is_live = message[1]
if is_live:
self.live_handler.previous()
else:
self.previewHandler.previous()
self.preview_handler.previous()
def shutdown(self, message):
isLive = self.decode_message(message)[0]
if isLive:
is_live = message[1]
if is_live:
Receiver.send_message(u'maindisplay_show')
self.liveHandler.shutdown()
self.live_handler.shutdown()
else:
self.previewHandler.shutdown()
self.preview_handler.shutdown()
def hide(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.stop()
is_live = message[1]
if is_live:
self.live_handler.stop()
def blank(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.blank()
is_live = message[1]
if is_live:
self.live_handler.blank()
def unblank(self, message):
isLive = self.decode_message(message)[0]
if isLive:
self.liveHandler.unblank()
is_live = message[1]
if is_live:
self.live_handler.unblank()
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
import _winreg
import win32ui
import pywintypes
from presentationcontroller import PresentationController, PresentationDocument
@ -65,7 +66,7 @@ class PowerpointController(PresentationController):
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
u'PowerPoint.Application').Close()
return True
except:
except WindowsError:
pass
return False
@ -91,7 +92,7 @@ class PowerpointController(PresentationController):
return
try:
self.process.Quit()
except:
except pywintypes.com_error:
pass
self.process = None
@ -121,11 +122,8 @@ class PowerpointDocument(PresentationDocument):
log.debug(u'LoadPresentation')
if not self.controller.process.Visible:
self.controller.start_process()
#try:
self.controller.process.Presentations.Open(self.filepath, False, False,
True)
#except:
# return
self.presentation = self.controller.process.Presentations(
self.controller.process.Presentations.Count)
self.create_thumbnails()
@ -154,7 +152,7 @@ class PowerpointDocument(PresentationDocument):
if self.presentation:
try:
self.presentation.Close()
except:
except pywintypes.com_error:
pass
self.presentation = None
self.controller.remove_doc(self)
@ -170,7 +168,7 @@ class PowerpointDocument(PresentationDocument):
return False
if self.controller.process.Presentations.Count == 0:
return False
except:
except (AttributeError, pywintypes.com_error):
return False
return True
@ -186,7 +184,7 @@ class PowerpointDocument(PresentationDocument):
return False
if self.presentation.SlideShowWindow.View is None:
return False
except:
except (AttributeError, pywintypes.com_error):
return False
return True
@ -208,7 +206,10 @@ class PowerpointDocument(PresentationDocument):
"""
Returns true if screen is blank
"""
if self.is_active():
return self.presentation.SlideShowWindow.View.State == 3
else:
return False
def stop_presentation(self):
"""
@ -224,11 +225,11 @@ class PowerpointDocument(PresentationDocument):
#SlideShowWindow measures its size/position by points, not pixels
try:
dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88)
except:
except win32ui.error:
try:
dpi = \
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
except:
except win32ui.error:
dpi = 96
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.GotoSlide(1)

View File

@ -58,10 +58,7 @@ class PptviewController(PresentationController):
log.debug(u'check_available')
if os.name != u'nt':
return False
try:
return self.check_installed()
except:
return False
if os.name == u'nt':
def check_installed(self):
@ -72,7 +69,7 @@ class PptviewController(PresentationController):
try:
self.start_process()
return self.process.CheckInstalled()
except:
except WindowsError:
return False
def start_process(self):
@ -84,6 +81,7 @@ class PptviewController(PresentationController):
log.debug(u'start PPTView')
self.process = cdll.LoadLibrary(
r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
#self.process.SetDebug(1)
def kill(self):
"""
@ -106,6 +104,7 @@ class PptviewDocument(PresentationDocument):
self.presentation = None
self.pptid = None
self.blanked = False
self.hidden = False
def load_presentation(self):
"""
@ -123,13 +122,11 @@ class PptviewDocument(PresentationDocument):
rect = rendermanager.screens.current[u'size']
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
filepath = str(self.filepath.replace(u'/', u'\\'))
try:
self.pptid = self.controller.process.OpenPPT(filepath, None, rect,
str(os.path.join(self.thumbnailpath,
self.controller.thumbnailprefix)))
if self.pptid:
self.stop_presentation()
except:
log.exception(u'Failed to load presentation')
def close_presentation(self):
"""
@ -156,7 +153,7 @@ class PptviewDocument(PresentationDocument):
"""
Returns true if a presentation is currently active
"""
return self.is_loaded()
return self.is_loaded() and not self.hidden
def blank_screen(self):
"""
@ -183,12 +180,17 @@ class PptviewDocument(PresentationDocument):
"""
Stops the current presentation and hides the output
"""
self.hidden = True
self.controller.process.Stop(self.pptid)
def start_presentation(self):
"""
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)
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 project can be built with the free Microsoft Visual C++ 2008 Express Edition.
USAGE
-----
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.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, "\"");
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);
SavePPTInfo(id);
if(pptviewobj[id].state==PPT_CLOSING){
if(pptviewobj[id].state==PPT_CLOSING||pptviewobj[id].slideCount<=0){
ClosePPT(id);
id=-1;
}

View File

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

View File

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

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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):
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.setObjectName(u'RemoteLayout')
self.RemoteModeGroupBox = QtGui.QGroupBox(self)
@ -54,7 +54,7 @@ class RemoteTab(SettingsTab):
def retranslateUi(self):
self.RemoteModeGroupBox.setTitle(
translate(u'RemotePlugin.RemoteTab', u'Remotes Receiver Port'))
translate('RemotePlugin.RemoteTab', 'Remotes Receiver Port'))
def load(self):
self.RemotePortSpinBox.setValue(

View File

@ -25,7 +25,7 @@
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
log = logging.getLogger(__name__)
@ -37,7 +37,8 @@ class RemotesPlugin(Plugin):
"""
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.server = None
@ -69,9 +70,9 @@ class RemotesPlugin(Plugin):
"""
Information about this plugin
"""
about_text = translate(u'RemotePlugin',
u'<b>Remote Plugin</b><br>This plugin '
u'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>'
u'The Primary use for this would be to send alerts from a creche')
about_text = translate('RemotePlugin',
'<b>Remote Plugin</b><br>This plugin '
'provides the ability to send messages to a running version of '
'openlp on a different computer via a web browser or other app<br>'
'The Primary use for this would be to send alerts from a creche')
return about_text

View File

@ -22,3 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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 openlp.core.lib import translate
class Ui_AuthorsDialog(object):
@ -75,10 +76,10 @@ class Ui_AuthorsDialog(object):
def retranslateUi(self, AuthorsDialog):
AuthorsDialog.setWindowTitle(
translate(u'SongsPlugin.AuthorsForm', u'Author Maintenance'))
translate('SongsPlugin.AuthorsForm', 'Author Maintenance'))
self.DisplayLabel.setText(
translate(u'SongsPlugin.AuthorsForm', u'Display name:'))
translate('SongsPlugin.AuthorsForm', 'Display name:'))
self.FirstNameLabel.setText(
translate(u'SongsPlugin.AuthorsForm', u'First name:'))
translate('SongsPlugin.AuthorsForm', 'First name:'))
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.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
"""
Class to control the Maintenance of Authors Dialog
@ -80,27 +79,27 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
def accept(self):
if not self.FirstNameEdit.text():
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'),
translate(u'SongsPlugin.AuthorsForm',
u'You need to type in the first name of the author.'),
self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate('SongsPlugin.AuthorsForm',
'You need to type in the first name of the author.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.FirstNameEdit.setFocus()
return False
elif not self.LastNameEdit.text():
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'),
translate(u'SongsPlugin.AuthorsForm',
u'You need to type in the last name of the author.'),
self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate('SongsPlugin.AuthorsForm',
'You need to type in the last name of the author.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.LastNameEdit.setFocus()
return False
elif not self.DisplayEdit.text():
if QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.AuthorsForm', u'Error'),
translate(u'SongsPlugin.AuthorsForm',
u'You haven\'t set a display name for the '
u'author, would you like me to combine the first and '
u'last names for you?'),
self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate('SongsPlugin.AuthorsForm',
'You haven\'t set a display name for the '
'author, would you like me to combine the first and '
'last names for you?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
) == QtGui.QMessageBox.Yes:

View File

@ -24,9 +24,8 @@
###############################################################################
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):
def setupUi(self, EditSongDialog):
@ -50,6 +49,7 @@ class Ui_EditSongDialog(object):
self.TitleLabel.setObjectName(u'TitleLabel')
self.LyricsTabLayout.addWidget(self.TitleLabel, 0, 0, 1, 1)
self.TitleEditItem = QtGui.QLineEdit(self.LyricsTab)
self.TitleLabel.setBuddy(self.TitleEditItem)
sizePolicy = QtGui.QSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@ -63,6 +63,7 @@ class Ui_EditSongDialog(object):
self.AlternativeTitleLabel.setObjectName(u'AlternativeTitleLabel')
self.LyricsTabLayout.addWidget(self.AlternativeTitleLabel, 1, 0, 1, 1)
self.AlternativeEdit = QtGui.QLineEdit(self.LyricsTab)
self.AlternativeTitleLabel.setBuddy(self.AlternativeEdit)
self.AlternativeEdit.setObjectName(u'AlternativeEdit')
self.LyricsTabLayout.addWidget(self.AlternativeEdit, 1, 1, 1, 2)
self.LyricsLabel = QtGui.QLabel(self.LyricsTab)
@ -71,6 +72,7 @@ class Ui_EditSongDialog(object):
self.LyricsLabel.setObjectName(u'LyricsLabel')
self.LyricsTabLayout.addWidget(self.LyricsLabel, 2, 0, 1, 1)
self.VerseListWidget = QtGui.QTableWidget(self.LyricsTab)
self.LyricsLabel.setBuddy(self.VerseListWidget)
self.VerseListWidget.setColumnCount(1)
self.VerseListWidget.horizontalHeader().setVisible(False)
self.VerseListWidget.setSelectionBehavior(1)
@ -83,6 +85,7 @@ class Ui_EditSongDialog(object):
self.VerseOrderLabel.setObjectName(u'VerseOrderLabel')
self.LyricsTabLayout.addWidget(self.VerseOrderLabel, 4, 0, 1, 1)
self.VerseOrderEdit = QtGui.QLineEdit(self.LyricsTab)
self.VerseOrderLabel.setBuddy(self.VerseOrderEdit)
self.VerseOrderEdit.setObjectName(u'VerseOrderEdit')
self.LyricsTabLayout.addWidget(self.VerseOrderEdit, 4, 1, 1, 2)
self.VerseButtonWidget = QtGui.QWidget(self.LyricsTab)
@ -440,7 +443,7 @@ class Ui_EditSongDialog(object):
self.TitleLabel.setText(
translate('SongsPlugin.EditSongForm', '&Title:'))
self.AlternativeTitleLabel.setText(
translate('SongsPlugin.EditSongForm', 'Alt&ernative Title:'))
translate('SongsPlugin.EditSongForm', 'Alt&ernate Title:'))
self.LyricsLabel.setText(
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.VerseOrderLabel.setText(
@ -478,11 +481,11 @@ class Ui_EditSongDialog(object):
self.ThemeGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Theme'))
self.ThemeAddButton.setText(
translate('SongsPlugin.EditSongForm', 'Add a &Theme'))
translate('SongsPlugin.EditSongForm', 'New &Theme'))
self.CopyrightGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Copyright Information'))
self.CopyrightInsertButton.setText(
translate('SongsPlugin.EditSongForm', u'\xa9'))
translate('SongsPlugin.EditSongForm', '\xa9'))
self.CCLILabel.setText(
translate('SongsPlugin.EditSongForm', 'CCLI Number:'))
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.plugins.songs.forms import EditVerseForm
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
log = logging.getLogger(__name__)
@ -96,7 +96,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.previewButton = QtGui.QPushButton()
self.previewButton.setObjectName(u'previewButton')
self.previewButton.setText(
translate(u'SongsPlugin.EditSongForm', u'Save && Preview'))
translate('SongsPlugin.EditSongForm', 'Save && Preview'))
self.ButtonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.ButtonBox,
@ -118,7 +118,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False)
def loadAuthors(self):
authors = self.songmanager.get_authors()
authors = self.songmanager.get_all_objects(Author, Author.display_name)
self.AuthorsSelectionComboItem.clear()
self.AuthorsSelectionComboItem.addItem(u'')
for author in authors:
@ -128,7 +128,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
row, QtCore.QVariant(author.id))
def loadTopics(self):
topics = self.songmanager.get_topics()
topics = self.songmanager.get_all_objects(Topic, Topic.name)
self.SongTopicCombo.clear()
self.SongTopicCombo.addItem(u'')
for topic in topics:
@ -137,7 +137,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id))
def loadBooks(self):
books = self.songmanager.get_books()
books = self.songmanager.get_all_objects(Book, Book.name)
self.SongbookCombo.clear()
self.SongbookCombo.addItem(u'')
for book in books:
@ -178,11 +178,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.loadAuthors()
self.loadTopics()
self.loadBooks()
self.song = self.songmanager.get_song(id)
self.song = self.songmanager.get_object(Song, id)
self.TitleEditItem.setText(self.song.title)
title = self.song.search_title.split(u'@')
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(
unicode(book_name.name), QtCore.Qt.MatchExactly)
if id == -1:
@ -289,7 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
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)
author_item = QtGui.QListWidgetItem(
unicode(author.display_name))
@ -302,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return
elif item > 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)
author_item = QtGui.QListWidgetItem(unicode(author.display_name))
author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id))
@ -325,7 +326,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.AuthorRemoveButton.setEnabled(False)
item = self.AuthorsListView.currentItem()
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)
row = self.AuthorsListView.row(item)
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.Yes:
topic = Topic.populate(name=text)
self.songmanager.save_topic(topic)
self.songmanager.save_object(topic)
self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole,
@ -353,7 +354,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return
elif item > 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)
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -375,7 +376,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False)
item = self.TopicsListView.currentItem()
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)
row = self.TopicsListView.row(item)
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.Yes:
book = Book.populate(name=text)
self.songmanager.save_book(book)
self.songmanager.save_object(book)
self.song.book = book
self.loadBooks()
else:
return
elif item > 1:
elif item >= 1:
item = int(self.SongbookCombo.currentIndex())
self.song.song_book_id = \
(self.SongbookCombo.itemData(item)).toInt()[0]
@ -516,26 +517,26 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTabWidget.setCurrentIndex(0)
self.TitleEditItem.setFocus()
QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'),
translate(u'SongsPlugin.EditSongForm',
u'You need to enter a song title.'))
translate('SongsPlugin.EditSongForm', 'Error'),
translate('SongsPlugin.EditSongForm',
'You need to type in a song title.'))
return False
if self.VerseListWidget.rowCount() == 0:
self.SongTabWidget.setCurrentIndex(0)
self.VerseListWidget.setFocus()
QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'),
translate('uSongsPlugin.EditSongForm',
u'You need to enter some verses.'))
translate('SongsPlugin.EditSongForm', 'Error'),
translate('SongsPlugin.EditSongForm',
'You need to type in at least one verse.'))
return False
if self.AuthorsListView.count() == 0:
self.SongTabWidget.setCurrentIndex(1)
self.AuthorsListView.setFocus()
answer = QtGui.QMessageBox.warning(self,
translate(u'SongsPlugin.EditSongForm', u'Warning'),
translate('SongsPlugin.EditSongForm', 'Warning'),
translate('SongsPlugin.EditSongForm',
'You have set no author.\n'
'Do you want to add now a author?'),
'You have not added any authors for this song. Do you '
'want to add an author now?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.Yes:
return False
@ -564,7 +565,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for verse in verses:
valid = valid + u', ' + verse
QtGui.QMessageBox.critical(self,
translate(u'SongsPlugin.EditSongForm', u'Error'),
translate('SongsPlugin.EditSongForm', 'Error'),
unicode(translate('SongsPlugin.EditSongForm',
'The verse order is invalid. There is no verse '
'corresponding to %s. Valid entries are %s.')) % \
@ -575,10 +576,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTabWidget.setCurrentIndex(0)
self.VerseOrderEdit.setFocus()
answer = QtGui.QMessageBox.warning(self,
translate(u'SongsPlugin.EditSongForm', u'Warning'),
translate('SongsPlugin.EditSongForm', 'Warning'),
unicode(translate('SongsPlugin.EditSongForm',
'%s is not addressed in the verse order.\n'
'Do you want to save anyhow?')) % \
'You have not used %s anywhere in the verse '
'order. Are you sure you want to save the song '
'like this?')) % \
verse_names[count].replace(u':', u' '),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
@ -588,7 +590,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def onCopyrightInsertButtonTriggered(self):
text = self.CopyrightEditItem.text()
pos = self.CopyrightEditItem.cursorPosition()
text = text[:pos] + u'\xa9' + text[pos:]
text = text[:pos] + '\xa9' + text[pos:]
self.CopyrightEditItem.setText(text)
self.CopyrightEditItem.setFocus()
self.CopyrightEditItem.setCursorPosition(pos + 1)
@ -629,7 +631,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if self._validate_song():
self.processLyrics()
self.processTitle()
self.songmanager.save_song(self.song)
self.songmanager.save_object(self.song)
return True
return False
@ -654,7 +656,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for verse in multiple:
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:
log.exception(u'Problem processing song Lyrics \n%s',
sxml.dump_xml())

View File

@ -87,9 +87,9 @@ class Ui_EditVerseDialog(object):
def retranslateUi(self, EditVerseDialog):
EditVerseDialog.setWindowTitle(
translate(u'SongsPlugin.EditVerseForm', u'Edit Verse'))
translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
self.VerseTypeLabel.setText(
translate(u'SongsPlugin.EditVerseForm', u'Verse Type:'))
translate('SongsPlugin.EditVerseForm', '&Verse type:'))
self.VerseTypeComboBox.setItemText(0,
VerseType.to_string(VerseType.Verse))
self.VerseTypeComboBox.setItemText(1,
@ -105,5 +105,5 @@ class Ui_EditVerseDialog(object):
self.VerseTypeComboBox.setItemText(6,
VerseType.to_string(VerseType.Other))
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 openlp.core.lib import translate
class Ui_SongBookDialog(object):
@ -67,7 +68,7 @@ class Ui_SongBookDialog(object):
def retranslateUi(self, SongBookDialog):
SongBookDialog.setWindowTitle(
translate(u'SongsPlugin.SongBookForm', u'Edit Book'))
self.NameLabel.setText(translate(u'SongsPlugin.SongBookForm', u'Name:'))
translate('SongsPlugin.SongBookForm', 'Edit Book'))
self.NameLabel.setText(translate('SongsPlugin.SongBookForm', '&Name:'))
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.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
"""
Class documentation goes here.
@ -50,9 +49,9 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
def accept(self):
if not self.NameEdit.text():
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongBookForm', u'Error'),
translate(u'SongsPlugin.SongBookForm',
u'You need to type in a book name!'),
self, translate('SongsPlugin.SongBookForm', 'Error'),
translate('SongsPlugin.SongBookForm',
'You need to type in a name for the book.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.NameEdit.setFocus()
return False

View File

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

View File

@ -230,54 +230,54 @@ class Ui_SongImportWizard(object):
def retranslateUi(self, SongImportWizard):
SongImportWizard.setWindowTitle(
translate(u'SongsPlugin.SongImportWizard', u'Song Import Wizard'))
translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
self.TitleLabel.setText(
'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate(u'SongsPlugin.SongImportWizard',
u'Welcome to the Song Import Wizard'))
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('SongsPlugin.ImportWizardForm',
'Welcome to the Song Import Wizard'))
self.InformationLabel.setText(
translate(u'SongsPlugin.SongImportWizard',
u'This wizard will help you to import songs from a variety of '
u'formats. Click the next button below to start the process by '
u'selecting a format to import from.'))
translate('SongsPlugin.ImportWizardForm',
'This wizard will help you to import songs from a variety of '
'formats. Click the next button below to start the process by '
'selecting a format to import from.'))
self.SourcePage.setTitle(
translate(u'SongsPlugin.SongImportWizard', u'Select Import Source'))
translate('SongsPlugin.ImportWizardForm', 'Select Import Source'))
self.SourcePage.setSubTitle(
translate(u'SongsPlugin.SongImportWizard',
u'Select the import format, and where to import from.'))
translate('SongsPlugin.ImportWizardForm',
'Select the import format, and where to import from.'))
self.FormatLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Format:'))
translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.FormatComboBox.setItemText(0,
translate(u'SongsPlugin.SongImportWizard', u'OpenLyrics'))
translate('SongsPlugin.ImportWizardForm', 'OpenLyrics'))
self.FormatComboBox.setItemText(1,
translate(u'SongsPlugin.SongImportWizard', u'OpenSong'))
translate('SongsPlugin.ImportWizardForm', 'OpenSong'))
self.FormatComboBox.setItemText(2,
translate(u'SongsPlugin.SongImportWizard', u'CCLI'))
translate('SongsPlugin.ImportWizardForm', 'CCLI'))
self.FormatComboBox.setItemText(3,
translate(u'SongsPlugin.SongImportWizard', u'CSV'))
translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.OpenLyricsAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...'))
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.OpenLyricsRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)'))
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.OpenSongAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...'))
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.OpenSongRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)'))
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.CCLIAddButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Add Files...'))
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.CCLIRemoveButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Remove File(s)'))
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.CSVFilenameLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Filename:'))
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.CSVBrowseButton.setText(
translate(u'SongsPlugin.SongImportWizard', u'Browse...'))
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.ImportPage.setTitle(
translate(u'SongsPlugin.SongImportWizard', u'Importing'))
translate('SongsPlugin.ImportWizardForm', 'Importing'))
self.ImportPage.setSubTitle(
translate(u'SongsPlugin.SongImportWizard',
u'Please wait while your songs are imported.'))
translate('SongsPlugin.ImportWizardForm',
'Please wait while your songs are imported.'))
self.ImportProgressLabel.setText(
translate(u'SongsPlugin.SongImportWizard', u'Ready.'))
translate('SongsPlugin.ImportWizardForm', 'Ready.'))
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 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.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):
"""
@ -81,17 +79,17 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
else:
return -1
def _deleteItem(self, list_widget, get_func, del_func, reset_func,
dlg_title, del_text, err_text, sel_text):
def _deleteItem(self, item_class, list_widget, reset_func, dlg_title,
del_text, err_text, sel_text):
item_id = self._getCurrentItemId(list_widget)
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 QtGui.QMessageBox.warning(self, dlg_title, del_text,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
) == QtGui.QMessageBox.Yes:
del_func(item.id)
self.songmanager.delete_object(item_class, item.id)
reset_func()
else:
QtGui.QMessageBox.critical(self, dlg_title, err_text)
@ -100,7 +98,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetAuthors(self):
self.AuthorsListWidget.clear()
authors = self.songmanager.get_authors()
authors = self.songmanager.get_all_objects(Author, Author.display_name)
for author in authors:
if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name)
@ -112,7 +110,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetTopics(self):
self.TopicsListWidget.clear()
topics = self.songmanager.get_topics()
topics = self.songmanager.get_all_objects(Topic, Topic.name)
for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -120,7 +118,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetBooks(self):
self.BooksListWidget.clear()
books = self.songmanager.get_books()
books = self.songmanager.get_all_objects(Book, Book.name)
for book in books:
book_name = QtGui.QListWidgetItem(book.name)
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()),
last_name=unicode(self.authorform.LastNameEdit.text()),
display_name=unicode(self.authorform.DisplayEdit.text()))
if self.songmanager.save_author(author):
if self.songmanager.save_object(author):
self.resetAuthors()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your author.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t add your author.'))
def onTopicAddButtonClick(self):
if self.topicform.exec_():
topic = Topic.populate(name=unicode(self.topicform.NameEdit.text()))
if self.songmanager.save_topic(topic):
if self.songmanager.save_object(topic):
self.resetTopics()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your topic.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t add your topic.'))
def onBookAddButtonClick(self):
if self.bookform.exec_():
book = Book.populate(
name=unicode(self.bookform.NameEdit.text()),
publisher=unicode(self.bookform.PublisherEdit.text()))
if self.songmanager.save_book(book):
if self.songmanager.save_object(book):
self.resetBooks()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t add your book.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t add your book.'))
def onAuthorEditButtonClick(self):
author_id = self._getCurrentItemId(self.AuthorsListWidget)
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
if author.first_name is None:
author.first_name = u''
@ -189,92 +187,86 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
author.last_name = unicode(self.authorform.LastNameEdit.text())
author.display_name = unicode(
self.authorform.DisplayEdit.text())
if self.songmanager.save_author(author):
if self.songmanager.save_object(author):
self.resetAuthors()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your author.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t save your author.'))
def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.TopicsListWidget)
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)
if self.topicform.exec_(False):
topic.name = unicode(self.topicform.NameEdit.text())
if self.songmanager.save_topic(topic):
if self.songmanager.save_object(topic):
self.resetTopics()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your topic.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t save your topic.'))
def onBookEditButtonClick(self):
book_id = self._getCurrentItemId(self.BooksListWidget)
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.PublisherEdit.setText(book.publisher)
if self.bookform.exec_(False):
book.name = unicode(self.bookform.NameEdit.text())
book.publisher = unicode(self.bookform.PublisherEdit.text())
if self.songmanager.save_book(book):
if self.songmanager.save_object(book):
self.resetBooks()
else:
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.SongMaintenanceForm',
u'Error'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Couldn\'t save your book.'))
self, translate('SongsPlugin.SongMaintenanceForm',
'Error'),
translate('SongsPlugin.SongMaintenanceForm',
'Couldn\'t save your book.'))
def onAuthorDeleteButtonClick(self):
"""
Delete the author if the author is not attached to any songs
"""
self._deleteItem(
self.AuthorsListWidget, self.songmanager.get_author,
self.songmanager.delete_author, self.resetAuthors,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Author'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected author?'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'This author can\'t be deleted, they are currently '
u'assigned to at least one song.'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'No author selected!'))
self._deleteItem(Author, self.AuthorsListWidget, self.resetAuthors,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected author?'),
translate('SongsPlugin.SongMaintenanceForm',
'This author can\'t be deleted, they are currently '
'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm',
'No author selected!'))
def onTopicDeleteButtonClick(self):
"""
Delete the Book is the Book is not attached to any songs
"""
self._deleteItem(
self.TopicsListWidget, self.songmanager.get_topic,
self.songmanager.delete_topic, self.resetTopics,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Topic'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected topic?'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'This topic can\'t be deleted, it is currently '
u'assigned to at least one song.'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'No topic selected!'))
self._deleteItem(Topic, self.TopicsListWidget, self.resetTopics,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected topic?'),
translate('SongsPlugin.SongMaintenanceForm',
'This topic can\'t be deleted, it is currently '
'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm',
'No topic selected!'))
def onBookDeleteButtonClick(self):
"""
Delete the Book is the Book is not attached to any songs
"""
self._deleteItem(
self.BooksListWidget, self.songmanager.get_book,
self.songmanager.delete_book, self.resetBooks,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Book'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected book?'),
translate(u'SongsPlugin.SongMaintenanceForm',
u'This book can\'t be deleted, it is currently '
u'assigned to at least one song.'),
translate(u'SongsPlugin.SongMaintenanceForm', u'No book selected!'))
self._deleteItem(Book, self.BooksListWidget, self.resetBooks,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected book?'),
translate('SongsPlugin.SongMaintenanceForm',
'This book can\'t be deleted, it is currently '
'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm', u'No book selected!'))

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_TopicsDialog(object):
@ -61,6 +62,6 @@ class Ui_TopicsDialog(object):
def retranslateUi(self, TopicsDialog):
TopicsDialog.setWindowTitle(
translate(u'SongsPlugin.TopicsForm', u'Topic Maintenance'))
translate('SongsPlugin.TopicsForm', 'Topic Maintenance'))
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.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
"""
Class documentation goes here.
@ -49,9 +48,9 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def accept(self):
if not self.NameEdit.text():
QtGui.QMessageBox.critical(
self, translate(u'SongsPlugin.TopicsForm', u'Error'),
translate(u'SongsPlugin.TopicsForm',
u'You need to type in a topic name!'),
self, translate('SongsPlugin.TopicsForm', 'Error'),
translate('SongsPlugin.TopicsForm',
'You need to type in a topic name!'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.NameEdit.setFocus()
return False

View File

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