This commit is contained in:
Tim Bentley 2014-01-01 12:09:00 +00:00
commit 3a75e53fcf
102 changed files with 1001 additions and 738 deletions

View File

@ -43,8 +43,8 @@ from traceback import format_exception
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, UiStrings, check_directory_exists
from openlp.core.lib import ScreenList, Registry
from openlp.core.common import Registry, AppLocation, Settings, UiStrings, check_directory_exists
from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
@ -162,7 +162,8 @@ class OpenLP(QtGui.QApplication):
self.shared_memory = QtCore.QSharedMemory('OpenLP')
if self.shared_memory.attach():
status = QtGui.QMessageBox.critical(None, UiStrings().Error, UiStrings().OpenLPStart,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No))
if status == QtGui.QMessageBox.No:
return True
return False
@ -248,16 +249,16 @@ def main(args=None):
usage = 'Usage: %prog [options] [qt-options]'
parser = OptionParser(usage=usage)
parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true',
help='Disable the error notification form.')
help='Disable the error notification form.')
parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
parser.add_option('-p', '--portable', dest='portable', action='store_true',
help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')
help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')
parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true',
help='Ignore the version file and pull the version directly from Bazaar')
help='Ignore the version file and pull the version directly from Bazaar')
parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
# Parse command line options and deal with them.
# Use args supplied programatically if possible.
# Use args supplied pragmatically if possible.
(options, args) = parser.parse_args(args) if args else parser.parse_args()
qt_args = []
if options.loglevel.lower() in ['d', 'debug']:
@ -326,4 +327,3 @@ def main(args=None):
if not options.no_error_form:
sys.excepthook = application.hook_exception
sys.exit(application.run(qt_args))

View File

@ -30,15 +30,32 @@
The :mod:`common` module contains most of the components and libraries that make
OpenLP work.
"""
import re
import os
import logging
import sys
import traceback
from PyQt4 import QtCore
log = logging.getLogger(__name__)
FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)')
SECOND_CAMEL_REGEX = re.compile('([a-z0-9])([A-Z])')
def trace_error_handler(logger):
"""
Log the calling path of an exception
``logger``
logger to use so traceback is logged to correct class
"""
for tb in traceback.extract_stack():
logger.error('Called by ' + tb[3] + ' at line ' + str(tb[1]) + ' in ' + tb[0])
def check_directory_exists(directory, do_not_log=False):
"""
Check a theme directory exists and if not create it
@ -103,6 +120,17 @@ class SlideLimits(object):
Wrap = 2
Next = 3
def de_hump(name):
"""
Change any Camel Case string to python string
"""
sub_name = FIRST_CAMEL_REGEX.sub(r'\1_\2', name)
return SECOND_CAMEL_REGEX.sub(r'\1_\2', sub_name).lower()
from .openlpmixin import OpenLPMixin
from .registry import Registry
from .registrymixin import RegistryMixin
from .uistrings import UiStrings
from .settings import Settings
from .applocation import AppLocation

View File

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Provide Error Handling and login Services
"""
import logging
import inspect
from openlp.core.common import trace_error_handler
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent']
class OpenLPMixin(object):
"""
Base Calling object for OpenLP classes.
"""
def __init__(self, parent):
try:
super(OpenLPMixin, self).__init__(parent)
except TypeError:
super(OpenLPMixin, self).__init__()
self.logger = logging.getLogger("%s.%s" % (self.__module__, self.__class__.__name__))
if self.logger.getEffectiveLevel() == logging.DEBUG:
for name, m in inspect.getmembers(self, inspect.ismethod):
if name not in DO_NOT_TRACE_EVENTS:
if not name.startswith("_") and not name.startswith("log"):
setattr(self, name, self.logging_wrapper(m, self))
def logging_wrapper(self, func, parent):
"""
Code to added debug wrapper to work on called functions within a decorated class.
"""
def wrapped(*args, **kwargs):
parent.logger.debug("Entering %s" % func.__name__)
try:
return func(*args, **kwargs)
except Exception as e:
if parent.logger.getEffectiveLevel() <= logging.ERROR:
parent.logger.error('Exception in %s : %s' % (func.__name__, e))
raise e
return wrapped
def log_debug(self, message):
"""
Common log debug handler which prints the calling path
"""
self.logger.debug(message)
def log_info(self, message):
"""
Common log info handler which prints the calling path
"""
self.logger.info(message)
def log_error(self, message):
"""
Common log error handler which prints the calling path
"""
trace_error_handler(self.logger)
self.logger.error(message)
def log_exception(self, message):
"""
Common log exception handler which prints the calling path
"""
trace_error_handler(self.logger)
self.logger.exception(message)

View File

@ -32,6 +32,8 @@ Provide Registry Services
import logging
import sys
from openlp.core.common import trace_error_handler
log = logging.getLogger(__name__)
@ -76,8 +78,9 @@ class Registry(object):
if key in self.service_list:
return self.service_list[key]
else:
trace_error_handler(log)
log.error('Service %s not found in list' % key)
raise KeyError('Service %s not found in list' % key)
#raise KeyError('Service %s not found in list' % key)
def register(self, key, reference):
"""
@ -90,6 +93,7 @@ class Registry(object):
The service address to be saved.
"""
if key in self.service_list:
trace_error_handler(log)
log.error('Duplicate service exception %s' % key)
raise KeyError('Duplicate service exception %s' % key)
else:
@ -134,6 +138,7 @@ class Registry(object):
The function to be called when the event happens.
"""
if self.running_under_test is False:
trace_error_handler(log)
log.error('Invalid Method call for key %s' % event)
raise KeyError('Invalid Method call for key %s' % event)
if event in self.functions_list:
@ -161,7 +166,9 @@ class Registry(object):
results.append(result)
except TypeError:
# Who has called me can help in debugging
import inspect
log.debug(inspect.currentframe().f_back.f_locals)
trace_error_handler(log)
log.exception('Exception for function %s', function)
else:
trace_error_handler(log)
log.error("Event %s not called by not registered" % event)
return results

View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Provide Registry Services
"""
from openlp.core.common import Registry, de_hump
class RegistryMixin(object):
"""
This adds registry components to classes to use at run time.
"""
def __init__(self, parent):
"""
Register the class and bootstrap hooks.
"""
try:
super(RegistryMixin, self).__init__(parent)
except TypeError:
super(RegistryMixin, self).__init__()
Registry().register(de_hump(self.__class__.__name__), self)
Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
def bootstrap_initialise(self):
"""
Dummy method to be overridden
"""
pass
def bootstrap_post_set_up(self):
"""
Dummy method to be overridden
"""
pass

View File

@ -329,7 +329,6 @@ def create_separated_list(string_list):
return translate('OpenLP.core.lib', '%s, %s', 'Locale list separator: start') % (string_list[0], merged)
from .registry import Registry
from .filedialog import FileDialog
from .screen import ScreenList
from .listwidgetwithdnd import ListWidgetWithDnD

View File

@ -39,7 +39,8 @@ import queue
from PyQt4 import QtCore
from openlp.core.lib import Registry, ScreenList, resize_image, image_to_byte
from openlp.core.common import Registry
from openlp.core.lib import ScreenList, resize_image, image_to_byte
log = logging.getLogger(__name__)

View File

@ -33,7 +33,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
class ListWidgetWithDnD(QtGui.QListWidget):

View File

@ -35,9 +35,9 @@ import re
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import FileDialog, OpenLPToolbar, ServiceItem, StringContent, ListWidgetWithDnD, \
ServiceItemContext, Registry
ServiceItemContext
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import create_widget_action, critical_error_message_box

View File

@ -34,8 +34,7 @@ import os
from PyQt4 import QtCore
from openlp.core.common import Settings, UiStrings
from openlp.core.lib import Registry
from openlp.core.common import Registry, Settings, UiStrings
from openlp.core.utils import get_application_version
log = logging.getLogger(__name__)

View File

@ -31,68 +31,56 @@ Provide plugin management
"""
import os
import sys
import logging
import imp
from openlp.core.lib import Plugin, PluginStatus, Registry
from openlp.core.common import AppLocation
log = logging.getLogger(__name__)
from openlp.core.lib import Plugin, PluginStatus
from openlp.core.common import AppLocation, Registry, OpenLPMixin, RegistryMixin
class PluginManager(object):
class PluginManager(RegistryMixin, OpenLPMixin):
"""
This is the Plugin manager, which loads all the plugins,
and executes all the hooks, as and when necessary.
"""
log.info('Plugin manager loaded')
def __init__(self):
def __init__(self, parent=None):
"""
The constructor for the plugin manager. Passes the controllers on to
the plugins for them to interact with via their ServiceItems.
"""
log.info('Plugin manager Initialising')
Registry().register('plugin_manager', self)
Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
super(PluginManager, self).__init__(parent)
self.log_info('Plugin manager Initialising')
self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
log.debug('Base path %s ', self.base_path)
self.log_debug('Base path %s ' % self.base_path)
self.plugins = []
log.info('Plugin manager Initialised')
self.log_info('Plugin manager Initialised')
def bootstrap_initialise(self):
"""
Bootstrap all the plugin manager functions
"""
log.info('bootstrap_initialise')
self.find_plugins()
# hook methods have to happen after find_plugins. Find plugins needs
# the controllers hence the hooks have moved from setupUI() to here
# Find and insert settings tabs
log.info('hook settings')
self.hook_settings_tabs()
# Find and insert media manager items
log.info('hook media')
self.hook_media_manager()
# Call the hook method to pull in import menus.
log.info('hook menus')
self.hook_import_menu()
# Call the hook method to pull in export menus.
self.hook_export_menu()
# Call the hook method to pull in tools menus.
self.hook_tools_menu()
# Call the initialise method to setup plugins.
log.info('initialise plugins')
self.initialise_plugins()
def find_plugins(self):
"""
Scan a directory for objects inheriting from the ``Plugin`` class.
"""
log.info('Finding plugins')
start_depth = len(os.path.abspath(self.base_path).split(os.sep))
present_plugin_dir = os.path.join(self.base_path, 'presentations')
log.debug('finding plugins in %s at depth %d', str(self.base_path), start_depth)
self.log_debug('finding plugins in %s at depth %d' % (self.base_path, start_depth))
for root, dirs, files in os.walk(self.base_path):
if sys.platform == 'darwin' and root.startswith(present_plugin_dir):
# TODO Presentation plugin is not yet working on Mac OS X.
@ -108,7 +96,7 @@ class PluginManager(object):
break
module_name = name[:-3]
# import the modules
log.debug('Importing %s from %s. Depth %d', module_name, root, this_depth)
self.log_debug('Importing %s from %s. Depth %d' % (module_name, root, this_depth))
try:
# Use the "imp" library to try to get around a problem with the PyUNO library which
# monkey-patches the __import__ function to do some magic. This causes issues with our tests.
@ -117,20 +105,21 @@ class PluginManager(object):
# Then load the module (do the actual import) using the details from find_module()
imp.load_module(module_name, fp, path_name, description)
except ImportError as e:
log.exception('Failed to import module %s on path %s: %s', module_name, path, e.args[0])
self.log_exception('Failed to import module %s on path %s: %s'
% (module_name, path, e.args[0]))
plugin_classes = Plugin.__subclasses__()
plugin_objects = []
for p in plugin_classes:
try:
plugin = p()
log.debug('Loaded plugin %s', str(p))
self.log_debug('Loaded plugin %s' % str(p))
plugin_objects.append(plugin)
except TypeError:
log.exception('Failed to load plugin %s', str(p))
self.log_exception('Failed to load plugin %s' % str(p))
plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight)
for plugin in plugins_list:
if plugin.check_pre_conditions():
log.debug('Plugin %s active', str(plugin.name))
self.log_debug('Plugin %s active' % str(plugin.name))
plugin.set_status()
else:
plugin.status = PluginStatus.Disabled
@ -199,24 +188,21 @@ class PluginManager(object):
Loop through all the plugins and give them an opportunity to
initialise themselves.
"""
log.info('Initialise Plugins - Started')
for plugin in self.plugins:
log.info('initialising plugins %s in a %s state' % (plugin.name, plugin.is_active()))
self.log_info('initialising plugins %s in a %s state' % (plugin.name, plugin.is_active()))
if plugin.is_active():
plugin.initialise()
log.info('Initialisation Complete for %s ' % plugin.name)
log.info('Initialise Plugins - Finished')
self.log_info('Initialisation Complete for %s ' % plugin.name)
def finalise_plugins(self):
"""
Loop through all the plugins and give them an opportunity to
clean themselves up
"""
log.info('finalising plugins')
for plugin in self.plugins:
if plugin.is_active():
plugin.finalise()
log.info('Finalisation Complete for %s ' % plugin.name)
self.log_info('Finalisation Complete for %s ' % plugin.name)
def get_plugin_by_name(self, name):
"""
@ -231,7 +217,6 @@ class PluginManager(object):
"""
Loop through all the plugins and give them an opportunity to handle a new service
"""
log.info('plugins - new service created')
for plugin in self.plugins:
if plugin.is_active():
plugin.new_service_created()
@ -255,4 +240,3 @@ class PluginManager(object):
return self._main_window
main_window = property(_get_main_window)

View File

@ -31,9 +31,9 @@ import logging
from PyQt4 import QtGui, QtCore, QtWebKit
from openlp.core.common import Settings
from openlp.core.lib import FormattingTags, ImageSource, ItemCapabilities, Registry, ScreenList, \
ServiceItem, expand_tags, build_lyrics_format_css, build_lyrics_outline_css
from openlp.core.common import Registry, Settings
from openlp.core.lib import FormattingTags, ImageSource, ItemCapabilities, ScreenList, ServiceItem, expand_tags, \
build_lyrics_format_css, build_lyrics_outline_css
from openlp.core.common import ThemeLevel
from openlp.core.ui import MainDisplay

View File

@ -36,8 +36,7 @@ import copy
from PyQt4 import QtCore
from openlp.core.common import Settings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, Settings, translate
log = logging.getLogger(__name__)

View File

@ -39,8 +39,8 @@ import uuid
from PyQt4 import QtGui
from openlp.core.common import Settings, translate
from openlp.core.lib import ImageSource, Registry, build_icon, clean_tags, expand_tags
from openlp.core.common import Registry, Settings, translate
from openlp.core.lib import ImageSource, build_icon, clean_tags, expand_tags
log = logging.getLogger(__name__)

View File

@ -35,7 +35,7 @@ own tab to the settings dialog.
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
class SettingsTab(QtGui.QWidget):

View File

@ -133,7 +133,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
"""
self.dictionary = enchant.Dict(action.text())
self.highlighter.spelling_dictionary = self.dictionary
self.highlighter.highlight_block(self.toPlainText())
self.highlighter.highlightBlock(self.toPlainText())
self.highlighter.rehighlight()
def correct_word(self, word):
@ -180,9 +180,11 @@ class Highlighter(QtGui.QSyntaxHighlighter):
super(Highlighter, self).__init__(*args)
self.spelling_dictionary = None
def highlight_block(self, text):
def highlightBlock(self, text):
"""
Highlight misspelt words in a block of text.
Note, this is a Qt hook.
"""
if not self.spelling_dictionary:
return

View File

@ -36,7 +36,7 @@ import json
from xml.dom.minidom import Document
from lxml import etree, objectify
from openlp.core.common import AppLocation
from openlp.core.common import AppLocation, de_hump
from openlp.core.lib import str_to_bool, ScreenList, get_text_file_string
@ -157,9 +157,6 @@ class ThemeXML(object):
"""
A class to encapsulate the Theme XML.
"""
FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)')
SECOND_CAMEL_REGEX = re.compile('([a-z0-9])([A-Z])')
def __init__(self):
"""
Initialise the theme object.
@ -532,7 +529,7 @@ class ThemeXML(object):
reject, master, element, value = self._translate_tags(master, element, value)
if reject:
return
field = self._de_hump(element)
field = de_hump(element)
tag = master + '_' + field
if field in BOOLEAN_LIST:
setattr(self, tag, str_to_bool(value))
@ -557,13 +554,6 @@ class ThemeXML(object):
theme_strings.append('%30s: %s' % (key, getattr(self, key)))
return '\n'.join(theme_strings)
def _de_hump(self, name):
"""
Change Camel Case string to python string
"""
sub_name = ThemeXML.FIRST_CAMEL_REGEX.sub(r'\1_\2', name)
return ThemeXML.SECOND_CAMEL_REGEX.sub(r'\1_\2', sub_name).lower()
def _build_xml_from_attrs(self):
"""
Build the XML from the varables in the object

View File

@ -33,7 +33,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
class TreeWidgetWithDnD(QtGui.QTreeWidget):

View File

@ -33,8 +33,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry, build_icon
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib import build_icon
from openlp.core.utils.actions import ActionList

View File

@ -86,7 +86,7 @@ from .starttimeform import StartTimeForm
from .maindisplay import MainDisplay, Display
from .servicenoteform import ServiceNoteForm
from .serviceitemeditform import ServiceItemEditForm
from .slidecontroller import SlideController, DisplayController
from .slidecontroller import SlideController, DisplayController, PreviewController, LiveController
from .splashscreen import SplashScreen
from .generaltab import GeneralTab
from .themestab import ThemesTab

View File

@ -38,7 +38,7 @@ import bs4
import sqlalchemy
from lxml import etree
from openlp.core.lib import Registry
from openlp.core.common import Registry
from PyQt4 import Qt, QtCore, QtGui, QtWebKit

View File

@ -34,8 +34,7 @@ from PyQt4 import QtGui
from .filerenamedialog import Ui_FileRenameDialog
from openlp.core.common import translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, translate
class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):

View File

@ -41,8 +41,8 @@ from configparser import ConfigParser
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, check_directory_exists, translate
from openlp.core.lib import PluginStatus, Registry, build_icon
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, translate
from openlp.core.lib import PluginStatus, build_icon
from openlp.core.utils import get_web_page
from .firsttimewizard import Ui_FirstTimeWizard, FirstTimePage

View File

@ -33,8 +33,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, SettingsTab, ScreenList
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import SettingsTab, ScreenList
log = logging.getLogger(__name__)

View File

@ -33,7 +33,8 @@ It is based on a QTableWidget but represents its contents in list form.
from PyQt4 import QtCore, QtGui
from openlp.core.lib import ImageSource, Registry, ServiceItem
from openlp.core.common import Registry
from openlp.core.lib import ImageSource, ServiceItem
class ListPreviewWidget(QtGui.QTableWidget):

View File

@ -44,8 +44,8 @@ import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
from PyQt4.phonon import Phonon
from openlp.core.common import Settings, translate
from openlp.core.lib import ServiceItem, ImageSource, Registry, build_html, expand_tags, image_to_byte
from openlp.core.common import Registry, Settings, translate
from openlp.core.lib import ServiceItem, ImageSource, build_html, expand_tags, image_to_byte
from openlp.core.lib.theme import BackgroundType
from openlp.core.lib import ScreenList

View File

@ -41,13 +41,13 @@ from datetime import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, ImageManager, PluginStatus, Registry, \
ScreenList, build_icon
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, translate
from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, ImageManager, PluginStatus, ScreenList, \
build_icon
from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, SlideController, PluginForm, \
MediaDockManager, ShortcutListForm, FormattingTagForm
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, LiveController, PluginForm, \
MediaDockManager, ShortcutListForm, FormattingTagForm, PreviewController
from openlp.core.common import AppLocation, Settings, check_directory_exists, translate
from openlp.core.ui.media import MediaController
from openlp.core.utils import LanguageManager, add_actions, get_application_version
from openlp.core.utils.actions import ActionList, CategoryOrder
@ -96,23 +96,21 @@ class Ui_MainWindow(object):
# Set up the main container, which contains all the other form widgets.
self.main_content = QtGui.QWidget(main_window)
self.main_content.setObjectName('main_content')
self.main_contentLayout = QtGui.QHBoxLayout(self.main_content)
self.main_contentLayout.setSpacing(0)
self.main_contentLayout.setMargin(0)
self.main_contentLayout.setObjectName('main_contentLayout')
self.main_content_layout = QtGui.QHBoxLayout(self.main_content)
self.main_content_layout.setSpacing(0)
self.main_content_layout.setMargin(0)
self.main_content_layout.setObjectName('main_content_layout')
main_window.setCentralWidget(self.main_content)
self.control_splitter = QtGui.QSplitter(self.main_content)
self.control_splitter.setOrientation(QtCore.Qt.Horizontal)
self.control_splitter.setObjectName('control_splitter')
self.main_contentLayout.addWidget(self.control_splitter)
self.main_content_layout.addWidget(self.control_splitter)
# Create slide controllers
self.preview_controller = SlideController(self)
self.live_controller = SlideController(self, True)
self.preview_controller = PreviewController(self)
self.live_controller = LiveController(self)
preview_visible = Settings().value('user interface/preview panel')
self.preview_controller.panel.setVisible(preview_visible)
live_visible = Settings().value('user interface/live panel')
panel_locked = Settings().value('user interface/lock panel')
self.live_controller.panel.setVisible(live_visible)
# Create menu
self.menu_bar = QtGui.QMenuBar(main_window)
self.menu_bar.setObjectName('menu_bar')
@ -127,8 +125,8 @@ class Ui_MainWindow(object):
# View Menu
self.view_menu = QtGui.QMenu(self.menu_bar)
self.view_menu.setObjectName('viewMenu')
self.view_modeMenu = QtGui.QMenu(self.view_menu)
self.view_modeMenu.setObjectName('viewModeMenu')
self.view_mode_menu = QtGui.QMenu(self.view_menu)
self.view_mode_menu.setObjectName('viewModeMenu')
# Tools Menu
self.tools_menu = QtGui.QMenu(self.menu_bar)
self.tools_menu.setObjectName('tools_menu')
@ -155,7 +153,7 @@ class Ui_MainWindow(object):
self.status_bar.addPermanentWidget(self.default_theme_label)
# Create the MediaManager
self.media_manager_dock = OpenLPDockWidget(main_window, 'media_manager_dock',
':/system/system_mediamanager.png')
':/system/system_mediamanager.png')
self.media_manager_dock.setStyleSheet(MEDIA_MANAGER_STYLE)
# Create the media toolbox
self.media_tool_box = QtGui.QToolBox(self.media_manager_dock)
@ -164,13 +162,13 @@ class Ui_MainWindow(object):
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.media_manager_dock)
# Create the service manager
self.service_manager_dock = OpenLPDockWidget(main_window, 'service_manager_dock',
':/system/system_servicemanager.png')
':/system/system_servicemanager.png')
self.service_manager_contents = ServiceManager(self.service_manager_dock)
self.service_manager_dock.setWidget(self.service_manager_contents)
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.service_manager_dock)
# Create the theme manager
self.theme_manager_dock = OpenLPDockWidget(main_window, 'theme_manager_dock',
':/system/system_thememanager.png')
':/system/system_thememanager.png')
self.theme_manager_contents = ThemeManager(self.theme_manager_dock)
self.theme_manager_contents.setObjectName('theme_manager_contents')
self.theme_manager_dock.setWidget(self.theme_manager_contents)
@ -178,98 +176,86 @@ class Ui_MainWindow(object):
# Create the menu items
action_list = ActionList.get_instance()
action_list.add_category(UiStrings().File, CategoryOrder.standard_menu)
self.file_new_item = create_action(main_window, 'fileNewItem',
icon=':/general/general_new.png',
can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.on_new_service_clicked)
self.file_open_item = create_action(main_window, 'fileOpenItem',
icon=':/general/general_open.png',
can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.on_load_service_clicked)
self.file_save_item = create_action(main_window, 'fileSaveItem',
icon=':/general/general_save.png',
can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.save_file)
self.file_save_as_item = create_action(main_window, 'fileSaveAsItem',
can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.save_file_as)
self.print_service_order_item = create_action(main_window,
'printServiceItem', can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.print_service_order)
self.file_exit_item = create_action(main_window, 'fileExitItem',
icon=':/system/system_exit.png',
can_shortcuts=True,
category=UiStrings().File, triggers=main_window.close)
self.file_new_item = create_action(main_window, 'fileNewItem', icon=':/general/general_new.png',
can_shortcuts=True, category=UiStrings().File,
triggers=self.service_manager_contents.on_new_service_clicked)
self.file_open_item = create_action(main_window, 'fileOpenItem', icon=':/general/general_open.png',
can_shortcuts=True, category=UiStrings().File,
triggers=self.service_manager_contents.on_load_service_clicked)
self.file_save_item = create_action(main_window, 'fileSaveItem', icon=':/general/general_save.png',
can_shortcuts=True, category=UiStrings().File,
triggers=self.service_manager_contents.save_file)
self.file_save_as_item = create_action(main_window, 'fileSaveAsItem', can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.save_file_as)
self.print_service_order_item = create_action(main_window, 'printServiceItem', can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.print_service_order)
self.file_exit_item = create_action(main_window, 'fileExitItem', icon=':/system/system_exit.png',
can_shortcuts=True,
category=UiStrings().File, triggers=main_window.close)
# Give QT Extra Hint that this is the Exit Menu Item
self.file_exit_item.setMenuRole(QtGui.QAction.QuitRole)
action_list.add_category(UiStrings().Import, CategoryOrder.standard_menu)
self.import_theme_item = create_action(
main_window, 'importThemeItem', category=UiStrings().Import, can_shortcuts=True)
self.import_theme_item = create_action(main_window, 'importThemeItem', category=UiStrings().Import,
can_shortcuts=True)
self.import_language_item = create_action(main_window, 'importLanguageItem')
action_list.add_category(UiStrings().Export, CategoryOrder.standard_menu)
self.export_theme_item = create_action(
main_window, 'exportThemeItem', category=UiStrings().Export, can_shortcuts=True)
self.export_theme_item = create_action(main_window, 'exportThemeItem', category=UiStrings().Export,
can_shortcuts=True)
self.export_language_item = create_action(main_window, 'exportLanguageItem')
action_list.add_category(UiStrings().View, CategoryOrder.standard_menu)
self.view_media_manager_item = create_action(main_window,
'viewMediaManagerItem',
icon=':/system/system_mediamanager.png',
checked=self.media_manager_dock.isVisible(),
can_shortcuts=True,
category=UiStrings().View, triggers=self.toggle_media_manager)
self.view_theme_manager_item = create_action(main_window,
'viewThemeManagerItem', can_shortcuts=True,
icon=':/system/system_thememanager.png',
checked=self.theme_manager_dock.isVisible(),
category=UiStrings().View, triggers=self.toggle_theme_manager)
self.view_service_manager_item = create_action(main_window,
'viewServiceManagerItem', can_shortcuts=True,
icon=':/system/system_servicemanager.png',
checked=self.service_manager_dock.isVisible(),
category=UiStrings().View, triggers=self.toggle_service_manager)
self.view_preview_panel = create_action(main_window, 'viewPreviewPanel',
can_shortcuts=True, checked=preview_visible,
category=UiStrings().View, triggers=self.set_preview_panel_visibility)
self.view_live_panel = create_action(main_window, 'viewLivePanel',
can_shortcuts=True, checked=live_visible,
category=UiStrings().View, triggers=self.set_live_panel_visibility)
self.lock_panel = create_action(main_window, 'lockPanel',
can_shortcuts=True, checked=panel_locked,
category=UiStrings().View,
triggers=self.set_lock_panel)
self.view_media_manager_item = create_action(main_window, 'viewMediaManagerItem',
icon=':/system/system_mediamanager.png',
checked=self.media_manager_dock.isVisible(),
can_shortcuts=True,
category=UiStrings().View, triggers=self.toggle_media_manager)
self.view_theme_manager_item = create_action(main_window, 'viewThemeManagerItem', can_shortcuts=True,
icon=':/system/system_thememanager.png',
checked=self.theme_manager_dock.isVisible(),
category=UiStrings().View, triggers=self.toggle_theme_manager)
self.view_service_manager_item = create_action(main_window, 'viewServiceManagerItem', can_shortcuts=True,
icon=':/system/system_servicemanager.png',
checked=self.service_manager_dock.isVisible(),
category=UiStrings().View, triggers=self.toggle_service_manager)
self.view_preview_panel = create_action(main_window, 'viewPreviewPanel', can_shortcuts=True,
checked=preview_visible, category=UiStrings().View,
triggers=self.set_preview_panel_visibility)
self.view_live_panel = create_action(main_window, 'viewLivePanel', can_shortcuts=True, checked=live_visible,
category=UiStrings().View, triggers=self.set_live_panel_visibility)
self.lock_panel = create_action(main_window, 'lockPanel', can_shortcuts=True, checked=panel_locked,
category=UiStrings().View, triggers=self.set_lock_panel)
action_list.add_category(UiStrings().ViewMode, CategoryOrder.standard_menu)
self.mode_default_Item = create_action(
self.mode_default_item = create_action(
main_window, 'modeDefaultItem', checked=False, category=UiStrings().ViewMode, can_shortcuts=True)
self.mode_setup_item = create_action(
main_window, 'modeSetupItem', checked=False, category=UiStrings().ViewMode, can_shortcuts=True)
self.mode_live_item = create_action(
main_window, 'modeLiveItem', checked=True, category=UiStrings().ViewMode, can_shortcuts=True)
self.mode_setup_item = create_action(main_window, 'modeSetupItem', checked=False, category=UiStrings().ViewMode,
can_shortcuts=True)
self.mode_live_item = create_action(main_window, 'modeLiveItem', checked=True, category=UiStrings().ViewMode,
can_shortcuts=True)
self.mode_group = QtGui.QActionGroup(main_window)
self.mode_group.addAction(self.mode_default_Item)
self.mode_group.addAction(self.mode_default_item)
self.mode_group.addAction(self.mode_setup_item)
self.mode_group.addAction(self.mode_live_item)
self.mode_default_Item.setChecked(True)
self.mode_default_item.setChecked(True)
action_list.add_category(UiStrings().Tools, CategoryOrder.standard_menu)
self.tools_add_tool_item = create_action(main_window,
'toolsAddToolItem', icon=':/tools/tools_add.png', category=UiStrings().Tools, can_shortcuts=True)
'toolsAddToolItem', icon=':/tools/tools_add.png',
category=UiStrings().Tools, can_shortcuts=True)
self.tools_open_data_folder = create_action(main_window,
'toolsOpenDataFolder', icon=':/general/general_open.png', category=UiStrings().Tools, can_shortcuts=True)
'toolsOpenDataFolder', icon=':/general/general_open.png',
category=UiStrings().Tools, can_shortcuts=True)
self.tools_first_time_wizard = create_action(main_window,
'toolsFirstTimeWizard', icon=':/general/general_revert.png',
category=UiStrings().Tools, can_shortcuts=True)
'toolsFirstTimeWizard', icon=':/general/general_revert.png',
category=UiStrings().Tools, can_shortcuts=True)
self.update_theme_images = create_action(main_window,
'updateThemeImages', category=UiStrings().Tools, can_shortcuts=True)
'updateThemeImages', category=UiStrings().Tools, can_shortcuts=True)
action_list.add_category(UiStrings().Settings, CategoryOrder.standard_menu)
self.settingsPluginListItem = create_action(main_window,
'settingsPluginListItem',
icon=':/system/settings_plugin_list.png',
can_shortcuts=True,
category=UiStrings().Settings, triggers=self.on_plugin_item_clicked)
self.settings_plugin_list_item = create_action(main_window,
'settingsPluginListItem',
icon=':/system/settings_plugin_list.png',
can_shortcuts=True,
category=UiStrings().Settings,
triggers=self.on_plugin_item_clicked)
# i18n Language Items
self.auto_language_item = create_action(main_window, 'autoLanguageItem', checked=LanguageManager.auto_language)
self.language_group = QtGui.QActionGroup(main_window)
@ -282,73 +268,77 @@ class Ui_MainWindow(object):
language_item = create_action(main_window, key, checked=qm_list[key] == saved_language)
add_actions(self.language_group, [language_item])
self.settings_shortcuts_item = create_action(main_window, 'settingsShortcutsItem',
icon=':/system/system_configure_shortcuts.png', category=UiStrings().Settings, can_shortcuts=True)
icon=':/system/system_configure_shortcuts.png',
category=UiStrings().Settings, can_shortcuts=True)
# Formatting Tags were also known as display tags.
self.formatting_tag_item = create_action(main_window, 'displayTagItem',
icon=':/system/tag_editor.png', category=UiStrings().Settings, can_shortcuts=True)
icon=':/system/tag_editor.png', category=UiStrings().Settings,
can_shortcuts=True)
self.settings_configure_item = create_action(main_window, 'settingsConfigureItem',
icon=':/system/system_settings.png', can_shortcuts=True, category=UiStrings().Settings)
icon=':/system/system_settings.png', can_shortcuts=True,
category=UiStrings().Settings)
# Give QT Extra Hint that this is the Preferences Menu Item
self.settings_configure_item.setMenuRole(QtGui.QAction.PreferencesRole)
self.settings_import_item = create_action(
main_window, 'settingsImportItem', category=UiStrings().Import, can_shortcuts=True)
self.settings_export_item = create_action(
main_window, 'settingsExportItem', category=UiStrings().Export, can_shortcuts=True)
self.settings_import_item = create_action(main_window, 'settingsImportItem',
category=UiStrings().Import, can_shortcuts=True)
self.settings_export_item = create_action(main_window, 'settingsExportItem',
category=UiStrings().Export, can_shortcuts=True)
action_list.add_category(UiStrings().Help, CategoryOrder.standard_menu)
self.about_item = create_action(main_window, 'aboutItem', icon=':/system/system_about.png',
can_shortcuts=True, category=UiStrings().Help, triggers=self.on_about_item_clicked)
can_shortcuts=True, category=UiStrings().Help,
triggers=self.on_about_item_clicked)
# Give QT Extra Hint that this is an About Menu Item
self.about_item.setMenuRole(QtGui.QAction.AboutRole)
if os.name == 'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offlineHelpItem = create_action(main_window, 'offlineHelpItem',
icon=':/system/system_help_contents.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offline_help_item = create_action(main_window, 'offline_help_item',
icon=':/system/system_help_contents.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
self.on_line_help_item = create_action(main_window, 'onlineHelpItem',
icon=':/system/system_online_help.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_online_help_clicked)
icon=':/system/system_online_help.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_online_help_clicked)
self.web_site_item = create_action(main_window, 'webSiteItem', can_shortcuts=True, category=UiStrings().Help)
# Shortcuts not connected to buttons or menu entires.
# Shortcuts not connected to buttons or menu entries.
self.search_shortcut_action = create_action(main_window,
'searchShortcut', can_shortcuts=True, category=translate('OpenLP.MainWindow', 'General'),
triggers=self.on_search_shortcut_triggered)
'searchShortcut', can_shortcuts=True,
category=translate('OpenLP.MainWindow', 'General'),
triggers=self.on_search_shortcut_triggered)
add_actions(self.file_import_menu, (self.settings_import_item, None, self.import_theme_item,
self.import_language_item))
self.import_language_item))
add_actions(self.file_export_menu, (self.settings_export_item, None, self.export_theme_item,
self.export_language_item))
self.export_language_item))
add_actions(self.file_menu, (self.file_new_item, self.file_open_item,
self.file_save_item, self.file_save_as_item, self.recent_files_menu.menuAction(), None,
self.file_import_menu.menuAction(), self.file_export_menu.menuAction(), None, self.print_service_order_item,
self.file_exit_item))
add_actions(self.view_modeMenu, (self.mode_default_Item, self.mode_setup_item, self.mode_live_item))
add_actions(self.view_menu, (self.view_modeMenu.menuAction(), None, self.view_media_manager_item,
self.view_service_manager_item, self.view_theme_manager_item, None, self.view_preview_panel,
self.view_live_panel, None, self.lock_panel))
self.file_save_item, self.file_save_as_item, self.recent_files_menu.menuAction(), None,
self.file_import_menu.menuAction(), self.file_export_menu.menuAction(), None, self.print_service_order_item,
self.file_exit_item))
add_actions(self.view_mode_menu, (self.mode_default_item, self.mode_setup_item, self.mode_live_item))
add_actions(self.view_menu, (self.view_mode_menu.menuAction(), None, self.view_media_manager_item,
self.view_service_manager_item, self.view_theme_manager_item, None, self.view_preview_panel,
self.view_live_panel, None, self.lock_panel))
# i18n add Language Actions
add_actions(self.settings_language_menu, (self.auto_language_item, None))
add_actions(self.settings_language_menu, self.language_group.actions())
# Order things differently in OS X so that Preferences menu item in the
# app menu is correct (this gets picked up automatically by Qt).
if sys.platform == 'darwin':
add_actions(self.settings_menu, (self.settingsPluginListItem, self.settings_language_menu.menuAction(),
None, self.settings_configure_item, self.settings_shortcuts_item, self.formatting_tag_item))
add_actions(self.settings_menu, (self.settings_plugin_list_item, self.settings_language_menu.menuAction(),
None, self.settings_configure_item, self.settings_shortcuts_item, self.formatting_tag_item))
else:
add_actions(self.settings_menu, (self.settingsPluginListItem, self.settings_language_menu.menuAction(),
None, self.formatting_tag_item, self.settings_shortcuts_item, self.settings_configure_item))
add_actions(self.settings_menu, (self.settings_plugin_list_item, self.settings_language_menu.menuAction(),
None, self.formatting_tag_item, self.settings_shortcuts_item, self.settings_configure_item))
add_actions(self.tools_menu, (self.tools_add_tool_item, None))
add_actions(self.tools_menu, (self.tools_open_data_folder, None))
add_actions(self.tools_menu, (self.tools_first_time_wizard, None))
add_actions(self.tools_menu, [self.update_theme_images])
if os.name == 'nt':
add_actions(self.help_menu, (self.offlineHelpItem, self.on_line_help_item, None, self.web_site_item,
self.about_item))
add_actions(self.help_menu, (self.offline_help_item, self.on_line_help_item, None, self.web_site_item,
self.about_item))
else:
add_actions(self.help_menu, (self.on_line_help_item, None, self.web_site_item, self.about_item))
add_actions(self.menu_bar, (self.file_menu.menuAction(), self.view_menu.menuAction(),
self.tools_menu.menuAction(), self.settings_menu.menuAction(), self.help_menu.menuAction()))
self.tools_menu.menuAction(), self.settings_menu.menuAction(), self.help_menu.menuAction()))
add_actions(self, [self.search_shortcut_action])
# Initialise the translation
self.retranslateUi(main_window)
@ -360,7 +350,7 @@ class Ui_MainWindow(object):
self.import_language_item.setVisible(False)
self.export_language_item.setVisible(False)
self.set_lock_panel(panel_locked)
self.settingsImported = False
self.settings_imported = False
def retranslateUi(self, main_window):
"""
@ -372,7 +362,7 @@ class Ui_MainWindow(object):
self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))
self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Files'))
self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View'))
self.view_modeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language'))
@ -392,7 +382,7 @@ class Ui_MainWindow(object):
self.file_save_as_item.setText(translate('OpenLP.MainWindow', 'Save &As...'))
self.file_save_as_item.setToolTip(translate('OpenLP.MainWindow', 'Save Service As'))
self.file_save_as_item.setStatusTip(translate('OpenLP.MainWindow',
'Save the current service under a new name.'))
'Save the current service under a new name.'))
self.print_service_order_item.setText(UiStrings().PrintService)
self.print_service_order_item.setStatusTip(translate('OpenLP.MainWindow', 'Print the current service.'))
self.file_exit_item.setText(translate('OpenLP.MainWindow', 'E&xit'))
@ -405,23 +395,24 @@ class Ui_MainWindow(object):
self.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...'))
self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...'))
self.settings_export_item.setStatusTip(translate('OpenLP.MainWindow',
'Export OpenLP settings to a specified *.config file'))
'Export OpenLP settings to a specified *.config file'))
self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.settings_import_item.setStatusTip(translate('OpenLP.MainWindow',
'Import OpenLP settings from a specified *.config file previously exported on this or another machine'))
'Import OpenLP settings from a specified *.config file previously '
'exported on this or another machine'))
self.settings_import_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.view_media_manager_item.setText(translate('OpenLP.MainWindow', '&Media Manager'))
self.view_media_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Media Manager'))
self.view_media_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the media manager.'))
'Toggle the visibility of the media manager.'))
self.view_theme_manager_item.setText(translate('OpenLP.MainWindow', '&Theme Manager'))
self.view_theme_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Theme Manager'))
self.view_theme_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the theme manager.'))
'Toggle the visibility of the theme manager.'))
self.view_service_manager_item.setText(translate('OpenLP.MainWindow', '&Service Manager'))
self.view_service_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Service Manager'))
self.view_service_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the service manager.'))
'Toggle the visibility of the service manager.'))
self.view_preview_panel.setText(translate('OpenLP.MainWindow', '&Preview Panel'))
self.view_preview_panel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Preview Panel'))
self.view_preview_panel.setStatusTip(
@ -431,12 +422,12 @@ class Ui_MainWindow(object):
self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels'))
self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.'))
self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.'))
self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', '&Plugin List'))
self.settingsPluginListItem.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))
self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Plugin List'))
self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))
self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP'))
if os.name == 'nt':
self.offlineHelpItem.setText(translate('OpenLP.MainWindow', '&User Guide'))
self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide'))
self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help'))
self.search_shortcut_action.setText(UiStrings().Search)
self.search_shortcut_action.setToolTip(
@ -449,18 +440,18 @@ class Ui_MainWindow(object):
self.auto_language_item.setStatusTip(translate('OpenLP.MainWindow', 'Use the system language, if available.'))
self.tools_add_tool_item.setText(translate('OpenLP.MainWindow', 'Add &Tool...'))
self.tools_add_tool_item.setStatusTip(translate('OpenLP.MainWindow',
'Add an application to the list of tools.'))
'Add an application to the list of tools.'))
self.tools_open_data_folder.setText(translate('OpenLP.MainWindow', 'Open &Data Folder...'))
self.tools_open_data_folder.setStatusTip(translate('OpenLP.MainWindow',
'Open the folder where songs, bibles and other data resides.'))
'Open the folder where songs, bibles and other data resides.'))
self.tools_first_time_wizard.setText(translate('OpenLP.MainWindow', 'Re-run First Time Wizard'))
self.tools_first_time_wizard.setStatusTip(translate('OpenLP.MainWindow',
'Re-run the First Time Wizard, importing songs, Bibles and themes.'))
'Re-run the First Time Wizard, importing songs, Bibles and themes.'))
self.update_theme_images.setText(translate('OpenLP.MainWindow', 'Update Theme Images'))
self.update_theme_images.setStatusTip(translate('OpenLP.MainWindow',
'Update the preview images for all themes.'))
self.mode_default_Item.setText(translate('OpenLP.MainWindow', '&Default'))
self.mode_default_Item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode back to the default.'))
'Update the preview images for all themes.'))
self.mode_default_item.setText(translate('OpenLP.MainWindow', '&Default'))
self.mode_default_item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode back to the default.'))
self.mode_setup_item.setText(translate('OpenLP.MainWindow', '&Setup'))
self.mode_setup_item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode to Setup.'))
self.mode_live_item.setText(translate('OpenLP.MainWindow', '&Live'))
@ -504,14 +495,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.formatting_tag_form = FormattingTagForm(self)
self.shortcut_form = ShortcutListForm(self)
# Set up the path with plugins
self.plugin_manager = PluginManager()
self.plugin_manager = PluginManager(self)
self.image_manager = ImageManager()
self.renderer = Renderer()
# Set up the interface
self.setupUi(self)
# Define the media Dock Manager
self.media_dock_manager = MediaDockManager(self.media_tool_box)
# Load settings after setupUi so default UI sizes are overwritten
self.load_settings()
# Once settings are loaded update the menu with the recent files.
self.update_recent_files_menu()
self.plugin_form = PluginForm(self)
@ -523,7 +514,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.export_theme_item.triggered.connect(self.theme_manager_contents.on_export_theme)
self.web_site_item.triggered.connect(self.on_help_web_site_clicked)
self.tools_open_data_folder.triggered.connect(self.on_tools_open_data_folder_clicked)
self.tools_first_time_wizard.triggered.connect(self.on_first_time_wzard_clicked)
self.tools_first_time_wizard.triggered.connect(self.on_first_time_wizard_clicked)
self.update_theme_images.triggered.connect(self.on_update_theme_images)
self.formatting_tag_item.triggered.connect(self.on_formatting_tag_item_clicked)
self.settings_configure_item.triggered.connect(self.on_settings_configure_iem_clicked)
@ -532,7 +523,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.settings_export_item.triggered.connect(self.on_settings_export_item_clicked)
# i18n set signals for languages
self.language_group.triggered.connect(LanguageManager.set_language)
self.mode_default_Item.triggered.connect(self.on_mode_default_item_clicked)
self.mode_default_item.triggered.connect(self.on_mode_default_item_clicked)
self.mode_setup_item.triggered.connect(self.on_mode_setup_item_clicked)
self.mode_live_item.triggered.connect(self.on_mode_live_item_clicked)
# Media Manager
@ -542,11 +533,19 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Registry().register_function('theme_update_global', self.default_theme_changed)
Registry().register_function('openlp_version_check', self.version_notice)
Registry().register_function('config_screen_changed', self.screen_changed)
Registry().register_function('bootstrap_post_set_up', self.restore_current_media_manager_item)
self.renderer = Renderer()
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
# Reset the cursor
self.application.set_normal_cursor()
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
"""
self.preview_controller.panel.setVisible(Settings().value('user interface/preview panel'))
self.live_controller.panel.setVisible(Settings().value('user interface/live panel'))
self.load_settings()
self.restore_current_media_manager_item()
def restore_current_media_manager_item(self):
"""
Called on start up to restore the last active media plugin.
@ -559,7 +558,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def on_search_shortcut_triggered(self):
"""
Called when the search shotcut has been pressed.
Called when the search shortcut has been pressed.
"""
# Make sure the media_dock is visible.
if not self.media_manager_dock.isVisible():
@ -583,7 +582,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
log.debug('version_notice')
version_text = translate('OpenLP.MainWindow', 'Version %s of OpenLP is now available for download (you are '
'currently running version %s). \n\nYou can download the latest version from http://openlp.org/.')
'currently running version %s). \n\nYou can download the latest version from '
'http://openlp.org/.')
self.version_text = version_text % (version, get_application_version()['full'])
def show(self):
@ -607,12 +607,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.timer_version_id = self.startTimer(1000)
view_mode = Settings().value('%s/view mode' % self.general_settings_section)
if view_mode == 'default':
self.mode_default_Item.setChecked(True)
self.mode_default_item.setChecked(True)
elif view_mode == 'setup':
self.setViewMode(True, True, False, True, False)
self.set_view_mode(True, True, False, True, False)
self.mode_setup_item.setChecked(True)
elif view_mode == 'live':
self.setViewMode(False, True, False, False, True)
self.set_view_mode(False, True, False, False, True)
self.mode_live_item.setChecked(True)
def app_startup(self):
@ -638,21 +638,21 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
temp_dir = os.path.join(str(gettempdir()), 'openlp')
shutil.rmtree(temp_dir, True)
def on_first_time_wzard_clicked(self):
def on_first_time_wizard_clicked(self):
"""
Re-run the first time wizard. Prompts the user for run confirmation
If wizard is run, songs, bibles and themes are imported. The default
theme is changed (if necessary). The plugins in pluginmanager are
Re-run the first time wizard. Prompts the user for run confirmation.If wizard is run, songs, bibles and
themes are imported. The default theme is changed (if necessary). The plugins in pluginmanager are
set active/in-active to match the selection in the wizard.
"""
answer = QtGui.QMessageBox.warning(self,
translate('OpenLP.MainWindow', 'Re-run First Time Wizard?'),
translate('OpenLP.MainWindow', 'Are you sure you want to re-run the First Time Wizard?\n\n'
'Re-running this wizard may make changes to your current '
'OpenLP configuration and possibly add songs to your '
'existing songs list and change your default theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
translate('OpenLP.MainWindow', 'Re-run First Time Wizard?'),
translate('OpenLP.MainWindow', 'Are you sure you want to re-run the First '
'Time Wizard?\n\nRe-running this wizard may make changes to your '
'current OpenLP configuration and possibly add songs to your '
'#existing songs list and change your default theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return
screens = ScreenList()
@ -663,15 +663,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.application.set_busy_cursor()
self.first_time()
for plugin in self.plugin_manager.plugins:
self.activePlugin = plugin
oldStatus = self.activePlugin.status
self.activePlugin.set_status()
if oldStatus != self.activePlugin.status:
if self.activePlugin.status == PluginStatus.Active:
self.activePlugin.toggle_status(PluginStatus.Active)
self.activePlugin.app_startup()
self.active_plugin = plugin
old_status = self.active_plugin.status
self.active_plugin.set_status()
if old_status != self.active_plugin.status:
if self.active_plugin.status == PluginStatus.Active:
self.active_plugin.toggle_status(PluginStatus.Active)
self.active_plugin.app_startup()
else:
self.activePlugin.toggle_status(PluginStatus.Inactive)
self.active_plugin.toggle_status(PluginStatus.Inactive)
# Set global theme and
Registry().execute('theme_update_global', self.theme_manager_contents.global_theme)
self.theme_manager_contents.load_first_time_themes()
@ -688,7 +688,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if settings.value('%s/screen blank' % self.general_settings_section):
if settings.value('%s/blank warning' % self.general_settings_section):
QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'),
translate('OpenLP.MainWindow', 'The Main Display has been blanked out'))
translate('OpenLP.MainWindow', 'The Main Display has been blanked out'))
def error_message(self, title, message):
"""
@ -743,7 +743,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
Load the local OpenLP help file
"""
os.startfile(self.localHelpFile)
os.startfile(self.local_help_file)
def on_online_help_clicked(self):
"""
@ -809,15 +809,21 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Import settings from an export INI file
"""
answer = QtGui.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'Import settings?'),
translate('OpenLP.MainWindow', 'Are you sure you want to import settings?\n\n'
'Importing settings will make permanent changes to your current OpenLP configuration.\n\n'
'Importing incorrect settings may cause erratic behaviour or OpenLP to terminate abnormally.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
translate('OpenLP.MainWindow', 'Are you sure you want to import '
'settings?\n\n Importing settings will '
'make permanent changes to your current '
'OpenLP configuration.\n\n Importing '
'incorrect settings may cause erratic '
'behaviour or OpenLP to terminate '
'abnormally.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return
import_file_name = QtGui.QFileDialog.getOpenFileName(self, translate('OpenLP.MainWindow', 'Open File'), '',
translate('OpenLP.MainWindow', 'OpenLP Export Settings Files (*.conf)'))
translate('OpenLP.MainWindow', 'OpenLP Export Settings '
'Files (*.conf)'))
if not import_file_name:
return
setting_sections = []
@ -850,9 +856,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# load what we can from it, and just silently ignore anything we don't recognise.
if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export':
QtGui.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'Import settings'),
translate('OpenLP.MainWindow', 'The file you have selected does not appear to be a valid OpenLP '
'settings file.\n\nProcessing has terminated and no changes have been made.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
translate('OpenLP.MainWindow', 'The file you have selected does not appear to '
'be a valid OpenLP settings file.\n\nProcessing has terminated and '
'no changes have been made.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return
import_keys = import_settings.allKeys()
for section_key in import_keys:
@ -885,10 +892,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# We must do an immediate restart or current configuration will overwrite what was just imported when
# application terminates normally. We need to exit without saving configuration.
QtGui.QMessageBox.information(self, translate('OpenLP.MainWindow', 'Import settings'),
translate('OpenLP.MainWindow', 'OpenLP will now close. Imported settings will '
'be applied the next time you start OpenLP.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.settingsImported = True
translate('OpenLP.MainWindow', 'OpenLP will now close. Imported settings will '
'be applied the next time you start OpenLP.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.settings_imported = True
self.clean_up()
QtCore.QCoreApplication.exit()
@ -897,8 +904,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Export settings to a .conf file in INI format
"""
export_file_name = QtGui.QFileDialog.getSaveFileName(self,
translate('OpenLP.MainWindow', 'Export Settings File'), '',
translate('OpenLP.MainWindow', 'OpenLP Export Settings File (*.conf)'))
translate('OpenLP.MainWindow', 'Export Settings File'),
'',
translate('OpenLP.MainWindow', 'OpenLP Export Settings '
'File (*.conf)'))
if not export_file_name:
return
# Make sure it's a .conf file.
@ -967,21 +976,21 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
Put OpenLP into "Default" view mode.
"""
self.setViewMode(True, True, True, True, True, 'default')
self.set_view_mode(True, True, True, True, True, 'default')
def on_mode_setup_item_clicked(self):
"""
Put OpenLP into "Setup" view mode.
"""
self.setViewMode(True, True, False, True, False, 'setup')
self.set_view_mode(True, True, False, True, False, 'setup')
def on_mode_live_item_clicked(self):
"""
Put OpenLP into "Live" view mode.
"""
self.setViewMode(False, True, False, False, True, 'live')
self.set_view_mode(False, True, False, False, True, 'live')
def setViewMode(self, media=True, service=True, theme=True, preview=True, live=True, mode=''):
def set_view_mode(self, media=True, service=True, theme=True, preview=True, live=True, mode=''):
"""
Set OpenLP to a different view mode.
"""
@ -1018,7 +1027,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
event.ignore()
return
# If we just did a settings import, close without saving changes.
if self.settingsImported:
if self.settings_imported:
self.clean_up(False)
event.accept()
if self.service_manager_contents.is_modified():
@ -1037,9 +1046,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
else:
if Settings().value('advanced/enable exit confirmation'):
ret = QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'Close OpenLP'),
translate('OpenLP.MainWindow', 'Are you sure you want to close OpenLP?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes)
translate('OpenLP.MainWindow', 'Are you sure you want to close '
'OpenLP?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui
.QMessageBox.No),
QtGui.QMessageBox.Yes)
if ret == QtGui.QMessageBox.Yes:
self.clean_up()
event.accept()
@ -1108,7 +1119,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Update the default theme indicator in the status bar
"""
self.default_theme_label.setText(translate('OpenLP.MainWindow', 'Default Theme: %s') %
Settings().value('themes/global theme'))
Settings().value('themes/global theme'))
def toggle_media_manager(self):
"""
@ -1197,8 +1208,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.live_controller.splitter.restoreState(settings.value('live splitter geometry'))
self.preview_controller.splitter.restoreState(settings.value('preview splitter geometry'))
self.control_splitter.restoreState(settings.value('main window splitter geometry'))
#This needs to be called after restoreState(), because saveState() also saves the "Collapsible" property
#which was True (by default) < OpenLP 2.1.
# This needs to be called after restoreState(), because saveState() also saves the "Collapsible" property
# which was True (by default) < OpenLP 2.1.
self.control_splitter.setChildrenCollapsible(False)
settings.endGroup()
@ -1207,7 +1218,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Save the main window settings.
"""
# Exit if we just did a settings import.
if self.settingsImported:
if self.settings_imported:
return
log.debug('Saving QSettings')
settings = Settings()
@ -1228,22 +1239,23 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Updates the recent file menu with the latest list of service files accessed.
"""
recent_file_count = Settings().value('advanced/recent file count')
existing_recent_files = [recentFile for recentFile in self.recent_files
if os.path.isfile(str(recentFile))]
existing_recent_files = [recentFile for recentFile in self.recent_files if os.path.isfile(str(recentFile))]
recent_files_to_display = existing_recent_files[0:recent_file_count]
self.recent_files_menu.clear()
for file_id, filename in enumerate(recent_files_to_display):
log.debug('Recent file name: %s', filename)
action = create_action(self, '',
text='&%d %s' % (file_id + 1, os.path.splitext(os.path.basename(
str(filename)))[0]), data=filename,
triggers=self.service_manager_contents.on_recent_service_clicked)
text='&%d %s' % (file_id + 1,
os.path.splitext(os.path.basename(str(filename)))[0]), data=filename,
triggers=self.service_manager_contents.on_recent_service_clicked)
self.recent_files_menu.addAction(action)
clear_recent_files_action = create_action(self, '',
text=translate('OpenLP.MainWindow', 'Clear List', 'Clear List of recent files'),
statustip=translate('OpenLP.MainWindow', 'Clear the list of recent files.'),
enabled=bool(self.recent_files),
triggers=self.clear_recent_file_menu)
text=translate('OpenLP.MainWindow', 'Clear List', 'Clear List of '
'recent files'),
statustip=translate('OpenLP.MainWindow', 'Clear the list of recent '
'files.'),
enabled=bool(self.recent_files),
triggers=self.clear_recent_file_menu)
add_actions(self.recent_files_menu, (None, clear_recent_files_action))
clear_recent_files_action.setEnabled(bool(self.recent_files))
@ -1312,7 +1324,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Has the thread passed some data to be displayed so display it and stop all waiting
if hasattr(self, 'version_text'):
QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'),
self.version_text)
self.version_text)
else:
# the thread has not confirmed it is running or it has not yet sent any data so lets keep waiting
if not hasattr(self, 'version_update_running') or self.version_update_running:
@ -1344,16 +1356,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
try:
self.showStatusMessage(
translate('OpenLP.MainWindow', 'Copying OpenLP data to new data directory location - %s '
'- Please wait for copy to finish').replace('%s', self.new_data_path))
'- Please wait for copy to finish').replace('%s', self.new_data_path))
dir_util.copy_tree(old_data_path, self.new_data_path)
log.info('Copy sucessful')
log.info('Copy successful')
except (IOError, os.error, DistutilsFileError) as why:
self.application.set_normal_cursor()
log.exception('Data copy failed %s' % str(why))
QtGui.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'New Data Directory Error'),
translate('OpenLP.MainWindow',
'OpenLP Data directory copy failed\n\n%s').replace('%s', str(why)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
translate('OpenLP.MainWindow',
'OpenLP Data directory copy failed\n\n%s').replace('%s', str(why)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return False
else:
log.info('No data copy requested')

View File

@ -35,8 +35,8 @@ import os
import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import OpenLPToolbar, Registry
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import OpenLPToolbar
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
from openlp.core.ui.media.mediaplayer import MediaPlayer

View File

@ -31,7 +31,7 @@ The :mod:`~openlp.core.ui.media.mediaplayer` module contains the MediaPlayer cla
"""
import os
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui.media import MediaState

View File

@ -31,8 +31,8 @@ The :mod:`~openlp.core.ui.media.playertab` module holds the configuration tab fo
"""
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, SettingsTab
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import SettingsTab
from openlp.core.lib.ui import create_button
from openlp.core.ui.media import get_media_players, set_media_players

View File

@ -34,8 +34,8 @@ import os
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import PluginStatus, Registry
from openlp.core.common import Registry, translate
from openlp.core.lib import PluginStatus
from .plugindialog import Ui_PluginViewDialog
log = logging.getLogger(__name__)

View File

@ -35,8 +35,8 @@ import os
from PyQt4 import QtCore, QtGui
from lxml import html
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, get_text_file_string
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import get_text_file_string
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
from openlp.core.common import AppLocation

View File

@ -30,7 +30,7 @@
The service item edit dialog
"""
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from .serviceitemeditdialog import Ui_ServiceItemEditDialog

View File

@ -42,8 +42,8 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, ThemeLevel, check_directory_exists, UiStrings, translate
from openlp.core.lib import OpenLPToolbar, ServiceItem, ItemCapabilities, PluginStatus, Registry, build_icon
from openlp.core.common import Registry, AppLocation, Settings, ThemeLevel, check_directory_exists, UiStrings, translate
from openlp.core.lib import OpenLPToolbar, ServiceItem, ItemCapabilities, PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceform import PrintServiceForm
@ -741,7 +741,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
Settings().setValue('servicemanager/last file', file_name)
else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
log.exception('File contains no service data')
log.error('File contains no service data')
except (IOError, NameError, zipfile.BadZipfile):
log.exception('Problem loading service file %s' % file_name)
critical_error_message_box(message=translate('OpenLP.ServiceManager',

View File

@ -31,8 +31,8 @@ The :mod:`~openlp.core.ui.servicenoteform` module contains the `ServiceNoteForm`
"""
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import SpellTextEdit, Registry
from openlp.core.common import Registry, translate
from openlp.core.lib import SpellTextEdit
from openlp.core.lib.ui import create_button_box

View File

@ -33,7 +33,8 @@ import logging
from PyQt4 import QtGui
from openlp.core.lib import PluginStatus, Registry, build_icon
from openlp.core.common import Registry
from openlp.core.lib import PluginStatus, build_icon
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
from openlp.core.ui.media import PlayerTab
from .settingsdialog import Ui_SettingsDialog

View File

@ -33,8 +33,7 @@ import re
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Registry
from openlp.core.common import Settings, translate
from openlp.core.common import Registry, Settings, translate
from openlp.core.utils.actions import ActionList
from .shortcutlistdialog import Ui_ShortcutListDialog

View File

@ -31,24 +31,21 @@ The :mod:`slidecontroller` module contains the most important part of OpenLP - t
"""
import os
import logging
import copy
from collections import deque
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, SlideLimits, UiStrings, translate
from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, Registry, \
from openlp.core.common import Registry, Settings, SlideLimits, UiStrings, translate, RegistryMixin, OpenLPMixin
from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, \
ScreenList, build_icon, build_html
from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
from openlp.core.lib.ui import create_action
from openlp.core.utils.actions import ActionList, CategoryOrder
from openlp.core.ui.listpreviewwidget import ListPreviewWidget
log = logging.getLogger(__name__)
# Threshold which has to be trespassed to toggle.
HIDE_MENU_THRESHOLD = 27
HIDE_MENU_THRESHOLD = 27
AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
'border-top-color: palette(shadow); ' \
'border-left-color: palette(shadow); ' \
@ -57,17 +54,35 @@ AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
'border-radius: 3px; border-style: inset; ' \
'border-width: 1; font-family: monospace; margin: 2px;'
NARROW_MENU = [
'hide_menu'
]
LOOP_LIST = [
'play_slides_menu',
'loop_separator',
'delay_spin_box'
]
AUDIO_LIST = [
'audioPauseItem',
'audio_time_label'
]
WIDE_MENU = [
'blank_screen_button',
'theme_screen_button',
'desktop_screen_button'
]
class DisplayController(QtGui.QWidget):
"""
Controller is a general display controller widget.
"""
def __init__(self, parent, is_live=False):
def __init__(self, parent):
"""
Set up the general Controller.
"""
super(DisplayController, self).__init__(parent)
self.is_live = is_live
self.is_live = False
self.display = None
self.controller_type = DisplayControllerType.Plugin
@ -87,43 +102,33 @@ class SlideController(DisplayController):
SlideController is the slide controller widget. This widget is what the
user uses to control the displaying of verses/slides/etc on the screen.
"""
def __init__(self, parent, is_live=False):
def __init__(self, parent):
"""
Set up the Slide Controller.
"""
super(SlideController, self).__init__(parent, is_live)
Registry().register_function('bootstrap_post_set_up', self.screen_size_changed)
super(SlideController, self).__init__(parent)
def post_set_up(self):
"""
Call by bootstrap functions
"""
self.initialise()
self.screen_size_changed()
def initialise(self):
self.screens = ScreenList()
try:
self.ratio = self.screens.current['size'].width() / self.screens.current['size'].height()
except ZeroDivisionError:
self.ratio = 1
self.loop_list = [
'play_slides_menu',
'loop_separator',
'delay_spin_box'
]
# audioPauseItem is also in Settings so any changes need to be paired
self.audio_list = [
'audioPauseItem',
'audio_time_label'
]
self.wide_menu = [
'blank_screen_button',
'theme_screen_button',
'desktop_screen_button'
]
self.narrow_menu = [
'hide_menu'
]
self.timer_id = 0
self.song_edit = False
self.selected_row = 0
self.service_item = None
self.slide_limits = None
self.update_slide_limits()
self.panel = QtGui.QWidget(parent.control_splitter)
self.slideList = {}
self.panel = QtGui.QWidget(self.main_window.control_splitter)
self.slide_list = {}
self.slide_count = 0
self.slide_image = None
# Layout for holding panel
@ -132,21 +137,6 @@ class SlideController(DisplayController):
self.panel_layout.setMargin(0)
# Type label for the top of the slide controller
self.type_label = QtGui.QLabel(self.panel)
if self.is_live:
Registry().register('live_controller', self)
self.type_label.setText(UiStrings().Live)
self.split = 1
self.type_prefix = 'live'
self.keypress_queue = deque()
self.keypress_loop = False
self.category = UiStrings().LiveToolbar
ActionList.get_instance().add_category(str(self.category), CategoryOrder.standard_toolbar)
else:
Registry().register('preview_controller', self)
self.type_label.setText(UiStrings().Preview)
self.split = 0
self.type_prefix = 'preview'
self.category = None
self.type_label.setStyleSheet('font-weight: bold; font-size: 12pt;')
self.type_label.setAlignment(QtCore.Qt.AlignCenter)
self.panel_layout.addWidget(self.type_label)
@ -172,17 +162,19 @@ class SlideController(DisplayController):
size_toolbar_policy.setHeightForWidth(self.toolbar.sizePolicy().hasHeightForWidth())
self.toolbar.setSizePolicy(size_toolbar_policy)
self.previous_item = create_action(self, 'previousItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Previous Slide'), icon=':/slides/slide_previous.png',
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_previous)
text=translate('OpenLP.SlideController', 'Previous Slide'),
icon=':/slides/slide_previous.png',
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_previous)
self.toolbar.addAction(self.previous_item)
self.nextItem = create_action(self, 'nextItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Next Slide'), icon=':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_next_action)
self.toolbar.addAction(self.nextItem)
self.next_item = create_action(self, 'nextItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Next Slide'),
icon=':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_next_action)
self.toolbar.addAction(self.next_item)
self.toolbar.addSeparator()
self.controller_type = DisplayControllerType.Preview
if self.is_live:
@ -195,16 +187,20 @@ class SlideController(DisplayController):
self.hide_menu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.toolbar.add_toolbar_widget(self.hide_menu)
self.blank_screen = create_action(self, 'blankScreen',
text=translate('OpenLP.SlideController', 'Blank Screen'), icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category, triggers=self.on_blank_display)
text=translate('OpenLP.SlideController', 'Blank Screen'),
icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_blank_display)
self.theme_screen = create_action(self, 'themeScreen',
text=translate('OpenLP.SlideController', 'Blank to Theme'), icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
text=translate('OpenLP.SlideController', 'Blank to Theme'),
icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
self.desktop_screen = create_action(self, 'desktopScreen',
text=translate('OpenLP.SlideController', 'Show Desktop'), icon=':/slides/slide_desktop.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_hide_display)
text=translate('OpenLP.SlideController', 'Show Desktop'),
icon=':/slides/slide_desktop.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_hide_display)
self.hide_menu.setDefaultAction(self.blank_screen)
self.hide_menu.menu().addAction(self.blank_screen)
self.hide_menu.menu().addAction(self.theme_screen)
@ -231,11 +227,11 @@ class SlideController(DisplayController):
self.play_slides_menu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Play Slides'), self.toolbar))
self.toolbar.add_toolbar_widget(self.play_slides_menu)
self.play_slides_loop = create_action(self, 'playSlidesLoop', text=UiStrings().PlaySlidesInLoop,
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_loop)
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_loop)
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_once)
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_once)
if Settings().value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
else:
@ -251,12 +247,15 @@ class SlideController(DisplayController):
self.toolbar.add_toolbar_widget(self.delay_spin_box)
else:
self.toolbar.add_toolbar_action('goLive', icon=':/general/general_live.png',
tooltip=translate('OpenLP.SlideController', 'Move to live.'), triggers=self.on_go_live)
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
triggers=self.on_go_live)
self.toolbar.add_toolbar_action('addToService', icon=':/general/general_add.png',
tooltip=translate('OpenLP.SlideController', 'Add to Service.'), triggers=self.on_preview_add_to_service)
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
triggers=self.on_preview_add_to_service)
self.toolbar.addSeparator()
self.toolbar.add_toolbar_action('editSong', icon=':/general/general_edit.png',
tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.'), triggers=self.on_edit_song)
tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.')
, triggers=self.on_edit_song)
self.controller_layout.addWidget(self.toolbar)
# Build the Media Toolbar
self.media_controller.register_controller(self)
@ -278,27 +277,29 @@ class SlideController(DisplayController):
self.audio_menu = QtGui.QMenu(translate('OpenLP.SlideController', 'Background Audio'), self.toolbar)
self.audio_pause_item.setMenu(self.audio_menu)
self.audio_pause_item.setParent(self.toolbar)
self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(
QtGui.QToolButton.MenuButtonPopup)
self.nextTrackItem = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
icon=':/slides/media_playback_next.png',
tooltip=translate('OpenLP.SlideController', 'Go to next audio track.'),
category=self.category, can_shortcuts=True, triggers=self.on_next_track_clicked)
self.audio_menu.addAction(self.nextTrackItem)
self.trackMenu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.next_track_item = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
icon=':/slides/media_playback_next.png',
tooltip=translate('OpenLP.SlideController',
'Go to next audio track.'),
category=self.category,
can_shortcuts=True,
triggers=self.on_next_track_clicked)
self.audio_menu.addAction(self.next_track_item)
self.track_menu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
self.audio_time_label = QtGui.QLabel(' 00:00 ', self.toolbar)
self.audio_time_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter)
self.audio_time_label.setStyleSheet(AUDIO_TIME_LABEL_STYLESHEET)
self.audio_time_label.setObjectName('audio_time_label')
self.toolbar.add_toolbar_widget(self.audio_time_label)
self.toolbar.set_widget_visible(self.audio_list, False)
self.toolbar.set_widget_visible(AUDIO_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
# Screen preview area
self.preview_frame = QtGui.QFrame(self.splitter)
self.preview_frame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
self.preview_frame.setMinimumHeight(100)
self.preview_frame.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored,
QtGui.QSizePolicy.Label))
QtGui.QSizePolicy.Label))
self.preview_frame.setFrameShape(QtGui.QFrame.StyledPanel)
self.preview_frame.setFrameShadow(QtGui.QFrame.Sunken)
self.preview_frame.setObjectName('preview_frame')
@ -331,9 +332,9 @@ class SlideController(DisplayController):
self.grid.addLayout(self.slide_layout, 0, 0, 1, 1)
if self.is_live:
self.current_shortcut = ''
self.shortcutTimer = QtCore.QTimer()
self.shortcutTimer.setObjectName('shortcutTimer')
self.shortcutTimer.setSingleShot(True)
self.shortcut_timer = QtCore.QTimer()
self.shortcut_timer.setObjectName('shortcut_timer')
self.shortcut_timer.setSingleShot(True)
shortcuts = [
{'key': 'V', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
{'key': 'C', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
@ -345,51 +346,49 @@ class SlideController(DisplayController):
{'key': 'O', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Other"')}
]
shortcuts.extend([{'key': str(number)} for number in range(10)])
self.controller.addActions([create_action(self,
'shortcutAction_%s' % s['key'], text=s.get('text'),
can_shortcuts=True,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category if s.get('configurable') else None,
triggers=self._slide_shortcut_activated) for s in shortcuts])
self.shortcutTimer.timeout.connect(self._slide_shortcut_activated)
self.controller.addActions([create_action(self, 'shortcutAction_%s' % s['key'],
text=s.get('text'),
can_shortcuts=True,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category if s.get('configurable') else None,
triggers=self._slide_shortcut_activated) for s in shortcuts])
self.shortcut_timer.timeout.connect(self._slide_shortcut_activated)
# Signals
self.preview_widget.clicked.connect(self.on_slide_selected)
self.preview_widget.itemSelectionChanged.connect(self.on_slide_selected)
if self.is_live:
# Need to use event as called across threads and UI is updated
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_toggle_display'), self.toggle_display)
Registry().register_function('slidecontroller_live_spin_delay', self.receive_spin_delay)
self.toolbar.set_widget_visible(self.loop_list, False)
self.toolbar.set_widget_visible(self.wide_menu, False)
self.toolbar.set_widget_visible(LOOP_LIST, False)
self.toolbar.set_widget_visible(WIDE_MENU, False)
else:
self.preview_widget.doubleClicked.connect(self.on_preview_add_to_service)
self.toolbar.set_widget_visible(['editSong'], False)
if self.is_live:
self.set_live_hotkeys(self)
self.set_live_hot_keys(self)
self.__add_actions_to_widget(self.controller)
else:
self.controller.addActions([self.nextItem, self.previous_item])
self.controller.addActions([self.next_item, self.previous_item])
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
Registry().register_function('slidecontroller_%s_change' % self.type_prefix, self.on_slide_change)
Registry().register_function('slidecontroller_%s_blank' % self.type_prefix, self.on_slide_blank)
Registry().register_function('slidecontroller_%s_unblank' % self.type_prefix, self.on_slide_unblank)
Registry().register_function('slidecontroller_update_slide_limits', self.update_slide_limits)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_set' % self.type_prefix),
self.on_slide_selected_index)
self.on_slide_selected_index)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_next' % self.type_prefix),
self.on_slide_selected_next)
self.on_slide_selected_next)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_previous' % self.type_prefix),
self.on_slide_selected_previous)
self.on_slide_selected_previous)
def _slide_shortcut_activated(self):
"""
Called, when a shortcut has been activated to jump to a chorus, verse,
etc.
Called, when a shortcut has been activated to jump to a chorus, verse, etc.
**Note**: This implementation is based on shortcuts. But it rather works
like "key sequenes". You have to press one key after the other and
**not** at the same time.
For example to jump to "V3" you have to press "V" and afterwards but
within a time frame of 350ms you have to press "3".
**Note**: This implementation is based on shortcuts. But it rather works like "key sequenes". You have to
press one key after the other and **not** at the same time.
For example to jump to "V3" you have to press "V" and afterwards but within a time frame of 350ms
you have to press "3".
"""
try:
from openlp.plugins.songs.lib import VerseType
@ -420,43 +419,45 @@ class SlideController(DisplayController):
self.current_shortcut += verse_type
elif verse_type:
self.current_shortcut = verse_type
keys = list(self.slideList.keys())
matches = [match for match in keys
if match.startswith(self.current_shortcut)]
keys = list(self.slide_list.keys())
matches = [match for match in keys if match.startswith(self.current_shortcut)]
if len(matches) == 1:
self.shortcutTimer.stop()
self.shortcut_timer.stop()
self.current_shortcut = ''
self.preview_widget.change_slide(self.slideList[matches[0]])
self.preview_widget.change_slide(self.slide_list[matches[0]])
self.slide_selected()
elif sender_name != 'shortcutTimer':
elif sender_name != 'shortcut_timer':
# Start the time as we did not have any match.
self.shortcutTimer.start(350)
self.shortcut_timer.start(350)
else:
# The timer timed out.
if self.current_shortcut in keys:
# We had more than one match for example "V1" and "V10", but
# "V1" was the slide we wanted to go.
self.preview_widget.change_slide(self.slideList[self.current_shortcut])
self.preview_widget.change_slide(self.slide_list[self.current_shortcut])
self.slide_selected()
# Reset the shortcut.
self.current_shortcut = ''
def set_live_hotkeys(self, parent=None):
def set_live_hot_keys(self, parent=None):
"""
Set the live hotkeys
"""
self.previousService = create_action(parent, 'previousService',
text=translate('OpenLP.SlideController', 'Previous Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.service_previous)
self.nextService = create_action(parent, 'nextService',
text=translate('OpenLP.SlideController', 'Next Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.service_next)
self.escapeItem = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.live_escape)
self.previous_service = create_action(parent, 'previousService',
text=translate('OpenLP.SlideController', 'Previous Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.service_previous)
self.next_service = create_action(parent, 'nextService',
text=translate('OpenLP.SlideController', 'Next Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.service_next)
self.escape_item = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.live_escape)
def live_escape(self):
"""
@ -502,10 +503,10 @@ class SlideController(DisplayController):
if self.keypress_queue:
while len(self.keypress_queue) and not self.keypress_loop:
self.keypress_loop = True
keypressCommand = self.keypress_queue.popleft()
if keypressCommand == ServiceItemAction.Previous:
keypress_command = self.keypress_queue.popleft()
if keypress_command == ServiceItemAction.Previous:
self.service_manager.previous_item()
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
elif keypress_command == ServiceItemAction.PreviousLastSlide:
# Go to the last slide of the previous item
self.service_manager.previous_item(last_slide=True)
else:
@ -535,7 +536,7 @@ class SlideController(DisplayController):
self.preview_display.setup()
service_item = ServiceItem()
self.preview_display.web_view.setHtml(build_html(service_item, self.preview_display.screen, None, self.is_live,
plugins=self.plugin_manager.plugins))
plugins=self.plugin_manager.plugins))
self.media_controller.setup_display(self.preview_display, True)
if self.service_item:
self.refresh_service_item()
@ -545,9 +546,9 @@ class SlideController(DisplayController):
Add actions to the widget specified by `widget`
"""
widget.addActions([
self.previous_item, self.nextItem,
self.previousService, self.nextService,
self.escapeItem])
self.previous_item, self.next_item,
self.previous_service, self.next_service,
self.escape_item])
def preview_size_changed(self):
"""
@ -579,19 +580,19 @@ class SlideController(DisplayController):
used_space = self.toolbar.size().width() + self.hide_menu.size().width()
# Add the threshold to prevent flickering.
if width > used_space + HIDE_MENU_THRESHOLD and self.hide_menu.isVisible():
self.toolbar.set_widget_visible(self.narrow_menu, False)
self.toolbar.set_widget_visible(self.wide_menu)
self.toolbar.set_widget_visible(NARROW_MENU, False)
self.toolbar.set_widget_visible(WIDE_MENU)
# Take away a threshold to prevent flickering.
elif width < used_space - HIDE_MENU_THRESHOLD and not self.hide_menu.isVisible():
self.toolbar.set_widget_visible(self.wide_menu, False)
self.toolbar.set_widget_visible(self.narrow_menu)
self.toolbar.set_widget_visible(WIDE_MENU, False)
self.toolbar.set_widget_visible(NARROW_MENU)
def on_song_bar_handler(self):
"""
Some song handler
"""
request = self.sender().text()
slide_no = self.slideList[request]
slide_no = self.slide_list[request]
width = self.main_window.control_splitter.sizes()[self.split]
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
self.slide_selected()
@ -626,7 +627,7 @@ class SlideController(DisplayController):
self.toolbar.hide()
self.mediabar.hide()
self.song_menu.hide()
self.toolbar.set_widget_visible(self.loop_list, False)
self.toolbar.set_widget_visible(LOOP_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
# Reset the button
self.play_slides_once.setChecked(False)
@ -634,14 +635,14 @@ class SlideController(DisplayController):
self.play_slides_loop.setChecked(False)
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
if item.is_text():
if Settings().value(self.main_window.songs_settings_section + '/display songbar') and self.slideList:
if Settings().value(self.main_window.songs_settings_section + '/display songbar') and self.slide_list:
self.toolbar.set_widget_visible(['song_menu'], True)
if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1:
self.toolbar.set_widget_visible(self.loop_list)
self.toolbar.set_widget_visible(LOOP_LIST)
if item.is_media():
self.mediabar.show()
self.previous_item.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
self.next_item.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
@ -660,7 +661,7 @@ class SlideController(DisplayController):
elif item.is_media():
self.mediabar.show()
self.previous_item.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
self.next_item.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
@ -669,7 +670,6 @@ class SlideController(DisplayController):
"""
Method to update the service item if the screen has changed
"""
log.debug('refresh_service_item live = %s' % self.is_live)
if self.service_item.is_text() or self.service_item.is_image():
item = self.service_item
item.render()
@ -680,7 +680,6 @@ class SlideController(DisplayController):
Method to install the service item into the controller
Called by plugins
"""
log.debug('add_service_item live = %s' % self.is_live)
item.render()
slide_no = 0
if self.song_edit:
@ -700,18 +699,17 @@ class SlideController(DisplayController):
Method to install the service item into the controller and request the correct toolbar for the plugin. Called by
:class:`~openlp.core.ui.ServiceManager`
"""
log.debug('add_service_manager_item live = %s' % self.is_live)
# If no valid slide number is specified we take the first one, but we remember the initial value to see if we
# should reload the song or not
slidenum = slide_no
slide_num = slide_no
if slide_no == -1:
slidenum = 0
slide_num = 0
# If service item is the same as the current one, only change slide
if slide_no >= 0 and item == self.service_item:
self.preview_widget.change_slide(slidenum)
self.preview_widget.change_slide(slide_num)
self.slide_selected()
else:
self._process_item(item, slidenum)
self._process_item(item, slide_num)
if self.is_live and item.auto_play_slides_loop and item.timed_slide_interval > 0:
self.play_slides_loop.setChecked(item.auto_play_slides_loop)
self.delay_spin_box.setValue(int(item.timed_slide_interval))
@ -721,11 +719,10 @@ class SlideController(DisplayController):
self.delay_spin_box.setValue(int(item.timed_slide_interval))
self.on_play_slides_once()
def _process_item(self, service_item, slideno):
def _process_item(self, service_item, slide_no):
"""
Loads a ServiceItem into the system from ServiceManager. Display the slide number passed.
"""
log.debug('processManagerItem live = %s' % self.is_live)
self.on_stop_loop()
old_item = self.service_item
# take a copy not a link to the servicemanager copy.
@ -733,8 +730,8 @@ class SlideController(DisplayController):
if old_item and self.is_live and old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
self._reset_blank()
Registry().execute(
'%s_start' % service_item.name.lower(), [service_item, self.is_live, self.hide_mode(), slideno])
self.slideList = {}
'%s_start' % service_item.name.lower(), [service_item, self.is_live, self.hide_mode(), slide_no])
self.slide_list = {}
if self.is_live:
self.song_menu.menu().clear()
self.display.audio_player.reset()
@ -742,15 +739,15 @@ class SlideController(DisplayController):
self.audio_pause_item.setChecked(False)
# If the current item has background audio
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug('Starting to play...')
self.log_debug('Starting to play...')
self.display.audio_player.add_to_playlist(self.service_item.background_audio)
self.trackMenu.clear()
self.track_menu.clear()
for counter in range(len(self.service_item.background_audio)):
action = self.trackMenu.addAction(os.path.basename(self.service_item.background_audio[counter]))
action = self.track_menu.addAction(os.path.basename(self.service_item.background_audio[counter]))
action.setData(counter)
action.triggered.connect(self.on_track_triggered)
self.display.audio_player.repeat = Settings().value(
self.main_window.general_settings_section + '/audio repeat list')
self.display.audio_player.repeat = \
Settings().value(self.main_window.general_settings_section + '/audio repeat list')
if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
self.audio_pause_item.setChecked(True)
self.display.audio_player.pause()
@ -767,21 +764,21 @@ class SlideController(DisplayController):
verse_def = '%s%s' % (verse_def[0], verse_def[1:])
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
row = two_line_def
if verse_def not in self.slideList:
self.slideList[verse_def] = framenumber
if verse_def not in self.slide_list:
self.slide_list[verse_def] = framenumber
if self.is_live:
self.song_menu.menu().addAction(verse_def, self.on_song_bar_handler)
else:
row += 1
self.slideList[str(row)] = row - 1
self.slide_list[str(row)] = row - 1
else:
row += 1
self.slideList[str(row)] = row - 1
self.slide_list[str(row)] = row - 1
# If current slide set background to image
if not self.service_item.is_command() and framenumber == slideno:
self.service_item.bg_image_bytes = self.image_manager.get_image_bytes(frame['path'],
ImageSource.ImagePlugin)
self.preview_widget.replace_service_item(self.service_item, width, slideno)
if not self.service_item.is_command() and framenumber == slide_no:
self.service_item.bg_image_bytes = \
self.image_manager.get_image_bytes(frame['path'], ImageSource.ImagePlugin)
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
self.enable_tool_bar(service_item)
# Pass to display for viewing.
# Postpone image build, we need to do this later to avoid the theme
@ -821,7 +818,6 @@ class SlideController(DisplayController):
"""
Allow the main display to blank the main display at startup time
"""
log.debug('main_display_set_background live = %s' % self.is_live)
display_type = Settings().value(self.main_window.general_settings_section + '/screen blank')
if self.screens.which_screen(self.window()) != self.screens.which_screen(self.display):
# Order done to handle initial conversion
@ -854,7 +850,7 @@ class SlideController(DisplayController):
"""
if checked is None:
checked = self.blank_screen.isChecked()
log.debug('on_blank_display %s' % checked)
self.log_debug('on_blank_display %s' % checked)
self.hide_menu.setDefaultAction(self.blank_screen)
self.blank_screen.setChecked(checked)
self.theme_screen.setChecked(False)
@ -873,7 +869,7 @@ class SlideController(DisplayController):
"""
if checked is None:
checked = self.theme_screen.isChecked()
log.debug('on_theme_display %s' % checked)
self.log_debug('on_theme_display %s' % checked)
self.hide_menu.setDefaultAction(self.theme_screen)
self.blank_screen.setChecked(False)
self.theme_screen.setChecked(checked)
@ -892,7 +888,7 @@ class SlideController(DisplayController):
"""
if checked is None:
checked = self.desktop_screen.isChecked()
log.debug('on_hide_display %s' % checked)
self.log_debug('on_hide_display %s' % checked)
self.hide_menu.setDefaultAction(self.desktop_screen)
self.blank_screen.setChecked(False)
self.theme_screen.setChecked(False)
@ -910,13 +906,13 @@ class SlideController(DisplayController):
Blank/Hide the display screen within a plugin if required.
"""
hide_mode = self.hide_mode()
log.debug('blank_plugin %s ', hide_mode)
self.log_debug('blank_plugin %s ' % hide_mode)
if self.service_item is not None:
if hide_mode:
if not self.service_item.is_command():
Registry().execute('live_display_hide', hide_mode)
Registry().execute('%s_blank' % self.service_item.name.lower(),
[self.service_item, self.is_live, hide_mode])
Registry().execute('%s_blank' %
self.service_item.name.lower(), [self.service_item, self.is_live, hide_mode])
else:
if not self.service_item.is_command():
Registry().execute('live_display_show')
@ -931,7 +927,7 @@ class SlideController(DisplayController):
"""
Tell the plugin to hide the display screen.
"""
log.debug('hide_plugin %s ', hide)
self.log_debug('hide_plugin %s ' % hide)
if self.service_item is not None:
if hide:
Registry().execute('live_display_hide', HideMode.Screen)
@ -946,9 +942,10 @@ class SlideController(DisplayController):
else:
Registry().execute('live_display_show')
def on_slide_selected(self):
def on_slide_selected(self, field=None):
"""
Slide selected in controller
Note for some reason a dummy field is required. Nothing is passed!
"""
self.slide_selected()
@ -962,8 +959,8 @@ class SlideController(DisplayController):
if -1 < row < self.preview_widget.slide_count():
if self.service_item.is_command():
if self.is_live and not start:
Registry().execute('%s_slide' % self.service_item.name.lower(),
[self.service_item, self.is_live, row])
Registry().execute('%s_slide' %
self.service_item.name.lower(), [self.service_item, self.is_live, row])
else:
to_display = self.service_item.get_rendered_frame(row)
if self.service_item.is_text():
@ -993,7 +990,7 @@ class SlideController(DisplayController):
"""
This updates the preview frame, for example after changing a slide or using *Blank to Theme*.
"""
log.debug('update_preview %s ' % self.screens.current['primary'])
self.log_debug('update_preview %s ' % self.screens.current['primary'])
if not self.screens.current['primary'] and self.service_item and \
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
# Grab now, but try again in a couple of seconds if slide change is slow
@ -1048,7 +1045,7 @@ class SlideController(DisplayController):
self.preview_widget.change_slide(row)
self.slide_selected()
def on_slide_selected_previous(self):
def on_slide_selected_previous(self, field=None):
"""
Go to the previous slide.
"""
@ -1104,7 +1101,7 @@ class SlideController(DisplayController):
checked = self.play_slides_loop.isChecked()
else:
self.play_slides_loop.setChecked(checked)
log.debug('on_play_slides_loop %s' % checked)
self.log_debug('on_play_slides_loop %s' % checked)
if checked:
self.play_slides_loop.setIcon(build_icon(':/media/media_stop.png'))
self.play_slides_loop.setText(UiStrings().StopPlaySlidesInLoop)
@ -1125,7 +1122,7 @@ class SlideController(DisplayController):
checked = self.play_slides_once.isChecked()
else:
self.play_slides_once.setChecked(checked)
log.debug('on_play_slides_once %s' % checked)
self.log_debug('on_play_slides_once %s' % checked)
if checked:
self.play_slides_once.setIcon(build_icon(':/media/media_stop.png'))
self.play_slides_once.setText(UiStrings().StopPlaySlidesToEnd)
@ -1142,7 +1139,7 @@ class SlideController(DisplayController):
"""
Set the visibility of the audio stuff
"""
self.toolbar.set_widget_visible(self.audio_list, visible)
self.toolbar.set_widget_visible(AUDIO_LIST, visible)
def set_audio_pause_clicked(self, checked):
"""
@ -1206,7 +1203,6 @@ class SlideController(DisplayController):
"""
Respond to the arrival of a media service item
"""
log.debug('SlideController on_media_start')
self.media_controller.video(self.controller_type, item, self.hide_mode())
if not self.is_live:
self.preview_display.show()
@ -1216,7 +1212,6 @@ class SlideController(DisplayController):
"""
Respond to a request to close the Video
"""
log.debug('SlideController on_media_close')
self.media_controller.media_reset(self)
self.preview_display.hide()
self.slide_preview.show()
@ -1333,3 +1328,46 @@ class SlideController(DisplayController):
main_window = property(_get_main_window)
class PreviewController(RegistryMixin, OpenLPMixin, SlideController):
"""
Set up the Live Controller.
"""
def __init__(self, parent):
"""
Set up the general Controller.
"""
super(PreviewController, self).__init__(parent)
self.split = 0
self.type_prefix = 'preview'
self.category = None
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
"""
self.post_set_up()
class LiveController(RegistryMixin, OpenLPMixin, SlideController):
"""
Set up the Live Controller.
"""
def __init__(self, parent):
"""
Set up the general Controller.
"""
super(LiveController, self).__init__(parent)
self.is_live = True
self.split = 1
self.type_prefix = 'live'
self.keypress_queue = deque()
self.keypress_loop = False
self.category = UiStrings().LiveToolbar
ActionList.get_instance().add_category(str(self.category), CategoryOrder.standard_toolbar)
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
"""
self.post_set_up()

View File

@ -33,8 +33,7 @@ from PyQt4 import QtGui
from .starttimedialog import Ui_StartTimeDialog
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib.ui import critical_error_message_box

View File

@ -34,8 +34,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ThemeLayoutForm

View File

@ -32,23 +32,21 @@ The Theme Manager manages adding, deleteing and modifying of themes.
import os
import zipfile
import shutil
import logging
from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.lib import FileDialog, ImageSource, OpenLPToolbar, Registry, get_text_file_string, build_icon, \
from openlp.core.common import Registry, AppLocation, Settings, OpenLPMixin, RegistryMixin, check_directory_exists, \
UiStrings, translate
from openlp.core.lib import FileDialog, ImageSource, OpenLPToolbar, get_text_file_string, build_icon, \
check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.theme import ThemeXML, BackgroundType
from openlp.core.lib.ui import critical_error_message_box, create_widget_action
from openlp.core.ui import FileRenameForm, ThemeForm, ThemeManagerHelper
from openlp.core.utils import delete_file, get_locale_key, get_filesystem_encoding
log = logging.getLogger(__name__)
class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
class ThemeManager(RegistryMixin, OpenLPMixin, QtGui.QWidget, ThemeManagerHelper):
"""
Manages the orders of Theme.
"""
@ -57,9 +55,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Constructor
"""
super(ThemeManager, self).__init__(parent)
Registry().register('theme_manager', self)
Registry().register_function('bootstrap_initialise', self.initialise)
Registry().register_function('bootstrap_post_set_up', self._push_themes)
self.settings_section = 'themes'
self.theme_form = ThemeForm(self)
self.file_rename_form = FileRenameForm()
@ -71,30 +66,32 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.toolbar = OpenLPToolbar(self)
self.toolbar.setObjectName('toolbar')
self.toolbar.add_toolbar_action('newTheme',
text=UiStrings().NewTheme, icon=':/themes/theme_new.png',
tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
triggers=self.on_add_theme)
text=UiStrings().NewTheme, icon=':/themes/theme_new.png',
tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
triggers=self.on_add_theme)
self.toolbar.add_toolbar_action('editTheme',
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
icon=':/themes/theme_edit.png',
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
triggers=self.on_edit_theme)
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
icon=':/themes/theme_edit.png',
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
triggers=self.on_edit_theme)
self.delete_toolbar_action = self.toolbar.add_toolbar_action('delete_theme',
text=translate('OpenLP.ThemeManager', 'Delete Theme'),
icon=':/general/general_delete.png',
tooltip=translate('OpenLP.ThemeManager', 'Delete a theme.'),
triggers=self.on_delete_theme)
text=translate('OpenLP.ThemeManager',
'Delete Theme'),
icon=':/general/general_delete.png',
tooltip=translate('OpenLP.ThemeManager',
'Delete a theme.'),
triggers=self.on_delete_theme)
self.toolbar.addSeparator()
self.toolbar.add_toolbar_action('importTheme',
text=translate('OpenLP.ThemeManager', 'Import Theme'),
icon=':/general/general_import.png',
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
triggers=self.on_import_theme)
text=translate('OpenLP.ThemeManager', 'Import Theme'),
icon=':/general/general_import.png',
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
triggers=self.on_import_theme)
self.toolbar.add_toolbar_action('exportTheme',
text=translate('OpenLP.ThemeManager', 'Export Theme'),
icon=':/general/general_export.png',
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
triggers=self.on_export_theme)
text=translate('OpenLP.ThemeManager', 'Export Theme'),
icon=':/general/general_export.png',
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
triggers=self.on_export_theme)
self.layout.addWidget(self.toolbar)
self.theme_widget = QtGui.QWidgetAction(self.toolbar)
self.theme_widget.setObjectName('theme_widget')
@ -109,25 +106,25 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
# build the context menu
self.menu = QtGui.QMenu()
self.edit_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_edit_theme)
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_edit_theme)
self.copy_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_copy_theme)
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_copy_theme)
self.rename_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_rename_theme)
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
icon=':/themes/theme_edit.png', triggers=self.on_rename_theme)
self.delete_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
icon=':/general/general_delete.png', triggers=self.on_delete_theme)
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
icon=':/general/general_delete.png', triggers=self.on_delete_theme)
self.menu.addSeparator()
self.global_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
icon=':/general/general_export.png',
triggers=self.change_global_from_screen)
self.exportAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Export Theme'),
icon=':/general/general_export.png', triggers=self.on_export_theme)
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
icon=':/general/general_export.png',
triggers=self.change_global_from_screen)
self.export_action = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Export Theme'),
icon=':/general/general_export.png', triggers=self.on_export_theme)
# Signals
self.theme_list_widget.doubleClicked.connect(self.change_global_from_screen)
self.theme_list_widget.currentItemChanged.connect(self.check_list_state)
@ -136,9 +133,25 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.theme_list = []
self.old_background_image = None
def check_list_state(self, item):
def bootstrap_initialise(self):
"""
process the bootstrap initialise setup request
"""
self.log_debug('initialise called')
self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path()
self.load_first_time_themes()
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
"""
self._push_themes()
def check_list_state(self, item, field=None):
"""
If Default theme selected remove delete button.
Note for some reason a dummy field is required. Nothing is passed!
"""
if item is None:
return
@ -171,7 +184,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Change the global theme when it is changed through the Themes settings tab
"""
self.global_theme = Settings().value(self.settings_section + '/global theme')
log.debug('change_global_from_tab %s', self.global_theme)
self.log_debug('change_global_from_tab %s' % self.global_theme)
for count in range(0, self.theme_list_widget.count()):
# reset the old name
item = self.theme_list_widget.item(count)
@ -190,7 +203,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Change the global theme when a theme is double clicked upon in the
Theme Manager list
"""
log.debug('change_global_from_screen %s', index)
selected_row = self.theme_list_widget.currentRow()
for count in range(0, self.theme_list_widget.count()):
item = self.theme_list_widget.item(count)
@ -207,7 +219,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Registry().execute('theme_update_global')
self._push_themes()
def on_add_theme(self):
def on_add_theme(self, field=None):
"""
Loads a new theme with the default settings and then launches the theme
editing form for the user to make their customisations.
@ -218,13 +230,13 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.theme_form.exec_()
self.load_themes()
def on_rename_theme(self):
def on_rename_theme(self, field=None):
"""
Renames an existing theme to a new name
"""
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to rename.'),
translate('OpenLP.ThemeManager', 'Rename Confirmation'),
translate('OpenLP.ThemeManager', 'Rename %s theme?'), False, False):
translate('OpenLP.ThemeManager', 'Rename Confirmation'),
translate('OpenLP.ThemeManager', 'Rename %s theme?'), False, False):
item = self.theme_list_widget.currentItem()
old_theme_name = item.data(QtCore.Qt.UserRole)
self.file_rename_form.file_name_edit.setText(old_theme_name)
@ -242,14 +254,14 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.renderer.update_theme(new_theme_name, old_theme_name)
self.load_themes()
def on_copy_theme(self):
def on_copy_theme(self, field=None):
"""
Copies an existing theme to a new name
"""
item = self.theme_list_widget.currentItem()
old_theme_name = item.data(QtCore.Qt.UserRole)
self.file_rename_form.file_name_edit.setText(translate('OpenLP.ThemeManager',
'Copy of %s', 'Copy of <theme name>') % old_theme_name)
'Copy of %s', 'Copy of <theme name>') % old_theme_name)
if self.file_rename_form.exec_(True):
new_theme_name = self.file_rename_form.file_name_edit.text()
if self.check_if_theme_exists(new_theme_name):
@ -260,7 +272,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
"""
Takes a theme and makes a new copy of it as well as saving it.
"""
log.debug('clone_theme_data')
save_to = None
save_from = None
if theme_data.background_type == 'image':
@ -271,13 +282,13 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.save_theme(theme_data, save_from, save_to)
self.load_themes()
def on_edit_theme(self):
def on_edit_theme(self, field=None):
"""
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.theme_list_widget,
translate('OpenLP.ThemeManager', 'You must select a theme to edit.')):
translate('OpenLP.ThemeManager', 'You must select a theme to edit.')):
item = self.theme_list_widget.currentItem()
theme = self.get_theme_data(item.data(QtCore.Qt.UserRole))
if theme.background_type == 'image':
@ -288,13 +299,13 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.renderer.update_theme(theme.theme_name)
self.load_themes()
def on_delete_theme(self):
def on_delete_theme(self, field=None):
"""
Delete a theme
"""
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to delete.'),
translate('OpenLP.ThemeManager', 'Delete Confirmation'),
translate('OpenLP.ThemeManager', 'Delete %s theme?')):
translate('OpenLP.ThemeManager', 'Delete Confirmation'),
translate('OpenLP.ThemeManager', 'Delete %s theme?')):
item = self.theme_list_widget.currentItem()
theme = item.text()
row = self.theme_list_widget.row(item)
@ -321,9 +332,9 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
except OSError as os_error:
shutil.Error = os_error
log.exception('Error deleting theme %s', theme)
self.log_exception('Error deleting theme %s', theme)
def on_export_theme(self):
def on_export_theme(self, field=None):
"""
Export the theme in a zip file
"""
@ -333,8 +344,9 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
return
theme = item.data(QtCore.Qt.UserRole)
path = QtGui.QFileDialog.getExistingDirectory(self,
translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme,
Settings().value(self.settings_section + '/last directory export'))
translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme,
Settings().value(self.settings_section +
'/last directory export'))
self.application.set_busy_cursor()
if path:
Settings().setValue(self.settings_section + '/last directory export', path)
@ -349,27 +361,29 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
os.path.join(source, name).encode('utf-8'), os.path.join(theme, name).encode('utf-8')
)
QtGui.QMessageBox.information(self,
translate('OpenLP.ThemeManager', 'Theme Exported'),
translate('OpenLP.ThemeManager', 'Your theme has been successfully exported.'))
translate('OpenLP.ThemeManager', 'Theme Exported'),
translate('OpenLP.ThemeManager',
'Your theme has been successfully exported.'))
except (IOError, OSError):
log.exception('Export Theme Failed')
self.log_exception('Export Theme Failed')
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
translate('OpenLP.ThemeManager', 'Your theme could not be exported due to an error.'))
translate('OpenLP.ThemeManager',
'Your theme could not be exported due to an error.'))
finally:
if theme_zip:
theme_zip.close()
self.application.set_normal_cursor()
def on_import_theme(self):
def on_import_theme(self, field=None):
"""
Opens a file dialog to select the theme file(s) to import before attempting to extract OpenLP themes from
those files. This process will load both OpenLP version 1 and version 2 themes.
"""
files = FileDialog.getOpenFileNames(self,
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
Settings().value(self.settings_section + '/last directory import'),
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.theme *.otz)'))
log.info('New Themes %s', str(files))
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
Settings().value(self.settings_section + '/last directory import'),
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.theme *.otz)'))
self.log_info('New Themes %s' % str(files))
if not files:
return
self.application.set_busy_cursor()
@ -383,7 +397,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
"""
Imports any themes on start up and makes sure there is at least one theme
"""
log.debug('load_first_time_themes called')
self.application.set_busy_cursor()
files = AppLocation.get_files(self.settings_section, '.otz')
for theme_file in files:
@ -406,7 +419,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
events for the plugins.
The plugins will call back in to get the real list if they want it.
"""
log.debug('Load themes from dir')
self.theme_list = []
self.theme_list_widget.clear()
files = AppLocation.get_files(self.settings_section, '.png')
@ -444,7 +456,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
"""
Return the list of loaded themes
"""
log.debug('get themes')
return self.theme_list
def get_theme_data(self, theme_name):
@ -454,11 +465,11 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
``theme_name``
Name of the theme to load from file
"""
log.debug('get theme data for theme %s', theme_name)
self.log_debug('get theme data for theme %s' % theme_name)
xml_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.xml')
xml = get_text_file_string(xml_file)
if not xml:
log.debug('No theme data - using default theme')
self.log_debug('No theme data - using default theme')
return ThemeXML()
else:
return self._create_theme_from_Xml(xml, self.path)
@ -468,10 +479,12 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Display a warning box to the user that a theme already exists
"""
ret = QtGui.QMessageBox.question(self, translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?').replace('%s', theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?')
.replace('%s', theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
return ret == QtGui.QMessageBox.Yes
def unzip_theme(self, file_name, directory):
@ -480,7 +493,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Generate a new preview file. Check the XML theme version and upgrade if
necessary.
"""
log.debug('Unzipping theme %s', file_name)
self.log_debug('Unzipping theme %s', file_name)
file_name = str(file_name)
theme_zip = None
out_file = None
@ -490,7 +503,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
theme_zip = zipfile.ZipFile(file_name)
xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
if len(xml_file) != 1:
log.exception('Theme contains "%s" XML files' % len(xml_file))
self.log_error('Theme contains "%s" XML files' % len(xml_file))
raise Exception('validation')
xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
theme_name = xml_tree.find('name').text.strip()
@ -518,12 +531,12 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
out_file.write(theme_zip.read(name))
out_file.close()
except (IOError, zipfile.BadZipfile):
log.exception('Importing theme from zip failed %s' % file_name)
self.log_exception('Importing theme from zip failed %s' % file_name)
raise Exception('validation')
except Exception as info:
if str(info) == 'validation':
critical_error_message_box(translate('OpenLP.ThemeManager',
'Validation Error'), translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
else:
raise
finally:
@ -543,7 +556,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
log.exception('Theme file does not contain XML data %s' % file_name)
self.log_error('Theme file does not contain XML data %s' % file_name)
def check_if_theme_exists(self, theme_name):
"""
@ -562,23 +575,21 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
def save_theme(self, theme, image_from, image_to):
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
Called by thememaintenance Dialog to save the theme and to trigger the reload of the theme list
"""
self._write_theme(theme, image_from, image_to)
if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
self.image_manager.update_image_border(theme.background_filename,
ImageSource.Theme, QtGui.QColor(theme.background_border_color))
ImageSource.Theme,
QtGui.QColor(theme.background_border_color))
self.image_manager.process_updates()
def _write_theme(self, theme, image_from, image_to):
"""
Writes the theme to the disk and handles the background image if
necessary
Writes the theme to the disk and handles the background image if necessary
"""
name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
log.debug('save_theme %s %s', name, theme_pretty_xml.decode('utf-8'))
theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + '.xml')
@ -589,7 +600,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
out_file = open(theme_file, 'w')
out_file.write(theme_pretty_xml.decode('UTF-8'))
except IOError:
log.exception('Saving theme to file failed')
self.log_exception('Saving theme to file failed')
finally:
if out_file:
out_file.close()
@ -599,14 +610,13 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
shutil.copyfile(str(image_from).encode(encoding), str(image_to).encode(encoding))
except IOError as xxx_todo_changeme:
shutil.Error = xxx_todo_changeme
log.exception('Failed to save theme image')
self.log_exception('Failed to save theme image')
self.generate_and_save_image(self.path, name, theme)
def generate_and_save_image(self, directory, name, theme):
"""
Generate and save a preview image
"""
log.debug('generate_and_save_image %s %s', directory, name)
frame = self.generate_image(theme)
sample_path_name = os.path.join(self.path, name + '.png')
if os.path.exists(sample_path_name):
@ -614,13 +624,11 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
frame.save(sample_path_name, 'png')
thumb = os.path.join(self.thumb_path, '%s.png' % name)
create_thumb(sample_path_name, thumb, False)
log.debug('Theme image written to %s', sample_path_name)
def update_preview_images(self):
"""
Called to update the themes' preview images.
"""
log.debug('update_preview_images')
self.main_window.display_progress_bar(len(self.theme_list))
for theme in self.theme_list:
self.main_window.increment_progress_bar()
@ -638,7 +646,6 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
``force_page``
Flag to tell message lines per page need to be generated.
"""
log.debug('generate_image \n%s ', theme_data)
return self.renderer.generate_preview(theme_data, force_page)
def get_preview_image(self, theme):
@ -648,9 +655,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
``theme``
The theme to return the image for
"""
log.debug('get_preview_image %s ', theme)
image = os.path.join(self.path, theme + '.png')
return image
return os.path.join(self.path, theme + '.png')
def _create_theme_from_Xml(self, theme_xml, path):
"""
@ -666,8 +671,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
def _validate_theme_action(self, select_text, confirm_title, confirm_text, test_plugin=True, confirm=True):
"""
Check to see if theme has been selected and the destructive action
is allowed.
Check to see if theme has been selected and the destructive action is allowed.
"""
self.global_theme = Settings().value(self.settings_section + '/global theme')
if check_item_selected(self.theme_list_widget, select_text):
@ -676,8 +680,9 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
# confirm deletion
if confirm:
answer = QtGui.QMessageBox.question(self, confirm_title, confirm_text % theme,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
# should be the same unless default
@ -690,8 +695,9 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
for plugin in self.plugin_manager.plugins:
if plugin.uses_theme(theme):
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') %
(theme, plugin.name))
translate('OpenLP.ThemeManager',
'Theme %s is used in the %s plugin.')
% (theme, plugin.name))
return False
return True
return False

View File

@ -29,32 +29,20 @@
"""
The Theme Controller helps manages adding, deleteing and modifying of themes.
"""
import logging
import os
from openlp.core.common import AppLocation, Settings, check_directory_exists
log = logging.getLogger(__name__)
from openlp.core.common import AppLocation, check_directory_exists
class ThemeManagerHelper(object):
"""
Manages the non ui theme functions.
"""
def initialise(self):
"""
Setup the manager
"""
log.debug('initialise called')
self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path()
self.load_first_time_themes()
def build_theme_path(self):
"""
Set up the theme path variables
"""
log.debug('build theme path called')
self.log_debug('build theme path called')
self.path = AppLocation.get_section_data_path(self.settings_section)
check_directory_exists(self.path)
self.thumb_path = os.path.join(self.path, 'thumbnails')

View File

@ -33,8 +33,8 @@ The Themes configuration tab
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, ThemeLevel, UiStrings, translate
from openlp.core.lib import Registry, SettingsTab
from openlp.core.common import Registry, Settings, ThemeLevel, UiStrings, translate
from openlp.core.lib import SettingsTab
from openlp.core.lib.ui import find_and_set_in_combo_box

View File

@ -34,8 +34,8 @@ import os
from PyQt4 import QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, build_icon
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page
log = logging.getLogger(__name__)

View File

@ -44,8 +44,7 @@ from random import randint
from PyQt4 import QtGui, QtCore
from openlp.core.common import AppLocation, Settings
from openlp.core.lib import Registry
from openlp.core.common import Registry, AppLocation, Settings
if sys.platform != 'win32' and sys.platform != 'darwin':

View File

@ -35,8 +35,7 @@ import logging
from PyQt4 import QtCore
from openlp.core.common import translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, translate
log = logging.getLogger(__name__)

View File

@ -36,8 +36,7 @@ from tempfile import gettempdir
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, UiStrings, Settings, check_directory_exists, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, AppLocation, UiStrings, Settings, check_directory_exists, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.core.utils import delete_file

View File

@ -33,8 +33,7 @@ import re
from PyQt4 import QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib.ui import critical_error_message_box
from .editbibledialog import Ui_EditBibleDialog
from openlp.plugins.bibles.lib import BibleStrings

View File

@ -31,8 +31,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, SettingsTab
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import SettingsTab
from openlp.core.lib.ui import find_and_set_in_combo_box
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, update_reference_separators, \
get_reference_separator, LanguageSelection

View File

@ -93,7 +93,7 @@ class CSVBible(BibleDB):
success = True
language_id = self.get_language(bible_name)
if not language_id:
log.exception('Importing books from "%s" failed' % self.filename)
log.error('Importing books from "%s" failed' % self.filename)
return False
books_file = None
book_list = {}
@ -112,7 +112,7 @@ class CSVBible(BibleDB):
str(line[2], details['encoding']))
book_ref_id = self.get_book_ref_id_by_name(str(line[2], details['encoding']), 67, language_id)
if not book_ref_id:
log.exception('Importing books from "%s" failed' % self.booksfile)
log.error('Importing books from "%s" failed' % self.booksfile)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
self.create_book(str(line[2], details['encoding']), book_ref_id, book_details['testament_id'])

View File

@ -38,8 +38,7 @@ from sqlalchemy import Column, ForeignKey, Table, or_, types, func
from sqlalchemy.orm import class_mapper, mapper, relation
from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.common import AppLocation, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, AppLocation, translate
from openlp.core.lib.db import BaseModel, init_db, Manager
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import clean_filename

View File

@ -38,8 +38,7 @@ from html.parser import HTMLParseError
from bs4 import BeautifulSoup, NavigableString, Tag
from openlp.core.common import translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import get_web_page
from openlp.plugins.bibles.lib import SearchResults
@ -553,7 +552,7 @@ class HTTPBible(BibleDB):
handler = BSExtract(self.proxy_server)
books = handler.get_books_from_http(self.download_name)
if not books:
log.exception('Importing books from %s - download name: "%s" '\
log.error('Importing books from %s - download name: "%s" '\
'failed' % (self.download_source, self.download_name))
return False
self.wizard.progress_bar.setMaximum(len(books) + 2)
@ -565,7 +564,7 @@ class HTTPBible(BibleDB):
else:
language_id = self.get_language(bible_name)
if not language_id:
log.exception('Importing books from %s failed' % self.filename)
log.error('Importing books from %s failed' % self.filename)
return False
for book in books:
if self.stop_import_flag:
@ -574,7 +573,7 @@ class HTTPBible(BibleDB):
'BiblesPlugin.HTTPBible', 'Importing %s...', 'Importing <book name>...') % book)
book_ref_id = self.get_book_ref_id_by_name(book, len(books), language_id)
if not book_ref_id:
log.exception('Importing books from %s - download name: "%s" '\
log.error('Importing books from %s - download name: "%s" '\
'failed' % (self.download_source, self.download_name))
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)

View File

@ -30,8 +30,7 @@
import logging
import os
from openlp.core.common import AppLocation, Settings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, AppLocation, Settings, translate
from openlp.core.utils import delete_file
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta

View File

@ -31,8 +31,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, ServiceItemContext, create_separated_list
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext, create_separated_list
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \
critical_error_message_box, find_and_set_in_combo_box, build_icon

View File

@ -84,14 +84,14 @@ class OpenSongBible(BibleDB):
bible = opensong.getroot()
language_id = self.get_language(bible_name)
if not language_id:
log.exception('Importing books from "%s" failed' % self.filename)
log.error('Importing books from "%s" failed' % self.filename)
return False
for book in bible.b:
if self.stop_import_flag:
break
book_ref_id = self.get_book_ref_id_by_name(str(book.attrib['n']), len(bible.b), language_id)
if not book_ref_id:
log.exception('Importing books from "%s" failed' % self.filename)
log.error('Importing books from "%s" failed' % self.filename)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
db_book = self.create_book(str(book.attrib['n']), book_ref_id, book_details['testament_id'])

View File

@ -131,7 +131,7 @@ class OSISBible(BibleDB):
if not language_id:
language_id = self.get_language(bible_name)
if not language_id:
log.exception('Importing books from "%s" failed' % self.filename)
log.error('Importing books from "%s" failed' % self.filename)
return False
match_count += 1
book = str(match.group(1))
@ -140,7 +140,7 @@ class OSISBible(BibleDB):
verse_text = match.group(4)
book_ref_id = self.get_book_ref_id_by_name(book, book_count, language_id)
if not book_ref_id:
log.exception('Importing books from "%s" failed' % self.filename)
log.error('Importing books from "%s" failed' % self.filename)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
if not db_book or db_book.name != book_details['name']:

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtGui
from openlp.core.lib import Registry, translate
from openlp.core.common import Registry, translate
from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide

View File

@ -32,9 +32,9 @@ import logging
from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_, func, and_
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus, \
check_item_selected
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus,\
check_item_selected
from openlp.plugins.custom.forms.editcustomform import EditCustomForm
from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder
from openlp.plugins.custom.lib.db import CustomSlide

View File

@ -31,8 +31,8 @@ from PyQt4 import QtGui
import logging
from openlp.core.common import Settings, translate
from openlp.core.lib import Plugin, StringContent, Registry, ImageSource, build_icon
from openlp.core.common import Registry, Settings, translate
from openlp.core.lib import Plugin, StringContent, ImageSource, build_icon
from openlp.core.lib.db import Manager
from openlp.plugins.images.lib import ImageMediaItem, ImageTab
from openlp.plugins.images.lib.db import init_schema

View File

@ -32,9 +32,9 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, UiStrings, check_directory_exists, translate
from openlp.core.lib import ItemCapabilities, MediaManagerItem, Registry, ServiceItemContext, \
StringContent, TreeWidgetWithDnD, build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.common import Registry, AppLocation, Settings, UiStrings, check_directory_exists, translate
from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, TreeWidgetWithDnD,\
build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import create_widget_action, critical_error_message_box
from openlp.core.utils import delete_file, get_locale_key, get_images_filter
from openlp.plugins.images.forms import AddGroupForm, ChooseGroupForm

View File

@ -32,8 +32,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.lib import ItemCapabilities, MediaManagerItem,MediaType, Registry, ServiceItem, ServiceItemContext, \
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.lib import ItemCapabilities, MediaManagerItem,MediaType, ServiceItem, ServiceItemContext, \
build_icon, check_item_selected
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.ui import DisplayController, Display, DisplayControllerType

View File

@ -31,8 +31,8 @@ import logging
from PyQt4 import QtCore
from openlp.core.common import translate
from openlp.core.lib import Plugin, Registry, StringContent, build_icon
from openlp.core.common import Registry, translate
from openlp.core.lib import Plugin, StringContent, build_icon
from openlp.plugins.media.lib import MediaMediaItem, MediaTab

View File

@ -32,8 +32,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import MediaManagerItem, Registry, ItemCapabilities, ServiceItemContext,\
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext,\
build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.utils import get_locale_key

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtCore
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui import HideMode
log = logging.getLogger(__name__)

View File

@ -33,8 +33,8 @@ import shutil
from PyQt4 import QtCore
from openlp.core.common import AppLocation, Settings, check_directory_exists
from openlp.core.lib import Registry, create_thumb, validate_thumb
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists
from openlp.core.lib import create_thumb, validate_thumb
log = logging.getLogger(__name__)

View File

@ -124,8 +124,8 @@ from urllib.parse import urlparse, parse_qs
from mako.template import Template
from PyQt4 import QtCore
from openlp.core.common import AppLocation, Settings, translate
from openlp.core.lib import Registry, PluginStatus, StringContent, image_to_byte
from openlp.core.common import Registry, AppLocation, Settings, translate
from openlp.core.lib import PluginStatus, StringContent, image_to_byte
log = logging.getLogger(__name__)
FILE_TYPES = {

View File

@ -35,7 +35,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Registry, translate
from openlp.core.common import Registry, translate
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.plugins.songs.lib import delete_song
from openlp.plugins.songs.lib.db import Song, MediaFile

View File

@ -38,8 +38,8 @@ import shutil
from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, UiStrings, check_directory_exists, translate
from openlp.core.lib import FileDialog, Registry, PluginStatus, MediaType, create_separated_list
from openlp.core.common import Registry, AppLocation, UiStrings, check_directory_exists, translate
from openlp.core.lib import FileDialog, PluginStatus, MediaType, create_separated_list
from openlp.core.lib.ui import set_case_insensitive_completer, critical_error_message_box, find_and_set_in_combo_box
from openlp.plugins.songs.lib import VerseType, clean_song
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic, MediaFile

View File

@ -34,8 +34,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry, create_separated_list, build_icon
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib import create_separated_list, build_icon
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.plugins.songs.lib.db import Song

View File

@ -35,9 +35,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.common import Settings
from openlp.core.lib import FileDialog, Registry
from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import FileDialog
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.plugins.songs.lib.importer import SongFormat, SongFormatSelect

View File

@ -32,8 +32,7 @@ import os
from PyQt4 import QtGui, QtCore
from sqlalchemy.sql import and_
from openlp.core.common import UiStrings, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.songs.forms.authorsform import AuthorsForm
from openlp.plugins.songs.forms.topicsform import TopicsForm

View File

@ -35,8 +35,8 @@ import shutil
from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_
from openlp.core.common import AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.lib import MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \
check_item_selected, create_separated_list
from openlp.core.lib.ui import create_widget_action
from openlp.plugins.songs.forms.editsongform import EditSongForm

View File

@ -127,7 +127,7 @@ class OooImport(SongImport):
manager = uno_instance.ServiceManager
self.desktop = manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance)
return
raise
raise Exception('Unable to start LibreOffice')
def startOooProcess(self):
try:

View File

@ -35,8 +35,7 @@ import os
from lxml import etree
from openlp.core.common import check_directory_exists, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, check_directory_exists, translate
from openlp.core.utils import clean_filename
from openlp.plugins.songs.lib.xml import OpenLyrics

View File

@ -34,8 +34,7 @@ import os
from PyQt4 import QtCore
from openlp.core.common import AppLocation, check_directory_exists, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, AppLocation, check_directory_exists, translate
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile

View File

@ -29,8 +29,7 @@
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, translate
from openlp.plugins.songusage.lib.db import SongUsageItem
from .songusagedeletedialog import Ui_SongUsageDeleteDialog

View File

@ -33,8 +33,7 @@ import os
from PyQt4 import QtGui
from sqlalchemy.sql import and_
from openlp.core.common import Settings, check_directory_exists, translate
from openlp.core.lib import Registry
from openlp.core.common import Registry, Settings, check_directory_exists, translate
from openlp.plugins.songusage.lib.db import SongUsageItem
from .songusagedetaildialog import Ui_SongUsageDetailDialog

View File

@ -32,8 +32,8 @@ from datetime import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings, translate
from openlp.core.lib import Plugin, Registry, StringContent, build_icon
from openlp.core.common import Registry, Settings, translate
from openlp.core.lib import Plugin, StringContent, build_icon
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import create_action
from openlp.core.utils.actions import ActionList

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Functional tests to test the AppLocation class and related methods.
"""
from unittest import TestCase
from openlp.core.common import de_hump
class TestInitFunctions(TestCase):
"""
A test suite to test out various functions in the __init__ class.
"""
def de_hump_conversion_test(self):
"""
Test the de_hump function with a class name
"""
# GIVEN: a Class name in Camel Case
string = "MyClass"
# WHEN: we call de_hump
new_string = de_hump(string)
# THEN: the new string should be converted to python format
self.assertTrue(new_string == "my_class", 'The class name should have been converted')
def de_hump_static_test(self):
"""
Test the de_hump function with a python string
"""
# GIVEN: a Class name in Camel Case
string = "my_class"
# WHEN: we call de_hump
new_string = de_hump(string)
# THEN: the new string should be converted to python format
self.assertTrue(new_string == "my_class", 'The class name should have been preserved')

View File

@ -32,10 +32,10 @@ Package to test the openlp.core.lib package.
import os
from unittest import TestCase
from openlp.core.lib import Registry
from openlp.core.common import Registry
from tests.functional import MagicMock
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'resources'))
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../', '..', 'resources'))
class TestRegistry(TestCase):

View File

@ -34,7 +34,8 @@ import os
from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry, ImageManager, ScreenList
from openlp.core.common import Registry
from openlp.core.lib import ImageManager, ScreenList
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'resources'))

View File

@ -31,9 +31,9 @@ Package to test the openlp.core.lib.pluginmanager package.
"""
from unittest import TestCase
from openlp.core.common import Settings
from openlp.core.common import Registry, Settings
from openlp.core.lib.pluginmanager import PluginManager
from openlp.core.lib import Registry, PluginStatus
from openlp.core.lib import PluginStatus
from tests.functional import MagicMock

View File

@ -33,7 +33,8 @@ from unittest import TestCase
from PyQt4 import QtGui, QtCore
from openlp.core.lib import Registry, ScreenList
from openlp.core.common import Registry
from openlp.core.lib import ScreenList
from tests.functional import MagicMock
SCREEN = {

View File

@ -36,7 +36,8 @@ from unittest import TestCase
from tests.functional import MagicMock, patch
from tests.utils import assert_length, convert_file_service_item
from openlp.core.lib import ItemCapabilities, ServiceItem, Registry
from openlp.core.common import Registry
from openlp.core.lib import ItemCapabilities, ServiceItem
VERSE = 'The Lord said to {r}Noah{/r}: \n'\

View File

@ -31,7 +31,7 @@ This module contains tests for the lib submodule of the Images plugin.
"""
from unittest import TestCase
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
from openlp.plugins.images.lib.mediaitem import ImageMediaItem
from tests.functional import MagicMock, patch

View File

@ -33,7 +33,7 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem
from tests.functional import patch, MagicMock

View File

@ -7,8 +7,8 @@ from unittest import TestCase
from PyQt4 import QtCore, QtGui
from openlp.core.common import Settings
from openlp.core.lib import Registry, ServiceItem
from openlp.core.common import Registry, Settings
from openlp.core.lib import ServiceItem
from openlp.plugins.songs.lib.mediaitem import SongMediaItem
from tests.functional import patch, MagicMock

View File

@ -9,9 +9,8 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.common import Settings
from openlp.core.common import Registry, Settings
from openlp.core.lib.pluginmanager import PluginManager
from openlp.core.lib import Registry
from tests.interfaces import MagicMock

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui, QtTest
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui import filerenameform
from tests.interfaces import MagicMock, patch

View File

@ -6,7 +6,8 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry, ServiceItem
from openlp.core.common import Registry
from openlp.core.lib import ServiceItem
from openlp.core.ui import listpreviewwidget
from tests.interfaces import MagicMock, patch
from tests.utils.osdinteraction import read_service_from_file

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui.mainwindow import MainWindow
from tests.interfaces import MagicMock, patch

View File

@ -6,7 +6,8 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry, ScreenList, ServiceItem
from openlp.core.common import Registry
from openlp.core.lib import ScreenList, ServiceItem
from openlp.core.ui.mainwindow import MainWindow
from tests.interfaces import MagicMock, patch

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtCore, QtGui, QtTest
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui import servicenoteform
from tests.interfaces import patch

View File

@ -5,8 +5,9 @@ from unittest import TestCase
from PyQt4 import QtCore, QtTest, QtGui
from openlp.core.common import Registry
from openlp.core.ui import settingsform
from openlp.core.lib import Registry, ScreenList
from openlp.core.lib import ScreenList
from tests.interfaces import MagicMock, patch

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtCore, QtGui, QtTest
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.core.ui import starttimeform
from tests.interfaces import MagicMock, patch

View File

@ -3,7 +3,7 @@
"""
from unittest import TestCase
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.bibles.lib.http import BGExtract, CWExtract
from tests.interfaces import MagicMock

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui, QtTest, QtCore
from openlp.core.lib import Registry
from openlp.core.common import Registry
# Import needed due to import problems.
from openlp.plugins.custom.lib.mediaitem import CustomMediaItem
from openlp.plugins.custom.forms.editcustomform import EditCustomForm

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.custom.forms.editcustomslideform import EditCustomSlideForm
from tests.interfaces import MagicMock, patch

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.songs.forms.authorsform import AuthorsForm

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.core.common import Registry
from openlp.plugins.songs.forms.editsongform import EditSongForm
from tests.interfaces import MagicMock

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