diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index d5556d16e..04badb454 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -43,16 +43,14 @@ from traceback import format_exception from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, check_directory_exists -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import Receiver, Settings, check_directory_exists, ScreenList, UiStrings, Registry from openlp.core.resources import qInitResources from openlp.core.ui.mainwindow import MainWindow from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm from openlp.core.ui.firsttimeform import FirstTimeForm from openlp.core.ui.exceptionform import ExceptionForm -from openlp.core.ui import SplashScreen, ScreenList -from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \ - get_application_version +from openlp.core.ui import SplashScreen +from openlp.core.utils import AppLocation, LanguageManager, VersionThread, get_application_version __all__ = [u'OpenLP', u'main'] @@ -118,7 +116,7 @@ class OpenLP(QtGui.QApplication): # Decide how many screens we have and their size screens = ScreenList.create(self.desktop()) # First time checks in settings - has_run_wizard = Settings().value(u'general/has run wizard', False) + has_run_wizard = Settings().value(u'general/has run wizard') if not has_run_wizard: if FirstTimeForm(screens).exec_() == QtGui.QDialog.Accepted: Settings().setValue(u'general/has run wizard', True) @@ -129,7 +127,7 @@ class OpenLP(QtGui.QApplication): u'QTableWidget, QListWidget, QTreeWidget {alternate-background-color: ' + base_color.name() + ';}\n' application_stylesheet += nt_repair_stylesheet self.setStyleSheet(application_stylesheet) - show_splash = Settings().value(u'general/show splash', True) + show_splash = Settings().value(u'general/show splash') if show_splash: self.splash = SplashScreen() self.splash.show() @@ -148,7 +146,7 @@ class OpenLP(QtGui.QApplication): self.processEvents() if not has_run_wizard: self.mainWindow.firstTime() - update_check = Settings().value(u'general/update check', True) + update_check = Settings().value(u'general/update check') if update_check: VersionThread(self.mainWindow).start() Receiver.send_message(u'live_display_blank_check') @@ -213,7 +211,7 @@ def set_up_logging(log_path): """ Setup our logging using log_path """ - check_directory_exists(log_path) + check_directory_exists(log_path, True) filename = os.path.join(log_path, u'openlp.log') logfile = logging.FileHandler(filename, u'w') logfile.setFormatter(logging.Formatter(u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s')) @@ -243,12 +241,6 @@ def main(args=None): # Parse command line options and deal with them. # Use args supplied programatically if possible. (options, args) = parser.parse_args(args) if args else parser.parse_args() - if options.portable: - app_path = AppLocation.get_directory(AppLocation.AppDir) - set_up_logging(os.path.abspath(os.path.join(app_path, u'..', u'..', u'Other'))) - log.info(u'Running portable') - else: - set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) qt_args = [] if options.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) @@ -273,14 +265,16 @@ def main(args=None): app.setApplicationName(u'OpenLPPortable') Settings.setDefaultFormat(Settings.IniFormat) # Get location OpenLPPortable.ini + app_path = AppLocation.get_directory(AppLocation.AppDir) + set_up_logging(os.path.abspath(os.path.join(app_path, u'..', u'..', u'Other'))) + log.info(u'Running portable') portable_settings_file = os.path.abspath(os.path.join(app_path, u'..', u'..', u'Data', u'OpenLP.ini')) # Make this our settings file log.info(u'INI file: %s', portable_settings_file) - Settings.setFilename(portable_settings_file) + Settings.set_filename(portable_settings_file) portable_settings = Settings() # Set our data path - data_path = os.path.abspath(os.path.join(app_path, - u'..', u'..', u'Data',)) + data_path = os.path.abspath(os.path.join(app_path, u'..', u'..', u'Data',)) log.info(u'Data path: %s', data_path) # Point to our data path portable_settings.setValue(u'advanced/data path', data_path) @@ -288,6 +282,8 @@ def main(args=None): portable_settings.sync() else: app.setApplicationName(u'OpenLP') + set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) + registry = Registry.create() app.setApplicationVersion(get_application_version()[u'version']) # Instance check if not options.testing: @@ -295,7 +291,7 @@ def main(args=None): if app.isAlreadyRunning(): sys.exit() # First time checks in settings - if not Settings().value(u'general/has run wizard', False): + if not Settings().value(u'general/has run wizard'): if not FirstTimeLanguageForm().exec_(): # if cancel then stop processing sys.exit() diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index d0a5e9880..5cbfec11f 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -90,83 +90,6 @@ class ServiceItemAction(object): Next = 3 -class Settings(QtCore.QSettings): - """ - Class to wrap QSettings. - - * Exposes all the methods of QSettings. - * Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to - ``IniFormat``, and the path to the Ini file is set using ``setFilename``, - then the Settings constructor (without any arguments) will create a Settings - object for accessing settings stored in that Ini file. - """ - __filePath__ = u'' - - @staticmethod - def setFilename(iniFile): - """ - Sets the complete path to an Ini file to be used by Settings objects. - - Does not affect existing Settings objects. - """ - Settings.__filePath__ = iniFile - - def __init__(self, *args): - if not args and Settings.__filePath__ and \ - Settings.defaultFormat() == Settings.IniFormat: - QtCore.QSettings.__init__(self, Settings.__filePath__, Settings.IniFormat) - else: - QtCore.QSettings.__init__(self, *args) - - def value(self, key, defaultValue): - """ - Returns the value for the given ``key``. The returned ``value`` is - of the same type as the ``defaultValue``. - - ``key`` - The key to return the value from. - - ``defaultValue`` - The value to be returned if the given ``key`` is not present in the - config. Note, the ``defaultValue``'s type defines the type the - returned is converted to. In other words, if the ``defaultValue`` is - a boolean, then the returned value will be converted to a boolean. - - **Note**, this method only converts a few types and might need to be - extended if a certain type is missing! - """ - # Check for none as u'' is passed as default and is valid! This is - # needed because the settings export does not know the default values, - # thus just passes None. - if defaultValue is None and not super(Settings, self).contains(key): - return None - setting = super(Settings, self).value(key, defaultValue) - # On OS X (and probably on other platforms too) empty value from QSettings - # is represented as type PyQt4.QtCore.QPyNullVariant. This type has to be - # converted to proper 'None' Python type. - if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): - setting = None - # Handle 'None' type (empty value) properly. - if setting is None: - # An empty string saved to the settings results in a None type being - # returned. Convert it to empty unicode string. - if isinstance(defaultValue, unicode): - return u'' - # An empty list saved to the settings results in a None type being - # returned. - else: - return [] - # Convert the setting to the correct type. - if isinstance(defaultValue, bool): - if isinstance(setting, bool): - return setting - # Sometimes setting is string instead of a boolean. - return setting == u'true' - if isinstance(defaultValue, int): - return int(setting) - return setting - - def translate(context, text, comment=None, encoding=QtCore.QCoreApplication.CodecForTr, n=-1, translate=QtCore.QCoreApplication.translate): @@ -415,17 +338,21 @@ def expand_tags(text): return text -def check_directory_exists(dir): +def check_directory_exists(directory, do_not_log=False): """ Check a theme directory exists and if not create it - ``dir`` - Theme directory to make sure exists + ``directory`` + The directory to make sure exists + + ``do_not_log`` + To not log anything. This is need for the start up, when the log isn't ready. """ - log.debug(u'check_directory_exists %s' % dir) + if not do_not_log: + log.debug(u'check_directory_exists %s' % directory) try: - if not os.path.exists(dir): - os.makedirs(dir) + if not os.path.exists(directory): + os.makedirs(directory) except IOError: pass @@ -459,7 +386,11 @@ def create_separated_list(stringlist): u'Locale list separator: start') % (stringlist[0], merged) +from registry import Registry +from uistrings import UiStrings from eventreceiver import Receiver +from screen import ScreenList +from settings import Settings from listwidgetwithdnd import ListWidgetWithDnD from formattingtags import FormattingTags from spelltextedit import SpellTextEdit @@ -468,8 +399,7 @@ from plugin import PluginStatus, StringContent, Plugin from pluginmanager import PluginManager from settingstab import SettingsTab from serviceitem import ServiceItem, ServiceItemType, ItemCapabilities -from htmlbuilder import build_html, build_lyrics_format_css, \ - build_lyrics_outline_css +from htmlbuilder import build_html, build_lyrics_format_css, build_lyrics_outline_css from toolbar import OpenLPToolbar from dockwidget import OpenLPDockWidget from imagemanager import ImageManager diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index ce920d598..1e696a107 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -118,8 +118,7 @@ def upgrade_db(url, upgrade): session.commit() version += 1 else: - version_meta = Metadata.populate(key=u'version', - value=int(upgrade.__version__)) + version_meta = Metadata.populate(key=u'version', value=int(upgrade.__version__)) session.commit() return int(version_meta.value), upgrade.__version__ @@ -185,7 +184,7 @@ class Manager(object): self.db_url = u'' self.is_dirty = False self.session = None - db_type = settings.value(u'db type', u'sqlite') + db_type = settings.value(u'db type') if db_type == u'sqlite': if db_file_name: self.db_url = u'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name) @@ -193,12 +192,12 @@ class Manager(object): self.db_url = u'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name) else: self.db_url = u'%s://%s:%s@%s/%s' % (db_type, - urlquote(settings.value(u'db username', u'')), - urlquote(settings.value(u'db password', u'')), - urlquote(settings.value(u'db hostname', u'')), - urlquote(settings.value(u'db database', u''))) + urlquote(settings.value(u'db username')), + urlquote(settings.value(u'db password')), + urlquote(settings.value(u'db hostname')), + urlquote(settings.value(u'db database'))) if db_type == u'mysql': - db_encoding = settings.value(u'db encoding', u'utf8') + db_encoding = settings.value(u'db encoding') self.db_url += u'?charset=%s' % urlquote(db_encoding) settings.endGroup() if upgrade_mod: diff --git a/openlp/core/lib/dockwidget.py b/openlp/core/lib/dockwidget.py index fd938e6a5..1a19a538b 100644 --- a/openlp/core/lib/dockwidget.py +++ b/openlp/core/lib/dockwidget.py @@ -35,8 +35,7 @@ import logging from PyQt4 import QtGui -from openlp.core.lib import build_icon -from openlp.core.ui import ScreenList +from openlp.core.lib import build_icon, ScreenList log = logging.getLogger(__name__) diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index bd0403c8a..d29652c35 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -200,12 +200,6 @@ class EventReceiver(QtCore.QObject): ``{plugin}_unblank`` Requests a plugin to handle an unblank screen event. - ``{plugin}_edit`` - Requests a plugin edit a database item with the key as the payload. - - ``{plugin}_edit_clear`` - Editing has been completed. - ``{plugin}_load_list`` Tells the the plugin to reload the media manager list. diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py index eb52dc26f..df24775c8 100644 --- a/openlp/core/lib/formattingtags.py +++ b/openlp/core/lib/formattingtags.py @@ -162,7 +162,7 @@ class FormattingTags(object): FormattingTags.add_html_tags(temporary_tags) # Formatting Tags were also known as display tags. - user_expands = Settings().value(u'displayTags/html_tags', u'') + user_expands = Settings().value(u'displayTags/html_tags') # cPickle only accepts str not unicode strings user_expands_string = str(user_expands) if user_expands_string: diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 941818295..72389066b 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -39,8 +39,7 @@ import Queue from PyQt4 import QtCore -from openlp.core.lib import resize_image, image_to_byte, Receiver -from openlp.core.ui import ScreenList +from openlp.core.lib import resize_image, image_to_byte, Receiver, Registry, ScreenList log = logging.getLogger(__name__) @@ -183,6 +182,7 @@ class ImageManager(QtCore.QObject): def __init__(self): QtCore.QObject.__init__(self) + Registry().register(u'image_manager', self) currentScreen = ScreenList().current self.width = currentScreen[u'size'].width() self.height = currentScreen[u'size'].height() diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 55e1bb84b..33c0eb1d1 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -35,10 +35,11 @@ import re from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, \ - Receiver, ListWidgetWithDnD, ServiceItemContext, Settings +from openlp.core.lib import OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, Receiver, \ + ListWidgetWithDnD, ServiceItemContext, Settings, Registry, UiStrings from openlp.core.lib.searchedit import SearchEdit -from openlp.core.lib.ui import UiStrings, create_widget_action, critical_error_message_box +from openlp.core.lib.ui import create_widget_action, critical_error_message_box + log = logging.getLogger(__name__) @@ -98,6 +99,7 @@ class MediaManagerItem(QtGui.QWidget): self.plugin = plugin visible_title = self.plugin.getString(StringContent.VisibleName) self.title = unicode(visible_title[u'title']) + Registry().register(self.plugin.name, self) self.settingsSection = self.plugin.name self.icon = None if icon: @@ -327,7 +329,7 @@ class MediaManagerItem(QtGui.QWidget): Add a file to the list widget to make it available for showing """ files = QtGui.QFileDialog.getOpenFileNames(self, self.onNewPrompt, - SettingsManager.get_last_dir(self.settingsSection), self.onNewFileMasks) + Settings().value(self.settingsSection + u'/last directory'), self.onNewFileMasks) log.info(u'New files(s) %s', files) if files: Receiver.send_message(u'cursor_busy') @@ -336,8 +338,7 @@ class MediaManagerItem(QtGui.QWidget): def loadFile(self, files): """ - Turn file from Drag and Drop into an array so the Validate code - can run it. + Turn file from Drag and Drop into an array so the Validate code can run it. ``files`` The list of files to be loaded @@ -382,9 +383,8 @@ class MediaManagerItem(QtGui.QWidget): self.listView.clear() self.loadList(full_list) last_dir = os.path.split(unicode(files[0]))[0] - SettingsManager.set_last_dir(self.settingsSection, last_dir) - SettingsManager.set_list(self.settingsSection, - self.settingsSection, self.getFileList()) + Settings().setValue(self.settingsSection + u'/last directory', last_dir) + Settings().setValue(u'%s/%s files' % (self.settingsSection, self.settingsSection), self.getFileList()) if duplicates_found: critical_error_message_box(UiStrings().Duplicate, translate('OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.')) @@ -436,15 +436,15 @@ class MediaManagerItem(QtGui.QWidget): """ pass - def generateSlideData(self, serviceItem, item=None, xmlVersion=False, - remote=False, context=ServiceItemContext.Live): + def generateSlideData(self, serviceItem, item=None, xmlVersion=False, remote=False, + context=ServiceItemContext.Live): raise NotImplementedError(u'MediaManagerItem.generateSlideData needs to be defined by the plugin') def onDoubleClicked(self): """ Allows the list click action to be determined dynamically """ - if Settings().value(u'advanced/double click live', False): + if Settings().value(u'advanced/double click live'): self.onLiveClick() else: self.onPreviewClick() @@ -453,7 +453,7 @@ class MediaManagerItem(QtGui.QWidget): """ Allows the change of current item in the list to be actioned """ - if Settings().value(u'advanced/single click preview', False) and self.quickPreviewAllowed \ + if Settings().value(u'advanced/single click preview') and self.quickPreviewAllowed \ and self.listView.selectedIndexes() and self.autoSelectId == -1: self.onPreviewClick(True) @@ -470,7 +470,7 @@ class MediaManagerItem(QtGui.QWidget): serviceItem = self.buildServiceItem() if serviceItem: serviceItem.from_plugin = True - self.plugin.previewController.addServiceItem(serviceItem) + self.preview_controller.add_service_item(serviceItem) if keepFocus: self.listView.setFocus() @@ -496,7 +496,7 @@ class MediaManagerItem(QtGui.QWidget): serviceItem.from_plugin = True if remote: serviceItem.will_auto_start = True - self.plugin.liveController.addServiceItem(serviceItem) + self.live_controller.add_service_item(serviceItem) def createItemFromId(self, item_id): item = QtGui.QListWidgetItem() @@ -507,13 +507,13 @@ class MediaManagerItem(QtGui.QWidget): """ Add a selected item to the current service """ - if not self.listView.selectedIndexes() and not self.remoteTriggered: + if not self.listView.selectedIndexes(): QtGui.QMessageBox.information(self, UiStrings().NISp, translate('OpenLP.MediaManagerItem', 'You must select one or more items to add.')) else: - # Is it posssible to process multiple list items to generate + # Is it possible to process multiple list items to generate # multiple service items? - if self.singleServiceItem or self.remoteTriggered: + if self.singleServiceItem: log.debug(u'%s Add requested', self.plugin.name) self.addToService(replace=self.remoteTriggered) else: @@ -525,7 +525,7 @@ class MediaManagerItem(QtGui.QWidget): serviceItem = self.buildServiceItem(item, True, remote=remote, context=ServiceItemContext.Service) if serviceItem: serviceItem.from_plugin = False - self.plugin.serviceManager.addServiceItem(serviceItem, replace=replace) + self.service_manager.add_service_item(serviceItem, replace=replace) def onAddEditClick(self): """ @@ -536,13 +536,13 @@ class MediaManagerItem(QtGui.QWidget): translate('OpenLP.MediaManagerItem', 'You must select one or more items.')) else: log.debug(u'%s Add requested', self.plugin.name) - serviceItem = self.plugin.serviceManager.getServiceItem() + serviceItem = self.service_manager.get_service_item() if not serviceItem: QtGui.QMessageBox.information(self, UiStrings().NISs, translate('OpenLP.MediaManagerItem', 'You must select an existing service item to add to.')) elif self.plugin.name == serviceItem.name: self.generateSlideData(serviceItem) - self.plugin.serviceManager.addServiceItem(serviceItem, replace=True) + self.service_manager.add_service_item(serviceItem, replace=True) else: # Turn off the remote edit update message indicator QtGui.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'Invalid Service Item'), @@ -554,8 +554,7 @@ class MediaManagerItem(QtGui.QWidget): """ serviceItem = ServiceItem(self.plugin) serviceItem.add_icon(self.plugin.iconPath) - if self.generateSlideData(serviceItem, item, xmlVersion, remote, - context): + if self.generateSlideData(serviceItem, item, xmlVersion, remote, context): return serviceItem else: return None @@ -618,3 +617,74 @@ class MediaManagerItem(QtGui.QWidget): Performs a plugin specific search for items containing ``string`` """ raise NotImplementedError(u'Plugin.search needs to be defined by the plugin') + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) + + def _get_renderer(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_renderer'): + self._renderer = Registry().get(u'renderer') + return self._renderer + + renderer = property(_get_renderer) + + def _get_live_controller(self): + """ + Adds the live controller to the class dynamically + """ + if not hasattr(self, u'_live_controller'): + self._live_controller = Registry().get(u'live_controller') + return self._live_controller + + live_controller = property(_get_live_controller) + + def _get_preview_controller(self): + """ + Adds the preview controller to the class dynamically + """ + if not hasattr(self, u'_preview_controller'): + self._preview_controller = Registry().get(u'preview_controller') + return self._preview_controller + + preview_controller = property(_get_preview_controller) + + def _get_plugin_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) + + def _get_media_controller(self): + """ + Adds the media controller to the class dynamically + """ + if not hasattr(self, u'_media_controller'): + self._media_controller = Registry().get(u'media_controller') + return self._media_controller + + media_controller = property(_get_media_controller) + + def _get_service_manager(self): + """ + Adds the service manager to the class dynamically + """ + if not hasattr(self, u'_service_manager'): + self._service_manager = Registry().get(u'service_manager') + return self._service_manager + + service_manager = property(_get_service_manager) + diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index 1a127a83e..49a08e32a 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -33,8 +33,7 @@ import logging from PyQt4 import QtCore -from openlp.core.lib import Receiver, Settings -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import Receiver, Settings, Registry, UiStrings from openlp.core.utils import get_application_version log = logging.getLogger(__name__) @@ -119,8 +118,7 @@ class Plugin(QtCore.QObject): """ log.info(u'loaded') - def __init__(self, name, plugin_helpers=None, media_item_class=None, - settings_tab_class=None, version=None): + def __init__(self, name, default_settings, media_item_class=None, settings_tab_class=None, version=None): """ This is the constructor for the plugin object. This provides an easy way for descendent plugins to populate common data. This method *must* @@ -133,17 +131,17 @@ class Plugin(QtCore.QObject): ``name`` Defaults to *None*. The name of the plugin. - ``version`` - Defaults to *None*. The version of the plugin. - - ``plugin_helpers`` - Defaults to *None*. A list of helper objects. + ``default_settings`` + A dict containing the plugin's settings. The value to each key is the default value to be used. ``media_item_class`` The class name of the plugin's media item. ``settings_tab_class`` The class name of the plugin's settings tab. + + ``version`` + Defaults to *None*, which means that the same version number is used as OpenLP's version number. """ log.debug(u'Plugin %s initialised' % name) QtCore.QObject.__init__(self) @@ -163,15 +161,15 @@ class Plugin(QtCore.QObject): self.mediaItem = None self.weight = 0 self.status = PluginStatus.Inactive - self.previewController = plugin_helpers[u'preview'] - self.liveController = plugin_helpers[u'live'] - self.renderer = plugin_helpers[u'renderer'] - self.serviceManager = plugin_helpers[u'service'] - self.settingsForm = plugin_helpers[u'settings form'] - self.mediaDock = plugin_helpers[u'toolbox'] - self.pluginManager = plugin_helpers[u'pluginmanager'] - self.formParent = plugin_helpers[u'formparent'] - self.mediaController = plugin_helpers[u'mediacontroller'] + # Add the default status to the default settings. + default_settings[name + u'/status'] = PluginStatus.Inactive + default_settings[name + u'/last directory'] = u'' + # Append a setting for files in the mediamanager (note not all plugins + # which have a mediamanager need this). + if media_item_class is not None: + default_settings[u'%s/%s files' % (name, name)] = [] + # Add settings to the dict of all settings. + Settings.extend_default_settings(default_settings) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'%s_add_service_item' % self.name), self.processAddServiceEvent) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'%s_config_updated' % self.name), @@ -190,7 +188,7 @@ class Plugin(QtCore.QObject): """ Sets the status of the plugin """ - self.status = Settings().value(self.settingsSection + u'/status', PluginStatus.Inactive) + self.status = Settings().value(self.settingsSection + u'/status') def toggleStatus(self, new_status): """ @@ -217,7 +215,7 @@ class Plugin(QtCore.QObject): you need, and return it for integration into OpenLP. """ if self.mediaItemClass: - self.mediaItem = self.mediaItemClass(self.mediaDock.media_dock, self, self.icon) + self.mediaItem = self.mediaItemClass(self.main_window.mediaDockManager.media_dock, self, self.icon) def addImportMenuItem(self, importMenu): """ @@ -287,20 +285,41 @@ class Plugin(QtCore.QObject): """ if self.mediaItem: self.mediaItem.initialise() - self.mediaDock.insert_dock(self.mediaItem, self.icon, self.weight) + self.main_window.mediaDockManager.insert_dock(self.mediaItem, self.icon, self.weight) def finalise(self): """ Called by the plugin Manager to cleanup things. """ if self.mediaItem: - self.mediaDock.remove_dock(self.mediaItem) + self.main_window.mediaDockManager.remove_dock(self.mediaItem) def appStartup(self): """ Perform tasks on application startup """ - pass + # FIXME: Remove after 2.2 release. + # This is needed to load the list of images/media/presentation from the config saved + # before the settings rewrite. + if self.mediaItemClass is not None: + # We need QSettings instead of Settings here to bypass our central settings dict. + # Do NOT do this anywhere else! + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + if settings.contains(u'%s count' % self.name): + list_count = int(settings.value(u'%s count' % self.name, 0)) + loaded_list = [] + if list_count: + for counter in range(list_count): + item = settings.value(u'%s %d' % (self.name, counter), u'') + if item: + loaded_list.append(item) + settings.remove(u'%s %d' % (self.name, counter)) + settings.remove(u'%s count' % self.name) + # Now save the list to the config using our Settings class. + Settings().setValue(u'%s/%s files' % (self.settingsSection, self.name), loaded_list) + settings.endGroup() + def usesTheme(self, theme): """ @@ -389,3 +408,14 @@ class Plugin(QtCore.QObject): The plugin's config has changed """ pass + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) + diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 7fbe7ba9e..ae1d9f984 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -33,7 +33,7 @@ import os import sys import logging -from openlp.core.lib import Plugin, PluginStatus +from openlp.core.lib import Plugin, PluginStatus, Registry log = logging.getLogger(__name__) @@ -43,13 +43,6 @@ class PluginManager(object): and executes all the hooks, as and when necessary. """ log.info(u'Plugin manager loaded') - __instance__ = None - @staticmethod - def get_instance(): - """ - Obtain a single instance of class. - """ - return PluginManager.__instance__ def __init__(self, plugin_dir): """ @@ -60,7 +53,7 @@ class PluginManager(object): The directory to search for plugins. """ log.info(u'Plugin manager Initialising') - PluginManager.__instance__ = self + Registry().register(u'plugin_manager', self) if not plugin_dir in sys.path: log.debug(u'Inserting %s into sys.path', plugin_dir) sys.path.insert(0, plugin_dir) @@ -69,7 +62,7 @@ class PluginManager(object): self.plugins = [] log.info(u'Plugin manager Initialised') - def find_plugins(self, plugin_dir, plugin_helpers): + def find_plugins(self, plugin_dir): """ Scan the directory ``plugin_dir`` for objects inheriting from the ``Plugin`` class. @@ -77,9 +70,6 @@ class PluginManager(object): ``plugin_dir`` The directory to scan. - ``plugin_helpers`` - A list of helper objects to pass to the plugins. - """ log.info(u'Finding plugins') startdepth = len(os.path.abspath(plugin_dir).split(os.sep)) @@ -117,7 +107,7 @@ class PluginManager(object): plugin_objects = [] for p in plugin_classes: try: - plugin = p(plugin_helpers) + plugin = p() log.debug(u'Loaded plugin %s', unicode(p)) plugin_objects.append(plugin) except TypeError: diff --git a/openlp/core/lib/registry.py b/openlp/core/lib/registry.py new file mode 100644 index 000000000..3a42a14c5 --- /dev/null +++ b/openlp/core/lib/registry.py @@ -0,0 +1,96 @@ +# -*- 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 +""" +import logging +import sys + +log = logging.getLogger(__name__) + +class Registry(object): + """ + This is the Component Registry. It is a singleton object and is used to provide a + look up service for common objects. + """ + log.info(u'Registry loaded') + __instance__ = None + + def __new__(cls): + if not cls.__instance__: + cls.__instance__ = object.__new__(cls) + return cls.__instance__ + + @classmethod + def create(cls): + """ + The constructor for the component registry providing a single registry of objects. + """ + log.info(u'Registry Initialising') + registry = cls() + registry.service_list = {} + registry.running_under_test = False + # Allow the tests to remove Registry entries but not the live system + if u'nosetest' in sys.argv[0]: + registry.running_under_test = True + return registry + + + def get(self, key): + """ + Extracts the registry value from the list based on the key passed in + """ + if key in self.service_list: + return self.service_list[key] + else: + log.error(u'Service %s not found in list' % key) + raise KeyError(u'Service %s not found in list' % key) + + def register(self, key, reference): + """ + Registers a component against a key. + """ + if key in self.service_list: + log.error(u'Duplicate service exception %s' % key) + raise KeyError(u'Duplicate service exception %s' % key) + else: + self.service_list[key] = reference + + def remove(self, key): + """ + Removes the registry value from the list based on the key passed in + (Only valid and active for testing framework) + """ + if self.running_under_test == False: + log.error(u'Invalid Method call for key %s' % key) + raise KeyError(u'Invalid Method call for key %s' % key) + return + if key in self.service_list: + del self.service_list[key] + diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 235d7d269..8e6d9d8ad 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -32,9 +32,9 @@ import logging from PyQt4 import QtGui, QtCore, QtWebKit from openlp.core.lib import ServiceItem, expand_tags, build_lyrics_format_css, build_lyrics_outline_css, Receiver, \ - ItemCapabilities, FormattingTags, ImageSource + ItemCapabilities, FormattingTags, ImageSource, Registry, ScreenList from openlp.core.lib.theme import ThemeLevel -from openlp.core.ui import MainDisplay, ScreenList +from openlp.core.ui import MainDisplay log = logging.getLogger(__name__) @@ -48,6 +48,7 @@ VERSE = u'The Lord said to {r}Noah{/r}: \n' \ VERSE_FOR_LINE_COUNT = u'\n'.join(map(unicode, xrange(50))) FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456'] + class Renderer(object): """ Class to pull all Renderer interactions into one place. The plugins will @@ -56,7 +57,7 @@ class Renderer(object): """ log.info(u'Renderer Loaded') - def __init__(self, image_manager, theme_manager): + def __init__(self): """ Initialise the renderer. @@ -68,15 +69,14 @@ class Renderer(object): The theme_manager instance, used to get the current theme details. """ log.debug(u'Initialisation started') - self.theme_manager = theme_manager - self.image_manager = image_manager self.screens = ScreenList() + Registry().register(u'renderer', self) self.theme_level = ThemeLevel.Global self.global_theme_name = u'' self.service_theme_name = u'' self.item_theme_name = u'' self.force_page = False - self.display = MainDisplay(None, self.image_manager, False, self) + self.display = MainDisplay(None, False, self) self.display.setup() self._theme_dimensions = {} self._calculate_default() @@ -93,7 +93,7 @@ class Renderer(object): self._calculate_default() if self.display: self.display.close() - self.display = MainDisplay(None, self.image_manager, False, self) + self.display = MainDisplay(None, False, self) self.display.setup() self._theme_dimensions = {} @@ -235,7 +235,6 @@ class Renderer(object): serviceItem.add_from_text(VERSE_FOR_LINE_COUNT) else: serviceItem.add_from_text(VERSE) - serviceItem.renderer = self serviceItem.raw_footer = FOOTER # if No file do not update cache if theme_data.background_filename: @@ -643,3 +642,23 @@ class Renderer(object): # this parse we are to be wordy line = line.replace(u'\n', u' ') return line.split(u' ') + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) + + def _get_theme_manager(self): + """ + Adds the theme manager to the class dynamically + """ + if not hasattr(self, u'_theme_manager'): + self._theme_manager = Registry().get(u'theme_manager') + return self._theme_manager + + theme_manager = property(_get_theme_manager) \ No newline at end of file diff --git a/openlp/core/ui/screen.py b/openlp/core/lib/screen.py similarity index 90% rename from openlp/core/ui/screen.py rename to openlp/core/lib/screen.py index cbd133e08..4c9032c97 100644 --- a/openlp/core/ui/screen.py +++ b/openlp/core/lib/screen.py @@ -35,10 +35,12 @@ import copy from PyQt4 import QtCore -from openlp.core.lib import Receiver, translate, Settings +from openlp.core.lib import Receiver, translate + log = logging.getLogger(__name__) + class ScreenList(object): """ Wrapper to handle the parameters of the display screen. @@ -241,15 +243,27 @@ class ScreenList(object): """ Loads the screen size and the monitor number from the settings. """ + from openlp.core.lib import Settings + # Add the screen settings to the settings dict. This has to be done here due to crycle dependency. + # Do not do this anywhere else. + screen_settings = { + u'general/x position': self.current[u'size'].x(), + u'general/y position': self.current[u'size'].y(), + u'general/monitor': self.display_count - 1, + u'general/height': self.current[u'size'].height(), + u'general/width': self.current[u'size'].width() + } + Settings.extend_default_settings(screen_settings) settings = Settings() settings.beginGroup(u'general') - self.set_current_display(settings.value(u'monitor', self.display_count - 1)) - self.display = settings.value(u'display on monitor', True) - override_display = settings.value(u'override position', False) - x = settings.value(u'x position', self.current[u'size'].x()) - y = settings.value(u'y position', self.current[u'size'].y()) - width = settings.value(u'width', self.current[u'size'].width()) - height = settings.value(u'height', self.current[u'size'].height()) + monitor = settings.value(u'monitor') + self.set_current_display(monitor) + self.display = settings.value(u'display on monitor') + override_display = settings.value(u'override position') + x = settings.value(u'x position') + y = settings.value(u'y position') + width = settings.value(u'width') + height = settings.value(u'height') self.override[u'size'] = QtCore.QRect(x, y, width, height) self.override[u'primary'] = False settings.endGroup() diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index ddfbe7f9b..b6f225cd9 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -39,7 +39,7 @@ import uuid from PyQt4 import QtGui -from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, ImageSource, Settings +from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, ImageSource, Settings, Registry log = logging.getLogger(__name__) @@ -148,7 +148,6 @@ class ServiceItem(object): The plugin that this service item belongs to. """ if plugin: - self.renderer = plugin.renderer self.name = plugin.name self.title = u'' self.shortname = u'' @@ -161,7 +160,7 @@ class ServiceItem(object): self.service_item_type = None self._raw_frames = [] self._display_frames = [] - self._uuid = 0 + self.unique_identifier = 0 self.notes = u'' self.from_plugin = False self.capabilities = [] @@ -195,7 +194,7 @@ class ServiceItem(object): Method to set the internal id of the item. This is used to compare service items to see if they are the same. """ - self._uuid = unicode(uuid.uuid1()) + self.unique_identifier = unicode(uuid.uuid1()) self.validate_item() def add_capability(self, capability): @@ -293,7 +292,7 @@ class ServiceItem(object): self.image_border = background self.service_item_type = ServiceItemType.Image self._raw_frames.append({u'title': title, u'path': path}) - self.renderer.image_manager.addImage(path, ImageSource.ImagePlugin, self.image_border) + self.image_manager.addImage(path, ImageSource.ImagePlugin, self.image_border) self._new_item() def add_from_text(self, raw_slide, verse_tag=None): @@ -420,7 +419,7 @@ class ServiceItem(object): self._raw_frames.append(slide) elif self.service_item_type == ServiceItemType.Image: settingsSection = serviceitem[u'serviceitem'][u'header'][u'name'] - background = QtGui.QColor(Settings().value(settingsSection + u'/background color', u'#000000')) + background = QtGui.QColor(Settings().value(settingsSection + u'/background color')) if path: self.has_original_files = False for text_image in serviceitem[u'serviceitem'][u'data']: @@ -454,14 +453,14 @@ class ServiceItem(object): def merge(self, other): """ - Updates the _uuid with the value from the original one - The _uuid is unique for a given service item but this allows one to + Updates the unique_identifier with the value from the original one + The unique_identifier is unique for a given service item but this allows one to replace an original version. ``other`` The service item to be merged with """ - self._uuid = other._uuid + self.unique_identifier = other.unique_identifier self.notes = other.notes self.temporary_edit = other.temporary_edit # Copy theme over if present. @@ -478,13 +477,13 @@ class ServiceItem(object): """ if not other: return False - return self._uuid == other._uuid + return self.unique_identifier == other.unique_identifier def __ne__(self, other): """ Confirms the service items are not for the same instance """ - return self._uuid != other._uuid + return self.unique_identifier != other.unique_identifier def is_media(self): """ @@ -637,10 +636,30 @@ class ServiceItem(object): if self.is_image() and not os.path.exists((frame[u'path'])): self.is_valid = False elif self.is_command(): - file = os.path.join(frame[u'path'],frame[u'title']) - if not os.path.exists(file): + file_name = os.path.join(frame[u'path'], frame[u'title']) + if not os.path.exists(file_name): self.is_valid = False if suffix_list and not self.is_text(): - type = frame[u'title'].split(u'.')[-1] - if type.lower() not in suffix_list: + file_suffix = frame[u'title'].split(u'.')[-1] + if file_suffix.lower() not in suffix_list: self.is_valid = False + + def _get_renderer(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_renderer'): + self._renderer = Registry().get(u'renderer') + return self._renderer + + renderer = property(_get_renderer) + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) \ No newline at end of file diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py new file mode 100644 index 000000000..0591871cc --- /dev/null +++ b/openlp/core/lib/settings.py @@ -0,0 +1,343 @@ +# -*- 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 # +############################################################################### +""" +This class contains the core default settings. +""" +import datetime +import logging +import os +import sys + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import SlideLimits +from openlp.core.lib.theme import ThemeLevel +from openlp.core.lib import UiStrings + + +log = logging.getLogger(__name__) + + +# Fix for bug #1014422. +X11_BYPASS_DEFAULT = True +if sys.platform.startswith(u'linux'): + # Default to False on Gnome. + X11_BYPASS_DEFAULT = bool(not os.environ.get(u'GNOME_DESKTOP_SESSION_ID')) + # Default to False on Xfce. + if os.environ.get(u'DESKTOP_SESSION') == u'xfce': + X11_BYPASS_DEFAULT = False + + +class Settings(QtCore.QSettings): + """ + Class to wrap QSettings. + + * Exposes all the methods of QSettings. + * Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to + ``IniFormat``, and the path to the Ini file is set using ``set_filename``, + then the Settings constructor (without any arguments) will create a Settings + object for accessing settings stored in that Ini file. + + ``__default_settings__`` + This dict contains all core settings with their default values. + + ``__obsolete_settings__`` + Each entry is structured in the following way:: + + (u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]) + + The first entry is the *old key*; it will be removed. + + The second entry is the *new key*; we will add it to the config. + + The last entry is a list containing two-pair tuples. If the list is empty, no conversion is made. Otherwise each + pair describes how to convert the old setting's value:: + + (SlideLimits.Wrap, True) + + This means, that if the value of ``general/enable slide loop`` is equal (``==``) ``True`` then we set + ``advanced/slide limits`` to ``SlideLimits.Wrap``. **NOTE**, this means that the rules have to cover all cases! + So, if the type of the old value is bool, then there must be two rules. + """ + __default_settings__ = { + u'advanced/x11 bypass wm': X11_BYPASS_DEFAULT, + u'advanced/default service enabled': True, + u'advanced/enable exit confirmation': True, + u'advanced/save current plugin': False, + u'advanced/single click preview': False, + # 7 stands for now, 0 to 6 is Monday to Sunday. + u'advanced/default service day': 7, + u'advanced/max recent files': 20, + u'advanced/is portable': False, + u'advanced/hide mouse': True, + u'advanced/current media plugin': -1, + u'advanced/double click live': False, + u'advanced/data path': u'', + u'advanced/default service hour': 11, + u'advanced/default color': u'#ffffff', + u'advanced/default image': u':/graphics/openlp-splash-screen.png', + u'advanced/expand service item': False, + u'advanced/recent file count': 4, + u'advanced/default service name': UiStrings().DefaultServiceName, + u'advanced/default service minute': 0, + u'advanced/slide limits': SlideLimits.End, + u'advanced/print slide text': False, + u'advanced/add page break': False, + u'advanced/print file meta data': False, + u'advanced/print notes': False, + u'advanced/display size': 0, + u'crashreport/last directory': u'', + u'displayTags/html_tags': u'', + u'general/ccli number': u'', + u'general/has run wizard': False, + u'general/update check': True, + u'general/language': u'[en]', + u'general/songselect password': u'', + u'general/recent files': [], + u'general/save prompt': False, + u'general/auto preview': False, + u'general/view mode': u'default', + u'general/auto open': False, + u'general/enable slide loop': True, + u'general/show splash': True, + u'general/screen blank': False, + # The oder display settings (display position and dimensions) are defined in the ScreenList class due to crycle + # dependency. + u'general/override position': False, + u'general/loop delay': 5, + u'general/songselect username': u'', + u'general/audio repeat list': False, + u'general/auto unblank': False, + u'general/display on monitor': True, + u'general/audio start paused': True, + # This defaults to yesterday in order to force the update check to run when you've never run it before. + u'general/last version test': datetime.datetime.now().date() - datetime.timedelta(days=1), + u'general/blank warning': False, + u'players/background color': u'#000000', + u'servicemanager/service theme': u'', + u'servicemanager/last file': u'', + u'SettingsImport/Make_Changes': u'At_Own_RISK', + u'SettingsImport/type': u'OpenLP_settings_export', + u'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"), + u'SettingsImport/version': u'', + u'shortcuts/aboutItem': [QtGui.QKeySequence(u'Ctrl+F1')], + u'shortcuts/audioPauseItem': [], + u'shortcuts/displayTagItem': [], + u'shortcuts/blankScreen': [QtCore.Qt.Key_Period], + u'shortcuts/collapse': [QtCore.Qt.Key_Minus], + u'shortcuts/desktopScreen': [QtGui.QKeySequence(u'D')], + u'shortcuts/down': [QtCore.Qt.Key_Down], + u'shortcuts/escapeItem': [QtCore.Qt.Key_Escape], + u'shortcuts/expand': [QtCore.Qt.Key_Plus], + u'shortcuts/exportThemeItem': [], + u'shortcuts/fileNewItem': [QtGui.QKeySequence(u'Ctrl+N')], + u'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(u'Ctrl+Shift+S')], + u'shortcuts/fileExitItem': [QtGui.QKeySequence(u'Alt+F4')], + u'shortcuts/fileSaveItem': [QtGui.QKeySequence(u'Ctrl+S')], + u'shortcuts/fileOpenItem': [QtGui.QKeySequence(u'Ctrl+O')], + u'shortcuts/importThemeItem': [], + u'shortcuts/importBibleItem': [], + u'shortcuts/modeDefaultItem': [], + u'shortcuts/modeLiveItem': [], + u'shortcuts/make_live': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/moveUp': [QtCore.Qt.Key_PageUp], + u'shortcuts/moveTop': [QtCore.Qt.Key_Home], + u'shortcuts/modeSetupItem': [], + u'shortcuts/moveBottom': [QtCore.Qt.Key_End], + u'shortcuts/moveDown': [QtCore.Qt.Key_PageDown], + u'shortcuts/nextTrackItem': [], + u'shortcuts/nextItem_live': [QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown], + u'shortcuts/nextService': [QtCore.Qt.Key_Right], + u'shortcuts/offlineHelpItem': [], + u'shortcuts/onlineHelpItem': [QtGui.QKeySequence(u'Alt+F1')], + u'shortcuts/previousItem_live': [QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], + u'shortcuts/playSlidesLoop': [], + u'shortcuts/playSlidesOnce': [], + u'shortcuts/previousService': [QtCore.Qt.Key_Left], + u'shortcuts/printServiceItem': [QtGui.QKeySequence(u'Ctrl+P')], + u'shortcuts/songExportItem': [], + u'shortcuts/songUsageStatus': [QtCore.Qt.Key_F4], + u'shortcuts/settingsShortcutsItem': [], + u'shortcuts/settingsImportItem': [], + u'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(u'Alt+F7')], + u'shortcuts/songUsageDelete': [], + u'shortcuts/settingsConfigureItem': [], + u'shortcuts/shortcutAction_B': [QtGui.QKeySequence(u'B')], + u'shortcuts/shortcutAction_C': [QtGui.QKeySequence(u'C')], + u'shortcuts/shortcutAction_E': [QtGui.QKeySequence(u'E')], + u'shortcuts/shortcutAction_I': [QtGui.QKeySequence(u'I')], + u'shortcuts/shortcutAction_O': [QtGui.QKeySequence(u'O')], + u'shortcuts/shortcutAction_P': [QtGui.QKeySequence(u'P')], + u'shortcuts/shortcutAction_V': [QtGui.QKeySequence(u'V')], + u'shortcuts/settingsExportItem': [], + u'shortcuts/songUsageReport': [], + u'shortcuts/songImportItem': [], + u'shortcuts/themeScreen': [QtGui.QKeySequence(u'T')], + u'shortcuts/toolsReindexItem': [], + u'shortcuts/toolsAlertItem': [u'F7'], + u'shortcuts/toolsFirstTimeWizard': [], + u'shortcuts/toolsOpenDataFolder': [], + u'shortcuts/toolsAddToolItem': [], + u'shortcuts/updateThemeImages': [], + u'shortcuts/up': [QtCore.Qt.Key_Up], + u'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(u'F10')], + u'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(u'F8')], + u'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(u'F11')], + u'shortcuts/viewLivePanel': [QtGui.QKeySequence(u'F12')], + u'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(u'F9')], + u'shortcuts/webSiteItem': [], + u'themes/theme level': ThemeLevel.Song, + u'themes/global theme': u'', + u'themes/last directory': u'', + u'themes/last directory export': u'', + u'themes/last directory import': u'', + u'user interface/main window position': QtCore.QPoint(0, 0), + u'user interface/preview panel': True, + u'user interface/live panel': True, + u'user interface/main window geometry': QtCore.QByteArray(), + u'user interface/preview splitter geometry': QtCore.QByteArray(), + u'user interface/lock panel': False, + u'user interface/mainwindow splitter geometry': QtCore.QByteArray(), + u'user interface/live splitter geometry': QtCore.QByteArray(), + u'user interface/main window state': QtCore.QByteArray(), + u'media/players': u'webkit', + u'media/override player': QtCore.Qt.Unchecked, + # Old settings (not used anymore). Have to be here, so that old setting.config backups can be imported. + u'advanced/stylesheet fix': u'', + u'servicemanager/last directory': u'' + } + __file_path__ = u'' + __obsolete_settings__ = [ + (u'bibles/bookname language', u'bibles/book name language', []), + (u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]), + (u'themes/last directory', u'themes/last directory import', []), + (u'themes/last directory 1', u'themes/last directory export', []), + (u'servicemanager/last directory', u'', []), + (u'songs/last directory 1', u'songs/last directory import', []), + (u'bibles/last directory 1', u'bibles/last directory import', []), + (u'songusage/last directory 1', u'songusage/last directory export', []), + (u'shortcuts/makeLive', u'shortcuts/make_live', []), + (u'advanced/stylesheet fix', u'', []), + (u'media/background color', u'players/background color', []) + ] + + @staticmethod + def extend_default_settings(default_values): + """ + Static method to merge the given ``default_values`` with the ``Settings.__default_settings__``. + + ``default_values`` + A dict with setting keys and their default values. + """ + Settings.__default_settings__ = dict(default_values.items() + Settings.__default_settings__.items()) + + @staticmethod + def set_filename(ini_file): + """ + Sets the complete path to an Ini file to be used by Settings objects. + + Does not affect existing Settings objects. + """ + Settings.__file_path__ = ini_file + + @staticmethod + def set_up_default_values(): + """ + This static method is called on start up. It is used to perform any operation on the __default_settings__ dict. + """ + # Make sure the string is translated (when building the dict the string is not translated because the translate + # function was not set up as this stage). + Settings.__default_settings__[u'advanced/default service name'] = UiStrings().DefaultServiceName + + def __init__(self, *args): + if not args and Settings.__file_path__ and Settings.defaultFormat() == Settings.IniFormat: + QtCore.QSettings.__init__(self, Settings.__file_path__, Settings.IniFormat) + else: + QtCore.QSettings.__init__(self, *args) + + def remove_obsolete_settings(self): + """ + This method is only called to clean up the config. It removes old settings and it renames settings. See + ``__obsolete_settings__`` for more details. + """ + for old_key, new_key, rules in Settings.__obsolete_settings__: + # Once removed we don't have to do this again. + if self.contains(old_key): + if new_key: + # Get the value of the old_key. + old_value = super(Settings, self).value(old_key) + # Iterate over our rules and check what the old_value should be "converted" to. + for new, old in rules: + # If the value matches with the condition (rule), then use the provided value. This is used to + # convert values. E. g. an old value 1 results in True, and 0 in False. + if old == old_value: + old_value = new + break + self.setValue(new_key, old_value) + self.remove(old_key) + + def value(self, key): + """ + Returns the value for the given ``key``. The returned ``value`` is of the same type as the default value in the + *Settings.__default_settings__* dict. + + **Note**, this method only converts a few types and might need to be extended if a certain type is missing! + + ``key`` + The key to return the value from. + """ + # if group() is not empty the group has not been specified together with the key. + if self.group(): + default_value = Settings.__default_settings__[self.group() + u'/' + key] + else: + default_value = Settings.__default_settings__[key] + setting = super(Settings, self).value(key, default_value) + # On OS X (and probably on other platforms too) empty value from QSettings is represented as type + # PyQt4.QtCore.QPyNullVariant. This type has to be converted to proper 'None' Python type. + if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): + setting = None + # Handle 'None' type (empty value) properly. + if setting is None: + # An empty string saved to the settings results in a None type being returned. + # Convert it to empty unicode string. + if isinstance(default_value, unicode): + return u'' + # An empty list saved to the settings results in a None type being returned. + else: + return [] + # Convert the setting to the correct type. + if isinstance(default_value, bool): + if isinstance(setting, bool): + return setting + # Sometimes setting is string instead of a boolean. + return setting == u'true' + if isinstance(default_value, int): + return int(setting) + return setting + diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index 37b8fc43d..8491fe4f1 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -27,9 +27,8 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -Provide handling for persisting OpenLP settings. OpenLP uses QSettings to -manage settings persistence. QSettings provides a single API for saving and -retrieving settings from the application but writes to disk in an OS dependant +Provide handling for persisting OpenLP settings. OpenLP uses QSettings to manage settings persistence. QSettings +provides a single API for saving and retrieving settings from the application but writes to disk in an OS dependant format. """ import os @@ -39,109 +38,19 @@ from PyQt4 import QtCore from openlp.core.lib import Settings from openlp.core.utils import AppLocation + class SettingsManager(object): """ - Class to provide helper functions for the loading and saving of application - settings. + Class to provide helper functions for the loading and saving of application settings. """ - @staticmethod - def get_last_dir(section, num=None): - """ - Read the last directory used for plugin. - - ``section`` - The section of code calling the method. This is used in the - settings key. - - ``num`` - Defaults to *None*. A further qualifier. - """ - if num: - name = u'last directory %d' % num - else: - name = u'last directory' - return Settings().value(section + u'/' + name, u'') - - @staticmethod - def set_last_dir(section, directory, num=None): - """ - Save the last directory used for plugin. - - ``section`` - The section of code calling the method. This is used in the - settings key. - - ``directory`` - The directory being stored in the settings. - - ``num`` - Defaults to *None*. A further qualifier. - """ - if num: - name = u'last directory %d' % num - else: - name = u'last directory' - Settings().setValue(section + u'/' + name, directory) - - @staticmethod - def set_list(section, name, list): - """ - Save a list to application settings. - - ``section`` - The section of the settings to store this list. - - ``name`` - The name of the list to save. - - ``list`` - The list of values to save. - """ - settings = Settings() - settings.beginGroup(section) - old_count = settings.value(u'%s count' % name, 0) - new_count = len(list) - settings.setValue(u'%s count' % name, new_count) - for counter in range(new_count): - settings.setValue(u'%s %d' % (name, counter), list[counter - 1]) - if old_count > new_count: - # Tidy up any old list items - for counter in range(new_count, old_count): - settings.remove(u'%s %d' % (name, counter)) - settings.endGroup() - - @staticmethod - def load_list(section, name): - """ - Load a list from the config file. - - ``section`` - The section of the settings to load the list from. - - ``name`` - The name of the list. - """ - settings = Settings() - settings.beginGroup(section) - list_count = settings.value(u'%s count' % name, 0) - list = [] - if list_count: - for counter in range(list_count): - item = settings.value(u'%s %d' % (name, counter), u'') - if item: - list.append(item) - settings.endGroup() - return list - @staticmethod def get_files(section=None, extension=None): """ Get a list of files from the data files path. ``section`` - Defaults to *None*. The section of code getting the files - used - to load from a section's data subdirectory. + Defaults to *None*. The section of code getting the files - used to load from a section's data subdirectory. ``extension`` Defaults to *None*. The extension to search for. @@ -154,8 +63,7 @@ class SettingsManager(object): except OSError: return [] if extension: - return [filename for filename in files - if extension == os.path.splitext(filename)[1]] + return [filename for filename in files if extension == os.path.splitext(filename)[1]] else: # no filtering required return files diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index b2803c965..8a85c0d86 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -36,7 +36,7 @@ import logging from xml.dom.minidom import Document from lxml import etree, objectify -from openlp.core.lib import str_to_bool +from openlp.core.lib import str_to_bool, ScreenList log = logging.getLogger(__name__) @@ -380,8 +380,7 @@ class ThemeXML(object): # Create italics name element self.child_element(background, u'italics', unicode(italics)) # Create indentation name element - self.child_element( - background, u'line_adjustment', unicode(line_adjustment)) + self.child_element(background, u'line_adjustment', unicode(line_adjustment)) # Create Location element element = self.theme_xml.createElement(u'location') element.setAttribute(u'override', unicode(override)) @@ -451,7 +450,6 @@ class ThemeXML(object): Set the header and footer size into the current primary screen. 10 px on each side is removed to allow for a border. """ - from openlp.core.ui import ScreenList current_screen = ScreenList().current self.font_main_y = 0 self.font_main_width = current_screen[u'size'].width() - 20 diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 10935384a..0d869d724 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -33,116 +33,12 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon, Receiver, translate +from openlp.core.lib import build_icon, translate, Receiver, UiStrings from openlp.core.utils.actions import ActionList + log = logging.getLogger(__name__) -class UiStrings(object): - """ - Provide standard strings for objects to use. - """ - __instance__ = None - - def __new__(cls): - """ - Override the default object creation method to return a single instance. - """ - if not cls.__instance__: - cls.__instance__ = object.__new__(cls) - return cls.__instance__ - - def __init__(self): - """ - These strings should need a good reason to be retranslated elsewhere. - Should some/more/less of these have an & attached? - """ - self.About = translate('OpenLP.Ui', 'About') - self.Add = translate('OpenLP.Ui', '&Add') - self.Advanced = translate('OpenLP.Ui', 'Advanced') - self.AllFiles = translate('OpenLP.Ui', 'All Files') - self.Automatic = translate('OpenLP.Ui', 'Automatic') - self.BackgroundColor = translate('OpenLP.Ui', 'Background Color') - self.Bottom = translate('OpenLP.Ui', 'Bottom') - self.Browse = translate('OpenLP.Ui', 'Browse...') - self.Cancel = translate('OpenLP.Ui', 'Cancel') - self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') - self.CreateService = translate('OpenLP.Ui', 'Create a new service.') - self.ConfirmDelete = translate('OpenLP.Ui', 'Confirm Delete') - self.Continuous = translate('OpenLP.Ui', 'Continuous') - self.Default = translate('OpenLP.Ui', 'Default') - self.DefaultColor = translate('OpenLP.Ui', 'Default Color:') - self.Delete = translate('OpenLP.Ui', '&Delete') - self.DisplayStyle = translate('OpenLP.Ui', 'Display style:') - self.Duplicate = translate('OpenLP.Ui', 'Duplicate Error') - self.Edit = translate('OpenLP.Ui', '&Edit') - self.EmptyField = translate('OpenLP.Ui', 'Empty Field') - self.Error = translate('OpenLP.Ui', 'Error') - self.Export = translate('OpenLP.Ui', 'Export') - self.File = translate('OpenLP.Ui', 'File') - self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') - self.Help = translate('OpenLP.Ui', 'Help') - self.Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours') - self.IFdSs = translate('OpenLP.Ui', 'Invalid Folder Selected', 'Singular') - self.IFSs = translate('OpenLP.Ui', 'Invalid File Selected', 'Singular') - self.IFSp = translate('OpenLP.Ui', 'Invalid Files Selected', 'Plural') - self.Image = translate('OpenLP.Ui', 'Image') - self.Import = translate('OpenLP.Ui', 'Import') - self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:') - self.Live = translate('OpenLP.Ui', 'Live') - self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error') - self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar') - self.Load = translate('OpenLP.Ui', 'Load') - self.Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes') - self.Middle = translate('OpenLP.Ui', 'Middle') - self.New = translate('OpenLP.Ui', 'New') - self.NewService = translate('OpenLP.Ui', 'New Service') - self.NewTheme = translate('OpenLP.Ui', 'New Theme') - self.NextTrack = translate('OpenLP.Ui', 'Next Track') - self.NFdSs = translate('OpenLP.Ui', 'No Folder Selected', 'Singular') - self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') - self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') - self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') - self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural') - self.OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x') - self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2') - self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.1') - self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?') - self.OpenService = translate('OpenLP.Ui', 'Open service.') - self.PlaySlidesInLoop = translate('OpenLP.Ui','Play Slides in Loop') - self.PlaySlidesToEnd = translate('OpenLP.Ui','Play Slides to End') - self.Preview = translate('OpenLP.Ui', 'Preview') - self.PrintService = translate('OpenLP.Ui', 'Print Service') - self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background') - self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.') - self.ResetBG = translate('OpenLP.Ui', 'Reset Background') - self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.') - self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds') - self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview') - self.Search = translate('OpenLP.Ui', 'Search') - self.SearchThemes = translate('OpenLP.Ui', 'Search Themes...', 'Search bar place holder text ') - self.SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.') - self.SelectEdit = translate('OpenLP.Ui', 'You must select an item to edit.') - self.Settings = translate('OpenLP.Ui', 'Settings') - self.SaveService = translate('OpenLP.Ui', 'Save Service') - self.Service = translate('OpenLP.Ui', 'Service') - self.Split = translate('OpenLP.Ui', 'Optional &Split') - self.SplitToolTip = translate('OpenLP.Ui', - 'Split a slide into two only if it does not fit on the screen as one slide.') - self.StartTimeCode = translate('OpenLP.Ui', 'Start %s') - self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop') - self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End') - self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular') - self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') - self.Tools = translate('OpenLP.Ui', 'Tools') - self.Top = translate('OpenLP.Ui', 'Top') - self.UnsupportedFile = translate('OpenLP.Ui', 'Unsupported File') - self.VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide') - self.VersePerLine = translate('OpenLP.Ui', 'Verse Per Line') - self.Version = translate('OpenLP.Ui', 'Version') - self.View = translate('OpenLP.Ui', 'View') - self.ViewMode = translate('OpenLP.Ui', 'View Mode') - def add_welcome_page(parent, image): """ diff --git a/openlp/core/lib/uistrings.py b/openlp/core/lib/uistrings.py new file mode 100644 index 000000000..f89b52a98 --- /dev/null +++ b/openlp/core/lib/uistrings.py @@ -0,0 +1,147 @@ +# -*- 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 # +############################################################################### +""" +The :mod:`uistrings` module provides standard strings for OpenLP. +""" +import logging + +from openlp.core.lib import translate + + +log = logging.getLogger(__name__) + + +class UiStrings(object): + """ + Provide standard strings for objects to use. + """ + __instance__ = None + + def __new__(cls): + """ + Override the default object creation method to return a single instance. + """ + if not cls.__instance__: + cls.__instance__ = object.__new__(cls) + return cls.__instance__ + + def __init__(self): + """ + These strings should need a good reason to be retranslated elsewhere. + Should some/more/less of these have an & attached? + """ + self.About = translate('OpenLP.Ui', 'About') + self.Add = translate('OpenLP.Ui', '&Add') + self.Advanced = translate('OpenLP.Ui', 'Advanced') + self.AllFiles = translate('OpenLP.Ui', 'All Files') + self.Automatic = translate('OpenLP.Ui', 'Automatic') + self.BackgroundColor = translate('OpenLP.Ui', 'Background Color') + self.Bottom = translate('OpenLP.Ui', 'Bottom') + self.Browse = translate('OpenLP.Ui', 'Browse...') + self.Cancel = translate('OpenLP.Ui', 'Cancel') + self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') + self.CreateService = translate('OpenLP.Ui', 'Create a new service.') + self.ConfirmDelete = translate('OpenLP.Ui', 'Confirm Delete') + self.Continuous = translate('OpenLP.Ui', 'Continuous') + self.Default = translate('OpenLP.Ui', 'Default') + self.DefaultColor = translate('OpenLP.Ui', 'Default Color:') + self.DefaultServiceName = translate('OpenLP.Ui', 'Service %Y-%m-%d %H-%M', + 'This may not contain any of the following characters: /\\?*|<>\[\]":+\n' + 'See http://docs.python.org/library/datetime.html#strftime-strptime-behavior for more information.') + self.Delete = translate('OpenLP.Ui', '&Delete') + self.DisplayStyle = translate('OpenLP.Ui', 'Display style:') + self.Duplicate = translate('OpenLP.Ui', 'Duplicate Error') + self.Edit = translate('OpenLP.Ui', '&Edit') + self.EmptyField = translate('OpenLP.Ui', 'Empty Field') + self.Error = translate('OpenLP.Ui', 'Error') + self.Export = translate('OpenLP.Ui', 'Export') + self.File = translate('OpenLP.Ui', 'File') + self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') + self.Help = translate('OpenLP.Ui', 'Help') + self.Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours') + self.IFdSs = translate('OpenLP.Ui', 'Invalid Folder Selected', 'Singular') + self.IFSs = translate('OpenLP.Ui', 'Invalid File Selected', 'Singular') + self.IFSp = translate('OpenLP.Ui', 'Invalid Files Selected', 'Plural') + self.Image = translate('OpenLP.Ui', 'Image') + self.Import = translate('OpenLP.Ui', 'Import') + self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:') + self.Live = translate('OpenLP.Ui', 'Live') + self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error') + self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar') + self.Load = translate('OpenLP.Ui', 'Load') + self.Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes') + self.Middle = translate('OpenLP.Ui', 'Middle') + self.New = translate('OpenLP.Ui', 'New') + self.NewService = translate('OpenLP.Ui', 'New Service') + self.NewTheme = translate('OpenLP.Ui', 'New Theme') + self.NextTrack = translate('OpenLP.Ui', 'Next Track') + self.NFdSs = translate('OpenLP.Ui', 'No Folder Selected', 'Singular') + self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') + self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') + self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') + self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural') + self.OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x') + self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2') + self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.1') + self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?') + self.OpenService = translate('OpenLP.Ui', 'Open service.') + self.PlaySlidesInLoop = translate('OpenLP.Ui','Play Slides in Loop') + self.PlaySlidesToEnd = translate('OpenLP.Ui','Play Slides to End') + self.Preview = translate('OpenLP.Ui', 'Preview') + self.PrintService = translate('OpenLP.Ui', 'Print Service') + self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background') + self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.') + self.ResetBG = translate('OpenLP.Ui', 'Reset Background') + self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.') + self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds') + self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview') + self.Search = translate('OpenLP.Ui', 'Search') + self.SearchThemes = translate('OpenLP.Ui', 'Search Themes...', 'Search bar place holder text ') + self.SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.') + self.SelectEdit = translate('OpenLP.Ui', 'You must select an item to edit.') + self.Settings = translate('OpenLP.Ui', 'Settings') + self.SaveService = translate('OpenLP.Ui', 'Save Service') + self.Service = translate('OpenLP.Ui', 'Service') + self.Split = translate('OpenLP.Ui', 'Optional &Split') + self.SplitToolTip = translate('OpenLP.Ui', + 'Split a slide into two only if it does not fit on the screen as one slide.') + self.StartTimeCode = translate('OpenLP.Ui', 'Start %s') + self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop') + self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End') + self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular') + self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') + self.Tools = translate('OpenLP.Ui', 'Tools') + self.Top = translate('OpenLP.Ui', 'Top') + self.UnsupportedFile = translate('OpenLP.Ui', 'Unsupported File') + self.VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide') + self.VersePerLine = translate('OpenLP.Ui', 'Verse Per Line') + self.Version = translate('OpenLP.Ui', 'Version') + self.View = translate('OpenLP.Ui', 'View') + self.ViewMode = translate('OpenLP.Ui', 'View Mode') + diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 132465b2e..a0065966b 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -31,31 +31,29 @@ The :mod:`ui` module provides the core user interface for OpenLP """ + class HideMode(object): """ - This is an enumeration class which specifies the different modes of hiding - the display. + This is an enumeration class which specifies the different modes of hiding the display. ``Blank`` - This mode is used to hide all output, specifically by covering the - display with a black screen. + This mode is used to hide all output, specifically by covering the display with a black screen. ``Theme`` - This mode is used to hide all output, but covers the display with the - current theme background, as opposed to black. + This mode is used to hide all output, but covers the display with the current theme background, as opposed to + black. ``Desktop`` - This mode hides all output by minimising the display, leaving the user's - desktop showing. + This mode hides all output by minimising the display, leaving the user's desktop showing. """ Blank = 1 Theme = 2 Screen = 3 + class AlertLocation(object): """ - This is an enumeration class which controls where Alerts are placed on the - screen. + This is an enumeration class which controls where Alerts are placed on the screen. ``Top`` Place the text at the top of the screen. @@ -70,10 +68,10 @@ class AlertLocation(object): Middle = 1 Bottom = 2 + class DisplayControllerType(object): """ - This is an enumeration class which says where a display controller - originated from. + This is an enumeration class which says where a display controller originated from. """ Live = 0 Preview = 1 @@ -86,7 +84,6 @@ from themelayoutform import ThemeLayoutForm from themeform import ThemeForm from filerenameform import FileRenameForm from starttimeform import StartTimeForm -from screen import ScreenList from maindisplay import MainDisplay, Display from servicenoteform import ServiceNoteForm from serviceitemeditform import ServiceItemEditForm diff --git a/openlp/core/ui/aboutdialog.py b/openlp/core/ui/aboutdialog.py index 13da58845..a07434b12 100644 --- a/openlp/core/ui/aboutdialog.py +++ b/openlp/core/ui/aboutdialog.py @@ -29,8 +29,9 @@ from PyQt4 import QtGui -from openlp.core.lib import build_icon, translate -from openlp.core.lib.ui import UiStrings, create_button, create_button_box +from openlp.core.lib import build_icon, translate, UiStrings +from openlp.core.lib.ui import create_button, create_button_box + class Ui_AboutDialog(object): def setupUi(self, aboutDialog): @@ -73,8 +74,8 @@ class Ui_AboutDialog(object): self.aboutNotebook.addTab(self.licenseTab, u'') self.aboutDialogLayout.addWidget(self.aboutNotebook) self.volunteerButton = create_button(None, u'volunteerButton', icon=u':/system/system_volunteer.png') - self.buttonBox = create_button_box(aboutDialog, u'buttonBox', [u'close'], [self.volunteerButton]) - self.aboutDialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(aboutDialog, u'button_box', [u'close'], [self.volunteerButton]) + self.aboutDialogLayout.addWidget(self.button_box) self.retranslateUi(aboutDialog) self.aboutNotebook.setCurrentIndex(0) diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index 17d554145..3be6fbeb9 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -36,13 +36,13 @@ import sys from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, translate, build_icon, Receiver, Settings -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import SettingsTab, translate, build_icon, Receiver, Settings, UiStrings from openlp.core.utils import get_images_filter, AppLocation, format_time from openlp.core.lib import SlideLimits log = logging.getLogger(__name__) + class AdvancedTab(SettingsTab): """ The :class:`AdvancedTab` manages the advanced settings tab including the UI @@ -53,17 +53,6 @@ class AdvancedTab(SettingsTab): Initialise the settings tab """ self.displayChanged = False - # 7 stands for now, 0 to 6 is Monday to Sunday. - self.defaultServiceDay = 7 - # 11 o'clock is the most popular time for morning service. - self.defaultServiceHour = 11 - self.defaultServiceMinute = 0 - self.defaultServiceName = translate('OpenLP.AdvancedTab', - 'Service %Y-%m-%d %H-%M', - 'This may not contain any of the following characters: ' - '/\\?*|<>\[\]":+\n' - 'See http://docs.python.org/library/datetime.html' - '#strftime-strptime-behavior for more information.') self.defaultImage = u':/graphics/openlp-splash-screen.png' self.defaultColor = u'#ffffff' self.dataExists = False @@ -310,7 +299,7 @@ class AdvancedTab(SettingsTab): self.serviceNameLabel.setText(translate('OpenLP.AdvancedTab', 'Name:')) self.serviceNameEdit.setToolTip(translate('OpenLP.AdvancedTab', 'Consult the OpenLP manual for usage.')) self.serviceNameRevertButton.setToolTip( - translate('OpenLP.AdvancedTab', 'Revert to the default service name "%s".') % self.defaultServiceName) + translate('OpenLP.AdvancedTab', 'Revert to the default service name "%s".') % UiStrings().DefaultServiceName) self.serviceNameExampleLabel.setText(translate('OpenLP.AdvancedTab', 'Example:')) self.hideMouseGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor')) self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window')) @@ -352,36 +341,26 @@ class AdvancedTab(SettingsTab): # The max recent files value does not have an interface and so never # gets actually stored in the settings therefore the default value of # 20 will always be used. - self.recentSpinBox.setMaximum(settings.value(u'max recent files', 20)) - self.recentSpinBox.setValue(settings.value(u'recent file count', 4)) - self.mediaPluginCheckBox.setChecked(settings.value(u'save current plugin', False)) - self.doubleClickLiveCheckBox.setChecked(settings.value(u'double click live', False)) - self.singleClickPreviewCheckBox.setChecked(settings.value(u'single click preview', False)) - self.expandServiceItemCheckBox.setChecked(settings.value(u'expand service item', False)) - self.enableAutoCloseCheckBox.setChecked(settings.value(u'enable exit confirmation', True)) - self.hideMouseCheckBox.setChecked(settings.value(u'hide mouse', True)) - self.serviceNameDay.setCurrentIndex(settings.value(u'default service day', self.defaultServiceDay)) - self.serviceNameTime.setTime(QtCore.QTime(settings.value(u'default service hour', self.defaultServiceHour), - settings.value(u'default service minute',self.defaultServiceMinute))) + self.recentSpinBox.setMaximum(settings.value(u'max recent files')) + self.recentSpinBox.setValue(settings.value(u'recent file count')) + self.mediaPluginCheckBox.setChecked(settings.value(u'save current plugin')) + self.doubleClickLiveCheckBox.setChecked(settings.value(u'double click live')) + self.singleClickPreviewCheckBox.setChecked(settings.value(u'single click preview')) + self.expandServiceItemCheckBox.setChecked(settings.value(u'expand service item')) + self.enableAutoCloseCheckBox.setChecked(settings.value(u'enable exit confirmation')) + self.hideMouseCheckBox.setChecked(settings.value(u'hide mouse')) + self.serviceNameDay.setCurrentIndex(settings.value(u'default service day')) + self.serviceNameTime.setTime(QtCore.QTime(settings.value(u'default service hour'), + settings.value(u'default service minute'))) self.shouldUpdateServiceNameExample = True - self.serviceNameEdit.setText(settings.value(u'default service name', - self.defaultServiceName)) - default_service_enabled = settings.value(u'default service enabled', True) + self.serviceNameEdit.setText(settings.value(u'default service name')) + default_service_enabled = settings.value(u'default service enabled') self.serviceNameCheckBox.setChecked(default_service_enabled) self.serviceNameCheckBoxToggled(default_service_enabled) - # Fix for bug #1014422. - x11_bypass_default = True - if sys.platform.startswith(u'linux'): - # Default to False on Gnome. - x11_bypass_default = bool(not - os.environ.get(u'GNOME_DESKTOP_SESSION_ID')) - # Default to False on XFce - if os.environ.get(u'DESKTOP_SESSION') == u'xfce': - x11_bypass_default = False - self.x11BypassCheckBox.setChecked(settings.value(u'x11 bypass wm', x11_bypass_default)) - self.defaultColor = settings.value(u'default color', u'#ffffff') - self.defaultFileEdit.setText(settings.value(u'default image', u':/graphics/openlp-splash-screen.png')) - self.slide_limits = settings.value(u'slide limits', SlideLimits.End) + self.x11BypassCheckBox.setChecked(settings.value(u'x11 bypass wm')) + self.defaultColor = settings.value(u'default color') + self.defaultFileEdit.setText(settings.value(u'default image')) + self.slide_limits = settings.value(u'slide limits') if self.slide_limits == SlideLimits.End: self.endSlideRadioButton.setChecked(True) elif self.slide_limits == SlideLimits.Wrap: @@ -423,7 +402,7 @@ class AdvancedTab(SettingsTab): self.dataDirectoryLabel.setText(os.path.abspath(self.currentDataPath)) self.defaultColorButton.setStyleSheet(u'background-color: %s' % self.defaultColor) # Don't allow data directory move if running portable. - if settings.value(u'advanced/is portable', False): + if settings.value(u'advanced/is portable'): self.dataDirectoryGroupBox.hide() def save(self): @@ -432,11 +411,10 @@ class AdvancedTab(SettingsTab): """ settings = Settings() settings.beginGroup(self.settingsSection) - settings.setValue(u'default service enabled', - self.serviceNameCheckBox.isChecked()) + settings.setValue(u'default service enabled', self.serviceNameCheckBox.isChecked()) service_name = self.serviceNameEdit.text() preset_is_valid = self.generateServiceNameExample()[0] - if service_name == self.defaultServiceName or not preset_is_valid: + if service_name == UiStrings().DefaultServiceName or not preset_is_valid: settings.remove(u'default service name') self.serviceNameEdit.setText(service_name) else: @@ -503,7 +481,7 @@ class AdvancedTab(SettingsTab): self.updateServiceNameExample(None) def onServiceNameRevertButtonClicked(self): - self.serviceNameEdit.setText(self.defaultServiceName) + self.serviceNameEdit.setText(UiStrings().DefaultServiceName) self.serviceNameEdit.setFocus() def onDefaultColorButtonClicked(self): @@ -528,9 +506,9 @@ class AdvancedTab(SettingsTab): """ old_root_path = unicode(self.dataDirectoryLabel.text()) # Get the new directory location. - new_data_path = unicode(QtGui.QFileDialog.getExistingDirectory(self, + new_data_path = QtGui.QFileDialog.getExistingDirectory(self, translate('OpenLP.AdvancedTab', 'Select Data Directory Location'), old_root_path, - options = QtGui.QFileDialog.ShowDirsOnly)) + options = QtGui.QFileDialog.ShowDirsOnly) # Set the new data path. if new_data_path: new_data_path = os.path.normpath(new_data_path) diff --git a/openlp/core/ui/exceptiondialog.py b/openlp/core/ui/exceptiondialog.py index 76a92938d..e3736de53 100644 --- a/openlp/core/ui/exceptiondialog.py +++ b/openlp/core/ui/exceptiondialog.py @@ -70,9 +70,9 @@ class Ui_ExceptionDialog(object): icon=u':/general/general_save.png', click=self.onSaveReportButtonClicked) self.attachFileButton = create_button(exceptionDialog, u'attachFileButton', icon=u':/general/general_open.png', click=self.onAttachFileButtonClicked) - self.buttonBox = create_button_box(exceptionDialog, u'buttonBox', + self.button_box = create_button_box(exceptionDialog, u'button_box', [u'close'], [self.sendReportButton, self.saveReportButton, self.attachFileButton]) - self.exceptionLayout.addWidget(self.buttonBox) + self.exceptionLayout.addWidget(self.button_box) self.retranslateUi(exceptionDialog) QtCore.QObject.connect(self.descriptionTextEdit, diff --git a/openlp/core/ui/exceptionform.py b/openlp/core/ui/exceptionform.py index 2fcc67071..213a66388 100644 --- a/openlp/core/ui/exceptionform.py +++ b/openlp/core/ui/exceptionform.py @@ -85,8 +85,7 @@ except AttributeError: WEBKIT_VERSION = u'-' -from openlp.core.lib import translate, SettingsManager -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import translate, UiStrings, Settings from openlp.core.utils import get_application_version from exceptiondialog import Ui_ExceptionDialog @@ -147,12 +146,12 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): '--- Library Versions ---\n%s\n') filename = QtGui.QFileDialog.getSaveFileName(self, translate('OpenLP.ExceptionForm', 'Save Crash Report'), - SettingsManager.get_last_dir(self.settingsSection), + Settings().value(self.settingsSection + u'/last directory'), translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)')) if filename: filename = unicode(filename).replace(u'/', os.path.sep) - SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(filename)) + Settings().setValue(self.settingsSection + u'/last directory', os.path.dirname(filename)) report_text = report_text % self._createReport() try: report_file = open(filename, u'w') @@ -212,7 +211,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): def onAttachFileButtonClicked(self): files = QtGui.QFileDialog.getOpenFileName( self, translate('ImagePlugin.ExceptionDialog', 'Select Attachment'), - SettingsManager.get_last_dir(u'exceptions'), u'%s (*.*) (*)' % UiStrings().AllFiles) + Settings().value(self.settingsSection + u'/last directory'), u'%s (*.*) (*)' % UiStrings().AllFiles) log.info(u'New files(s) %s', unicode(files)) if files: self.fileAttachment = unicode(files) diff --git a/openlp/core/ui/filerenamedialog.py b/openlp/core/ui/filerenamedialog.py index 956058d06..5cd67a20b 100644 --- a/openlp/core/ui/filerenamedialog.py +++ b/openlp/core/ui/filerenamedialog.py @@ -37,7 +37,7 @@ class Ui_FileRenameDialog(object): fileRenameDialog.setObjectName(u'fileRenameDialog') fileRenameDialog.resize(300, 10) self.dialogLayout = QtGui.QGridLayout(fileRenameDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.fileNameLabel = QtGui.QLabel(fileRenameDialog) self.fileNameLabel.setObjectName(u'fileNameLabel') self.dialogLayout.addWidget(self.fileNameLabel, 0, 0) @@ -45,8 +45,8 @@ class Ui_FileRenameDialog(object): self.fileNameEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'[^/\\?*|<>\[\]":+%]+'), self)) self.fileNameEdit.setObjectName(u'fileNameEdit') self.dialogLayout.addWidget(self.fileNameEdit, 0, 1) - self.buttonBox = create_button_box(fileRenameDialog, u'buttonBox', [u'cancel', u'ok']) - self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) + self.button_box = create_button_box(fileRenameDialog, u'button_box', [u'cancel', u'ok']) + self.dialogLayout.addWidget(self.button_box, 1, 0, 1, 2) self.retranslateUi(fileRenameDialog) self.setMaximumHeight(self.sizeHint().height()) diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index f979fc5a5..95ae35d5d 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -116,7 +116,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): unicode(gettempdir(), get_filesystem_encoding()), u'openlp')) self.noInternetFinishButton.setVisible(False) # Check if this is a re-run of the wizard. - self.hasRunWizard = Settings().value(u'general/has run wizard', False) + self.hasRunWizard = Settings().value(u'general/has run wizard') # Sort out internet access for downloads if self.webAccess: songs = self.config.get(u'songs', u'languages') @@ -202,7 +202,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): index = self.themeComboBox.findText(theme) if index == -1: self.themeComboBox.addItem(theme) - default_theme = Settings().value(u'themes/global theme', u'') + default_theme = Settings().value(u'themes/global theme') # Pre-select the current default theme. index = self.themeComboBox.findText(default_theme) self.themeComboBox.setCurrentIndex(index) diff --git a/openlp/core/ui/firsttimelanguagedialog.py b/openlp/core/ui/firsttimelanguagedialog.py index b4b2e374c..eae9dc198 100644 --- a/openlp/core/ui/firsttimelanguagedialog.py +++ b/openlp/core/ui/firsttimelanguagedialog.py @@ -39,7 +39,7 @@ class Ui_FirstTimeLanguageDialog(object): self.dialogLayout = QtGui.QVBoxLayout(languageDialog) self.dialogLayout.setContentsMargins(8, 8, 8, 8) self.dialogLayout.setSpacing(8) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.infoLabel = QtGui.QLabel(languageDialog) self.infoLabel.setObjectName(u'infoLabel') self.dialogLayout.addWidget(self.infoLabel) @@ -53,8 +53,8 @@ class Ui_FirstTimeLanguageDialog(object): self.languageComboBox.setObjectName("languageComboBox") self.languageLayout.addWidget(self.languageComboBox) self.dialogLayout.addLayout(self.languageLayout) - self.buttonBox = create_button_box(languageDialog, u'buttonBox', [u'cancel', u'ok']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(languageDialog, u'button_box', [u'cancel', u'ok']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(languageDialog) self.setMaximumHeight(self.sizeHint().height()) diff --git a/openlp/core/ui/formattingtagdialog.py b/openlp/core/ui/formattingtagdialog.py index 1477235ab..c9cdb15df 100644 --- a/openlp/core/ui/formattingtagdialog.py +++ b/openlp/core/ui/formattingtagdialog.py @@ -29,8 +29,9 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings, create_button_box +from openlp.core.lib import translate, UiStrings +from openlp.core.lib.ui import create_button_box + class Ui_FormattingTagDialog(object): @@ -109,8 +110,8 @@ class Ui_FormattingTagDialog(object): self.savePushButton.setObjectName(u'savePushButton') self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1) self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1) - self.buttonBox = create_button_box(formattingTagDialog, u'buttonBox', [u'close']) - self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) + self.button_box = create_button_box(formattingTagDialog, u'button_box', [u'close']) + self.listdataGridLayout.addWidget(self.button_box, 3, 0, 1, 1) self.retranslateUi(formattingTagDialog) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 5ff9f7b01..2e72bdd65 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -53,7 +53,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): QtCore.QObject.connect(self.newPushButton, QtCore.SIGNAL(u'clicked()'), self.onNewClicked) QtCore.QObject.connect(self.savePushButton, QtCore.SIGNAL(u'clicked()'), self.onSavedClicked) QtCore.QObject.connect(self.deletePushButton, QtCore.SIGNAL(u'clicked()'), self.onDeleteClicked) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), self.close) + QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(u'rejected()'), self.close) QtCore.QObject.connect(self.descriptionLineEdit, QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited) QtCore.QObject.connect(self.tagLineEdit, QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited) QtCore.QObject.connect(self.startTagLineEdit, QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited) diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 3328e06e2..31a07037a 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -30,9 +30,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, SettingsTab, translate -from openlp.core.lib.ui import UiStrings -from openlp.core.ui import ScreenList +from openlp.core.lib import Receiver, Settings, SettingsTab, translate, ScreenList, UiStrings log = logging.getLogger(__name__) @@ -247,28 +245,28 @@ class GeneralTab(SettingsTab): settings.beginGroup(self.settingsSection) self.monitorComboBox.clear() self.monitorComboBox.addItems(self.screens.get_screen_list()) - monitorNumber = settings.value(u'monitor', self.screens.display_count - 1) + monitorNumber = settings.value(u'monitor') self.monitorComboBox.setCurrentIndex(monitorNumber) - self.numberEdit.setText(settings.value(u'ccli number', u'')) - self.usernameEdit.setText(settings.value(u'songselect username', u'')) - self.passwordEdit.setText(settings.value(u'songselect password', u'')) - self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt', False)) - self.autoUnblankCheckBox.setChecked(settings.value(u'auto unblank', False)) + self.numberEdit.setText(settings.value(u'ccli number')) + self.usernameEdit.setText(settings.value(u'songselect username')) + self.passwordEdit.setText(settings.value(u'songselect password')) + self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt')) + self.autoUnblankCheckBox.setChecked(settings.value(u'auto unblank')) self.displayOnMonitorCheck.setChecked(self.screens.display) - self.warningCheckBox.setChecked(settings.value(u'blank warning', False)) - self.autoOpenCheckBox.setChecked(settings.value(u'auto open', False)) - self.showSplashCheckBox.setChecked(settings.value(u'show splash', True)) - self.checkForUpdatesCheckBox.setChecked(settings.value(u'update check', True)) - self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview', False)) - self.timeoutSpinBox.setValue(settings.value(u'loop delay', 5)) - self.monitorRadioButton.setChecked(not settings.value(u'override position', False)) - self.overrideRadioButton.setChecked(settings.value(u'override position', False)) - self.customXValueEdit.setValue(settings.value(u'x position', self.screens.current[u'size'].x())) - self.customYValueEdit.setValue(settings.value(u'y position', self.screens.current[u'size'].y())) - self.customHeightValueEdit.setValue(settings.value(u'height', self.screens.current[u'size'].height())) - self.customWidthValueEdit.setValue(settings.value(u'width', self.screens.current[u'size'].width())) - self.startPausedCheckBox.setChecked(settings.value(u'audio start paused', True)) - self.repeatListCheckBox.setChecked(settings.value(u'audio repeat list', False)) + self.warningCheckBox.setChecked(settings.value(u'blank warning')) + self.autoOpenCheckBox.setChecked(settings.value(u'auto open')) + self.showSplashCheckBox.setChecked(settings.value(u'show splash')) + self.checkForUpdatesCheckBox.setChecked(settings.value(u'update check')) + self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview')) + self.timeoutSpinBox.setValue(settings.value(u'loop delay')) + self.monitorRadioButton.setChecked(not settings.value(u'override position',)) + self.overrideRadioButton.setChecked(settings.value(u'override position')) + self.customXValueEdit.setValue(settings.value(u'x position')) + self.customYValueEdit.setValue(settings.value(u'y position')) + self.customHeightValueEdit.setValue(settings.value(u'height')) + self.customWidthValueEdit.setValue(settings.value(u'width')) + self.startPausedCheckBox.setChecked(settings.value(u'audio start paused')) + self.repeatListCheckBox.setChecked(settings.value(u'audio repeat list')) settings.endGroup() self.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked()) self.customXValueEdit.setEnabled(self.overrideRadioButton.isChecked()) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index ce4f3efe4..3fed96ec4 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -38,11 +38,12 @@ import sys from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL from PyQt4.phonon import Phonon -from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, translate, PluginManager, expand_tags,\ - Settings, ImageSource +from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, translate, expand_tags,\ + Settings, ImageSource, Registry from openlp.core.lib.theme import BackgroundType -from openlp.core.ui import HideMode, ScreenList, AlertLocation +from openlp.core.lib import ScreenList +from openlp.core.ui import HideMode, AlertLocation log = logging.getLogger(__name__) @@ -65,7 +66,6 @@ class Display(QtGui.QGraphicsView): self.isLive = live self.controller = controller self.screen = {} - self.plugins = PluginManager.get_instance().plugins # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with # OpenGL. Only white blank screen is shown on the 2nd monitor all the # time. We need to investigate more how to use OpenGL properly on Mac OS @@ -115,9 +115,8 @@ class MainDisplay(Display): """ This is the display screen as a specialized class from the Display class """ - def __init__(self, parent, imageManager, live, controller): + def __init__(self, parent, live, controller): Display.__init__(self, parent, live, controller) - self.imageManager = imageManager self.screens = ScreenList() self.rebuildCSS = False self.hideMode = None @@ -131,18 +130,8 @@ class MainDisplay(Display): self.firstTime = True self.webLoaded = True self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') - windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | \ - QtCore.Qt.WindowStaysOnTopHint - # Fix for bug #1014422. - x11_bypass_default = True - if sys.platform.startswith(u'linux'): - # Default to False on Gnome. - x11_bypass_default = bool(not - os.environ.get(u'GNOME_DESKTOP_SESSION_ID')) - # Default to False on XFce - if os.environ.get(u'DESKTOP_SESSION') == u'xfce': - x11_bypass_default = False - if Settings().value(u'advanced/x11 bypass wm', x11_bypass_default): + windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint + if Settings().value(u'advanced/x11 bypass wm'): windowFlags |= QtCore.Qt.X11BypassWindowManagerHint # TODO: The following combination of windowFlags works correctly # on Mac OS X. For next OpenLP version we should test it on other @@ -182,8 +171,8 @@ class MainDisplay(Display): Call the plugins to rebuild the Live display CSS as the screen has not been rebuild on exit of config. """ - if self.rebuildCSS and self.plugins: - for plugin in self.plugins: + if self.rebuildCSS and self.plugin_manager.plugins: + for plugin in self.plugin_manager.plugins: plugin.refreshCss(self.frame) self.rebuildCSS = False @@ -204,10 +193,10 @@ class MainDisplay(Display): if self.isLive: # Build the initial frame. background_color = QtGui.QColor() - background_color.setNamedColor(Settings().value(u'advanced/default color', u'#ffffff')) + background_color.setNamedColor(Settings().value(u'advanced/default color')) if not background_color.isValid(): background_color = QtCore.Qt.white - image_file = Settings().value(u'advanced/default image', u':/graphics/openlp-splash-screen.png') + image_file = Settings().value(u'advanced/default image') splash_image = QtGui.QImage(image_file) self.initialFrame = QtGui.QImage( self.screen[u'size'].width(), @@ -222,8 +211,8 @@ class MainDisplay(Display): splash_image) serviceItem = ServiceItem() serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) - self.webView.setHtml(build_html(serviceItem, self.screen, - self.isLive, None, plugins=self.plugins)) + self.webView.setHtml(build_html(serviceItem, self.screen, self.isLive, None, + plugins=self.plugin_manager.plugins)) self.__hideMouse() log.debug(u'Finished MainDisplay setup') @@ -289,7 +278,7 @@ class MainDisplay(Display): """ API for replacement backgrounds so Images are added directly to cache. """ - self.imageManager.addImage(path, ImageSource.ImagePlugin, background) + self.image_manager.addImage(path, ImageSource.ImagePlugin, background) if not hasattr(self, u'serviceItem'): return False self.override[u'image'] = path @@ -311,8 +300,8 @@ class MainDisplay(Display): re-added to the image manager. """ log.debug(u'image to display') - image = self.imageManager.getImageBytes(path, ImageSource.ImagePlugin) - self.controller.mediaController.media_reset(self.controller) + image = self.image_manager.getImageBytes(path, ImageSource.ImagePlugin) + self.controller.media_controller.media_reset(self.controller) self.displayImage(image) def displayImage(self, image): @@ -364,7 +353,7 @@ class MainDisplay(Display): # Single screen active if self.screens.display_count == 1: # Only make visible if setting enabled. - if Settings().value(u'general/display on monitor', True): + if Settings().value(u'general/display on monitor'): self.setVisible(True) else: self.setVisible(True) @@ -392,17 +381,18 @@ class MainDisplay(Display): self.override = {} else: # replace the background - background = self.imageManager.getImageBytes(self.override[u'image'], ImageSource.ImagePlugin) + background = self.image_manager.getImageBytes(self.override[u'image'], ImageSource.ImagePlugin) self.setTransparency(self.serviceItem.themedata.background_type == BackgroundType.to_string(BackgroundType.Transparent)) if self.serviceItem.themedata.background_filename: - self.serviceItem.bg_image_bytes = self.imageManager.getImageBytes( + self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes( self.serviceItem.themedata.background_filename,ImageSource.Theme) if image_path: - image_bytes = self.imageManager.getImageBytes(image_path, ImageSource.ImagePlugin) + image_bytes = self.image_manager.getImageBytes(image_path, ImageSource.ImagePlugin) else: image_bytes = None - html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes, self.plugins) + html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes, + plugins=self.plugin_manager.plugins) log.debug(u'buildHtml - pre setHtml') self.webView.setHtml(html) log.debug(u'buildHtml - post setHtml') @@ -410,7 +400,7 @@ class MainDisplay(Display): self.footer(serviceItem.foot_text) # if was hidden keep it hidden if self.hideMode and self.isLive and not serviceItem.is_media(): - if Settings().value(u'general/auto unblank', False): + if Settings().value(u'general/auto unblank'): Receiver.send_message(u'slidecontroller_live_unblank') else: self.hideDisplay(self.hideMode) @@ -432,7 +422,7 @@ class MainDisplay(Display): log.debug(u'hideDisplay mode = %d', mode) if self.screens.display_count == 1: # Only make visible if setting enabled. - if not Settings().value(u'general/display on monitor', True): + if not Settings().value(u'general/display on monitor'): return if mode == HideMode.Screen: self.frame.evaluateJavaScript(u'show_blank("desktop");') @@ -456,7 +446,7 @@ class MainDisplay(Display): log.debug(u'showDisplay') if self.screens.display_count == 1: # Only make visible if setting enabled. - if not Settings().value(u'general/display on monitor', True): + if not Settings().value(u'general/display on monitor'): return self.frame.evaluateJavaScript('show_blank("show");') if self.isHidden(): @@ -470,13 +460,33 @@ class MainDisplay(Display): """ Hide mouse cursor when moved over display. """ - if Settings().value(u'advanced/hide mouse', True): + if Settings().value(u'advanced/hide mouse'): self.setCursor(QtCore.Qt.BlankCursor) self.frame.evaluateJavaScript('document.body.style.cursor = "none"') else: self.setCursor(QtCore.Qt.ArrowCursor) self.frame.evaluateJavaScript('document.body.style.cursor = "auto"') + def _get_plugin_manager(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) + class AudioPlayer(QtCore.QObject): """ @@ -600,3 +610,4 @@ class AudioPlayer(QtCore.QObject): #@todo is this used? def connectSlot(self, signal, slot): QtCore.QObject.connect(self.mediaObject, signal, slot) + diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 6ba7a4d6d..77e954943 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -40,9 +40,8 @@ from datetime import datetime from PyQt4 import QtCore, QtGui from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, PluginManager, Receiver, translate, ImageManager, \ - PluginStatus + PluginStatus, Registry, Settings, ScreenList from openlp.core.lib.ui import UiStrings, create_action -from openlp.core.lib import SlideLimits, Settings from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, SlideController, PluginForm, \ MediaDockManager, ShortcutListForm, FormattingTagForm from openlp.core.ui.media import MediaController @@ -50,7 +49,6 @@ from openlp.core.utils import AppLocation, add_actions, LanguageManager, get_app get_filesystem_encoding from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.ui.firsttimeform import FirstTimeForm -from openlp.core.ui import ScreenList log = logging.getLogger(__name__) @@ -80,6 +78,7 @@ PROGRESSBAR_STYLE = """ } """ + class Ui_MainWindow(object): def setupUi(self, mainWindow): """ @@ -103,10 +102,10 @@ class Ui_MainWindow(object): # Create slide controllers self.previewController = SlideController(self) self.liveController = SlideController(self, True) - previewVisible = Settings().value(u'user interface/preview panel', True) + previewVisible = Settings().value(u'user interface/preview panel') self.previewController.panel.setVisible(previewVisible) - liveVisible = Settings().value(u'user interface/live panel', True) - panelLocked = Settings().value(u'user interface/lock panel', False) + liveVisible = Settings().value(u'user interface/live panel') + panelLocked = Settings().value(u'user interface/lock panel') self.liveController.panel.setVisible(liveVisible) # Create menu self.menuBar = QtGui.QMenuBar(mainWindow) @@ -159,12 +158,12 @@ class Ui_MainWindow(object): # Create the service manager self.serviceManagerDock = OpenLPDockWidget(mainWindow, u'serviceManagerDock', u':/system/system_servicemanager.png') - self.serviceManagerContents = ServiceManager(mainWindow, self.serviceManagerDock) + self.serviceManagerContents = ServiceManager(self.serviceManagerDock) self.serviceManagerDock.setWidget(self.serviceManagerContents) mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.serviceManagerDock) # Create the theme manager self.themeManagerDock = OpenLPDockWidget(mainWindow, u'themeManagerDock', u':/system/system_thememanager.png') - self.themeManagerContents = ThemeManager(mainWindow, self.themeManagerDock) + self.themeManagerContents = ThemeManager(self.themeManagerDock) self.themeManagerContents.setObjectName(u'themeManagerContents') self.themeManagerDock.setWidget(self.themeManagerContents) mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock) @@ -175,25 +174,25 @@ class Ui_MainWindow(object): icon=u':/general/general_new.png', shortcuts=[QtGui.QKeySequence(u'Ctrl+N')], category=UiStrings().File, - triggers=self.serviceManagerContents.onNewServiceClicked) + triggers=self.serviceManagerContents.on_new_service_clicked) self.fileOpenItem = create_action(mainWindow, u'fileOpenItem', icon=u':/general/general_open.png', shortcuts=[QtGui.QKeySequence(u'Ctrl+O')], category=UiStrings().File, - triggers=self.serviceManagerContents.onLoadServiceClicked) + triggers=self.serviceManagerContents.on_load_service_clicked) self.fileSaveItem = create_action(mainWindow, u'fileSaveItem', icon=u':/general/general_save.png', shortcuts=[QtGui.QKeySequence(u'Ctrl+S')], category=UiStrings().File, - triggers=self.serviceManagerContents.saveFile) + triggers=self.serviceManagerContents.save_file) self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')], category=UiStrings().File, - triggers=self.serviceManagerContents.saveFileAs) + triggers=self.serviceManagerContents.save_file_as) self.printServiceOrderItem = create_action(mainWindow, u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')], category=UiStrings().File, - triggers=self.serviceManagerContents.printServiceOrder) + triggers=self.serviceManagerContents.print_service_order) self.fileExitItem = create_action(mainWindow, u'fileExitItem', icon=u':/system/system_exit.png', shortcuts=[QtGui.QKeySequence(u'Alt+F4')], @@ -232,7 +231,7 @@ class Ui_MainWindow(object): checked=panelLocked, triggers=self.setLockPanel) action_list.add_category(UiStrings().ViewMode, CategoryOrder.standardMenu) - self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem', checked=False, + self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem', checked=False, category=UiStrings().ViewMode) self.modeSetupItem = create_action(mainWindow, u'modeSetupItem', checked=False, category=UiStrings().ViewMode) self.modeLiveItem = create_action(mainWindow, u'modeLiveItem', checked=True, category=UiStrings().ViewMode) @@ -456,11 +455,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): plugins. """ QtGui.QMainWindow.__init__(self) + Registry().register(u'main_window', self) self.application = application self.clipboard = self.application.clipboard() self.arguments = self.application.args - # Set up settings sections for the main application - # (not for use by plugins) + # Set up settings sections for the main application (not for use by plugins). self.uiSettingsSection = u'user interface' self.generalSettingsSection = u'general' self.advancedSettingsSection = u'advanced' @@ -471,17 +470,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.playersSettingsSection = u'players' self.displayTagsSection = u'displayTags' self.headerSection = u'SettingsImport' + Settings().set_up_default_values() + Settings().remove_obsolete_settings() self.serviceNotSaved = False self.aboutForm = AboutForm(self) self.mediaController = MediaController(self) - self.settingsForm = SettingsForm(self, self) + self.settingsForm = SettingsForm(self) self.formattingTagForm = FormattingTagForm(self) self.shortcutForm = ShortcutListForm(self) self.recentFiles = [] # Set up the path with plugins plugin_path = AppLocation.get_directory(AppLocation.PluginsDir) self.pluginManager = PluginManager(plugin_path) - self.pluginHelpers = {} self.imageManager = ImageManager() # Set up the interface self.setupUi(self) @@ -528,7 +528,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_display_blank_check'), self.blankCheck) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mainwindow_status_text'), self.showStatusMessage) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'cleanup'), self.cleanUp) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'cleanup'), self.clean_up) # Media Manager QtCore.QObject.connect(self.mediaToolBox, QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged) Receiver.send_message(u'cursor_busy') @@ -542,21 +542,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # warning cyclic dependency # renderer needs to call ThemeManager and # ThemeManager needs to call Renderer - self.renderer = Renderer(self.imageManager, self.themeManagerContents) + self.renderer = Renderer() # Define the media Dock Manager self.mediaDockManager = MediaDockManager(self.mediaToolBox) log.info(u'Load Plugins') - # make the controllers available to the plugins - self.pluginHelpers[u'preview'] = self.previewController - self.pluginHelpers[u'live'] = self.liveController - self.pluginHelpers[u'renderer'] = self.renderer - self.pluginHelpers[u'service'] = self.serviceManagerContents - self.pluginHelpers[u'settings form'] = self.settingsForm - self.pluginHelpers[u'toolbox'] = self.mediaDockManager - self.pluginHelpers[u'pluginmanager'] = self.pluginManager - self.pluginHelpers[u'formparent'] = self - self.pluginHelpers[u'mediacontroller'] = self.mediaController - self.pluginManager.find_plugins(plugin_path, self.pluginHelpers) + self.pluginManager.find_plugins(plugin_path) # 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 @@ -579,8 +569,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.previewController.screenSizeChanged() self.liveController.screenSizeChanged() log.info(u'Load data from Settings') - if Settings().value(u'advanced/save current plugin', False): - savedPlugin = Settings().value(u'advanced/current media plugin', -1) + if Settings().value(u'advanced/save current plugin'): + savedPlugin = Settings().value(u'advanced/current media plugin') if savedPlugin != -1: self.mediaToolBox.setCurrentIndex(savedPlugin) self.settingsForm.postSetUp() @@ -628,11 +618,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): filename = args[0] if not isinstance(filename, unicode): filename = unicode(filename, sys.getfilesystemencoding()) - self.serviceManagerContents.loadFile(filename) - elif Settings().value( - self.generalSettingsSection + u'/auto open', False): - self.serviceManagerContents.loadLastFile() - view_mode = Settings().value(u'%s/view mode' % self.generalSettingsSection, u'default') + self.serviceManagerContents.load_file(filename) + elif Settings().value(self.generalSettingsSection + u'/auto open'): + self.serviceManagerContents.load_Last_file() + view_mode = Settings().value(u'%s/view mode' % self.generalSettingsSection) if view_mode == u'default': self.modeDefaultItem.setChecked(True) elif view_mode == u'setup': @@ -710,10 +699,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ settings = Settings() self.liveController.mainDisplaySetBackground() - if settings.value(u'%s/screen blank' % self.generalSettingsSection, - False): - if settings.value(u'%s/blank warning' % self.generalSettingsSection, - False): + if settings.value(u'%s/screen blank' % self.generalSettingsSection): + if settings.value(u'%s/blank warning' % self.generalSettingsSection): QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'), translate('OpenLP.MainWindow', 'The Main Display has been blanked out')) @@ -837,7 +824,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Lets do a basic sanity check. If it contains this string we can # assume it was created by OpenLP and so we'll load what we can # from it, and just silently ignore anything we don't recognise - if import_settings.value(u'SettingsImport/type', u'') != u'OpenLP_settings_export': + if import_settings.value(u'SettingsImport/type') != u'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.'), @@ -860,7 +847,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): continue # We have a good file, import it. for section_key in import_keys: - value = import_settings.value(section_key, None) + if u'eneral' in section_key: + section_key = section_key.lower() + value = import_settings.value(section_key) if value is not None: settings.setValue(u'%s' % (section_key), value) now = datetime.now() @@ -877,7 +866,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 'be applied the next time you start OpenLP.'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) self.settingsImported = True - self.cleanUp() + self.clean_up() QtCore.QCoreApplication.exit() def onSettingsExportItemClicked(self): @@ -926,13 +915,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): export_settings.beginGroup(self.headerSection) export_settings.setValue(u'Make_Changes', u'At_Own_RISK') export_settings.setValue(u'type', u'OpenLP_settings_export') - export_settings.setValue(u'file_date_created', - now.strftime("%Y-%m-%d %H:%M")) + export_settings.setValue(u'file_date_created', now.strftime("%Y-%m-%d %H:%M")) export_settings.setValue(u'version', application_version[u'full']) export_settings.endGroup() # Write all the sections and keys. for section_key in keys: - key_value = settings.value(section_key, None) + # FIXME: We are conflicting with the standard "General" section. + if u'eneral' in section_key: + section_key = section_key.lower() + key_value = settings.value(section_key) if key_value is not None: export_settings.setValue(section_key, key_value) export_settings.sync() @@ -940,16 +931,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Read the temp file and output the user's CONF file with blanks to # make it more readable. temp_conf = open(temp_file, u'r') - export_conf = open(export_file_name, u'w') + export_conf = open(export_file_name, u'w') for file_record in temp_conf: # Get rid of any invalid entries. if file_record.find(u'@Invalid()') == -1: - file_record = file_record.replace(u'%20', u' ') + file_record = file_record.replace(u'%20', u' ') export_conf.write(file_record) temp_conf.close() export_conf.close() os.remove(temp_file) - return def onModeDefaultItemClicked(self): """ @@ -1009,37 +999,37 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): return # If we just did a settings import, close without saving changes. if self.settingsImported: - self.cleanUp(False) + self.clean_up(False) event.accept() - if self.serviceManagerContents.isModified(): - ret = self.serviceManagerContents.saveModifiedService() + if self.serviceManagerContents.is_modified(): + ret = self.serviceManagerContents.save_modified_service() if ret == QtGui.QMessageBox.Save: - if self.serviceManagerContents.decideSaveMethod(): - self.cleanUp() + if self.serviceManagerContents.decide_save_method(): + self.clean_up() event.accept() else: event.ignore() elif ret == QtGui.QMessageBox.Discard: - self.cleanUp() + self.clean_up() event.accept() else: event.ignore() else: - if Settings().value(u'advanced/enable exit confirmation', True): + if Settings().value(u'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) if ret == QtGui.QMessageBox.Yes: - self.cleanUp() + self.clean_up() event.accept() else: event.ignore() else: - self.cleanUp() + self.clean_up() event.accept() - def cleanUp(self, save_settings=True): + def clean_up(self, save_settings=True): """ Runs all the cleanup code before OpenLP shuts down. @@ -1052,7 +1042,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Clean temporary files used by services self.serviceManagerContents.cleanUp() if save_settings: - if Settings().value(u'advanced/save current plugin', False): + if Settings().value(u'advanced/save current plugin'): Settings().setValue(u'advanced/current media plugin', self.mediaToolBox.currentIndex()) # Call the cleanup method to shutdown plugins. log.info(u'cleanup plugins') @@ -1181,28 +1171,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Load the main window settings. """ log.debug(u'Loading QSettings') - # Migrate Wrap Settings to Slide Limits Settings - if Settings().contains(self.generalSettingsSection + u'/enable slide loop'): - if Settings().value(self.generalSettingsSection + u'/enable slide loop', True): - Settings().setValue(self.advancedSettingsSection + u'/slide limits', SlideLimits.Wrap) - else: - Settings().setValue(self.advancedSettingsSection + u'/slide limits', SlideLimits.End) - Settings().remove(self.generalSettingsSection + u'/enable slide loop') - Receiver.send_message(u'slidecontroller_update_slide_limits') settings = Settings() # Remove obsolete entries. settings.remove(u'custom slide') settings.remove(u'service') settings.beginGroup(self.generalSettingsSection) - self.recentFiles = settings.value(u'recent files', self.recentFiles) + self.recentFiles = settings.value(u'recent files') settings.endGroup() settings.beginGroup(self.uiSettingsSection) - self.move(settings.value(u'main window position', QtCore.QPoint(0, 0))) - self.restoreGeometry(settings.value(u'main window geometry', QtCore.QByteArray())) - self.restoreState(settings.value(u'main window state', QtCore.QByteArray())) - self.liveController.splitter.restoreState(settings.value(u'live splitter geometry', QtCore.QByteArray())) - self.previewController.splitter.restoreState(settings.value(u'preview splitter geometry', QtCore.QByteArray())) - self.controlSplitter.restoreState(settings.value(u'mainwindow splitter geometry', QtCore.QByteArray())) + self.move(settings.value(u'main window position')) + self.restoreGeometry(settings.value(u'main window geometry')) + self.restoreState(settings.value(u'main window state')) + self.liveController.splitter.restoreState(settings.value(u'live splitter geometry')) + self.previewController.splitter.restoreState(settings.value(u'preview splitter geometry')) + self.controlSplitter.restoreState(settings.value(u'mainwindow splitter geometry')) settings.endGroup() def saveSettings(self): @@ -1231,7 +1213,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Updates the recent file menu with the latest list of service files accessed. """ - recentFileCount = Settings().value(u'advanced/recent file count', 4) + recentFileCount = Settings().value(u'advanced/recent file count') existingRecentFiles = [recentFile for recentFile in self.recentFiles if os.path.isfile(unicode(recentFile))] recentFilesToDisplay = existingRecentFiles[0:recentFileCount] @@ -1241,7 +1223,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): action = create_action(self, u'', text=u'&%d %s' % (fileId + 1, os.path.splitext(os.path.basename( unicode(filename)))[0]), data=filename, - triggers=self.serviceManagerContents.onRecentServiceClicked) + triggers=self.serviceManagerContents.on_recent_service_clicked) self.recentFilesMenu.addAction(action) clearRecentFilesAction = create_action(self, u'', text=translate('OpenLP.MainWindow', 'Clear List', 'Clear List of recent files'), @@ -1261,7 +1243,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # The maxRecentFiles value does not have an interface and so never gets # actually stored in the settings therefore the default value of 20 will # always be used. - maxRecentFiles = Settings().value(u'advanced/max recent files', 20) + maxRecentFiles = Settings().value(u'advanced/max recent files') if filename: # Add some cleanup to reduce duplication in the recent file list filename = os.path.abspath(filename) @@ -1332,7 +1314,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): '- Please wait for copy to finish').replace('%s', self.newDataPath)) dir_util.copy_tree(old_data_path, self.newDataPath) log.info(u'Copy sucessful') - except (IOError, os.error, DistutilsFileError), why: + except (IOError, os.error, DistutilsFileError), why: Receiver.send_message(u'cursor_normal') log.exception(u'Data copy failed %s' % unicode(why)) QtGui.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'New Data Directory Error'), @@ -1348,3 +1330,4 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Check if the new data path is our default. if self.newDataPath == AppLocation.get_directory(AppLocation.DataDir): settings.remove(u'advanced/data path') + diff --git a/openlp/core/ui/media/__init__.py b/openlp/core/ui/media/__init__.py index 9653bb5ce..1e4473310 100644 --- a/openlp/core/ui/media/__init__.py +++ b/openlp/core/ui/media/__init__.py @@ -76,10 +76,9 @@ def get_media_players(): from the settings. """ log.debug(u'get_media_players') - saved_players = Settings().value(u'media/players', u'webkit') + saved_players = Settings().value(u'media/players') reg_ex = QtCore.QRegExp(".*\[(.*)\].*") - if Settings().value(u'media/override player', - QtCore.Qt.Unchecked)== QtCore.Qt.Checked: + if Settings().value(u'media/override player') == QtCore.Qt.Checked: if reg_ex.exactMatch(saved_players): overridden_player = u'%s' % reg_ex.cap(1) else: @@ -103,8 +102,7 @@ def set_media_players(players_list, overridden_player=u'auto'): """ log.debug(u'set_media_players') players = u','.join(players_list) - if Settings().value(u'media/override player', QtCore.Qt.Unchecked) == QtCore.Qt.Checked and \ - overridden_player != u'auto': + if Settings().value(u'media/override player') == QtCore.Qt.Checked and overridden_player != u'auto': players = players.replace(overridden_player, u'[%s]' % overridden_player) Settings().setValue(u'media/players', players) diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index f371610f0..0ac91c226 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -32,8 +32,8 @@ import os import datetime from PyQt4 import QtCore, QtGui -from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings, Registry, UiStrings +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 from openlp.core.utils import AppLocation @@ -88,6 +88,7 @@ class MediaController(object): """ def __init__(self, parent): self.mainWindow = parent + Registry().register(u'media_controller', self) self.mediaPlayers = {} self.displayControllers = {} self.currentMediaPlayer = {} @@ -130,14 +131,14 @@ class MediaController(object): for item in player.audio_extensions_list: if not item in self.audio_extensions_list: self.audio_extensions_list.append(item) - self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:]) + self.service_manager.supported_suffixes(item[2:]) self.video_extensions_list = [] for player in self.mediaPlayers.values(): if player.isActive: for item in player.video_extensions_list: if item not in self.video_extensions_list: self.video_extensions_list.extend(item) - self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:]) + self.service_manager.supported_suffixes(item[2:]) def register_players(self, player): """ @@ -409,7 +410,7 @@ class MediaController(object): elif not hidden or controller.media_info.is_background or serviceItem.will_auto_start: autoplay = True # Unblank on load set - elif Settings().value(u'general/auto unblank', False): + elif Settings().value(u'general/auto unblank'): autoplay = True if autoplay: if not self.media_play(controller): @@ -729,3 +730,13 @@ class MediaController(object): if controller.isLive: return controller.display return controller.previewDisplay + + def _get_service_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_service_manager'): + self._service_manager = Registry().get(u'service_manager') + return self._service_manager + + service_manager = property(_get_service_manager) \ No newline at end of file diff --git a/openlp/core/ui/media/phononplayer.py b/openlp/core/ui/media/phononplayer.py index bcba26e2d..da2d19857 100644 --- a/openlp/core/ui/media/phononplayer.py +++ b/openlp/core/ui/media/phononplayer.py @@ -223,7 +223,7 @@ class PhononPlayer(MediaPlayer): """ Add css style sheets to htmlbuilder """ - background = QtGui.QColor(Settings().value(u'players/background color', u'#000000')).name() + background = QtGui.QColor(Settings().value(u'players/background color')).name() return VIDEO_CSS % (background,background,background) def get_info(self): diff --git a/openlp/core/ui/media/playertab.py b/openlp/core/ui/media/playertab.py index ee6f80246..eb1a36ca6 100644 --- a/openlp/core/ui/media/playertab.py +++ b/openlp/core/ui/media/playertab.py @@ -29,8 +29,8 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, translate, Receiver, Settings -from openlp.core.lib.ui import UiStrings, create_button +from openlp.core.lib import SettingsTab, translate, Receiver, Settings, UiStrings +from openlp.core.lib.ui import create_button from openlp.core.ui.media import get_media_players, set_media_players class MediaQCheckBox(QtGui.QCheckBox): @@ -177,7 +177,7 @@ class PlayerTab(SettingsTab): settings = Settings() settings.beginGroup(self.settingsSection) self.updatePlayerList() - self.bg_color = settings.value(u'background color', u'#000000') + self.bg_color = settings.value(u'background color') self.initial_color = self.bg_color settings.endGroup() self.backgroundColorButton.setStyleSheet(u'background-color: %s' % self.bg_color) @@ -194,7 +194,7 @@ class PlayerTab(SettingsTab): set_media_players(self.usedPlayers, override_player) player_string_changed = True if player_string_changed: - self.parent.resetSupportedSuffixes() + self.parent.reset_supported_suffixes() Receiver.send_message(u'mediaitem_media_rebuild') Receiver.send_message(u'config_screen_changed') diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index 20191d5b6..6f3e3d0e7 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -114,7 +114,7 @@ class VlcPlayer(MediaPlayer): command_line_options = u'--no-video-title-show' if not display.hasAudio: command_line_options += u' --no-audio --no-video-title-show' - if Settings().value(u'advanced/hide mouse', True) and display.controller.isLive: + if Settings().value(u'advanced/hide mouse') and display.controller.isLive: command_line_options += u' --mouse-hide-timeout=0' display.vlcInstance = vlc.Instance(command_line_options) display.vlcInstance.set_log_verbosity(2) diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index 58e7a40f5..ce72f4583 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -253,7 +253,7 @@ VIDEO_EXT = [ , u'*.mp4' , u'*.ogv' , u'*.webm' - , u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi' + , u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi' , u'*.swf' ] @@ -282,7 +282,7 @@ class WebkitPlayer(MediaPlayer): """ Add css style sheets to htmlbuilder """ - background = QtGui.QColor(Settings().value(u'players/background color', u'#000000')).name() + background = QtGui.QColor(Settings().value(u'players/background color')).name() css = VIDEO_CSS % (background,background,background) return css + FLASH_CSS @@ -411,13 +411,13 @@ class WebkitPlayer(MediaPlayer): else: if display.frame.evaluateJavaScript(u'show_video("isEnded");') == 'true': self.stop(display) - (currentTime, ok) = display.frame.evaluateJavaScript(u'show_video("currentTime");') + currentTime = display.frame.evaluateJavaScript(u'show_video("currentTime");') # check if conversion was ok and value is not 'NaN' - if ok and currentTime != float('inf'): + if currentTime and currentTime != float('inf'): currentTime = int(currentTime * 1000) - (length, ok) = display.frame.evaluateJavaScript(u'show_video("length");') + length = display.frame.evaluateJavaScript(u'show_video("length");') # check if conversion was ok and value is not 'NaN' - if ok and length != float('inf'): + if length and length != float('inf'): length = int(length * 1000) if currentTime > 0: controller.media_info.length = length diff --git a/openlp/core/ui/plugindialog.py b/openlp/core/ui/plugindialog.py index eca4f2de2..401cab924 100644 --- a/openlp/core/ui/plugindialog.py +++ b/openlp/core/ui/plugindialog.py @@ -29,8 +29,9 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings, create_button_box +from openlp.core.lib import translate, UiStrings +from openlp.core.lib.ui import create_button_box + class Ui_PluginViewDialog(object): def setupUi(self, pluginViewDialog): @@ -66,8 +67,8 @@ class Ui_PluginViewDialog(object): self.pluginInfoLayout.addRow(self.aboutLabel, self.aboutTextBrowser) self.listLayout.addWidget(self.pluginInfoGroupBox) self.pluginLayout.addLayout(self.listLayout) - self.buttonBox = create_button_box(pluginViewDialog, u'buttonBox', [u'ok']) - self.pluginLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(pluginViewDialog, u'button_box', [u'ok']) + self.pluginLayout.addWidget(self.button_box) self.retranslateUi(pluginViewDialog) def retranslateUi(self, pluginViewDialog): diff --git a/openlp/core/ui/printservicedialog.py b/openlp/core/ui/printservicedialog.py index 3fd49dc7a..0a7ab4874 100644 --- a/openlp/core/ui/printservicedialog.py +++ b/openlp/core/ui/printservicedialog.py @@ -29,8 +29,7 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon, translate, SpellTextEdit -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import build_icon, translate, SpellTextEdit, UiStrings class ZoomSize(object): """ diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py index 70afca604..d10fe7ba0 100644 --- a/openlp/core/ui/printserviceform.py +++ b/openlp/core/ui/printserviceform.py @@ -33,8 +33,7 @@ import os from PyQt4 import QtCore, QtGui from lxml import html -from openlp.core.lib import translate, get_text_file_string, Receiver, Settings -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import translate, get_text_file_string, Receiver, Settings, UiStrings, Registry from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize from openlp.core.utils import AppLocation @@ -109,13 +108,11 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): - def __init__(self, mainWindow, serviceManager): + def __init__(self): """ Constructor """ - QtGui.QDialog.__init__(self, mainWindow) - self.mainWindow = mainWindow - self.serviceManager = serviceManager + QtGui.QDialog.__init__(self, self.main_window) self.printer = QtGui.QPrinter() self.printDialog = QtGui.QPrintDialog(self.printer, self) self.document = QtGui.QTextDocument() @@ -124,13 +121,13 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): # Load the settings for the dialog. settings = Settings() settings.beginGroup(u'advanced') - self.slideTextCheckBox.setChecked(settings.value(u'print slide text', False)) - self.pageBreakAfterText.setChecked(settings.value(u'add page break', False)) + self.slideTextCheckBox.setChecked(settings.value(u'print slide text')) + self.pageBreakAfterText.setChecked(settings.value(u'add page break')) if not self.slideTextCheckBox.isChecked(): self.pageBreakAfterText.setDisabled(True) - self.metaDataCheckBox.setChecked(settings.value(u'print file meta data', False)) - self.notesCheckBox.setChecked(settings.value(u'print notes', False)) - self.zoomComboBox.setCurrentIndex(settings.value(u'display size', 0)) + self.metaDataCheckBox.setChecked(settings.value(u'print file meta data')) + self.notesCheckBox.setChecked(settings.value(u'print notes')) + self.zoomComboBox.setCurrentIndex(settings.value(u'display size')) settings.endGroup() # Signals QtCore.QObject.connect(self.printButton, QtCore.SIGNAL(u'triggered()'), self.printServiceOrder) @@ -141,7 +138,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): QtCore.QObject.connect(self.zoomComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'), self.displaySizeChanged) QtCore.QObject.connect(self.plainCopy, QtCore.SIGNAL(u'triggered()'), self.copyText) QtCore.QObject.connect(self.htmlCopy, QtCore.SIGNAL(u'triggered()'), self.copyHtmlText) - QtCore.QObject.connect(self.slideTextCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTextCheckBoxChanged) + QtCore.QObject.connect(self.slideTextCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), + self.onSlideTextCheckBoxChanged) self.updatePreviewText() def toggleOptions(self, checked): @@ -171,7 +169,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): self._addElement(u'body', parent=html_data) self._addElement(u'h1', cgi.escape(self.titleLineEdit.text()), html_data.body, classId=u'serviceTitle') - for index, item in enumerate(self.serviceManager.serviceItems): + for index, item in enumerate(self.service_manager.serviceItems): self._addPreviewItem(html_data.body, item[u'service_item'], index) # Add the custom service notes: if self.footerTextEdit.toPlainText(): @@ -320,14 +318,14 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): # remove the icon from the text clipboard_text = clipboard_text.replace(u'\ufffc\xa0', u'') # and put it all on the clipboard - self.mainWindow.clipboard.setText(clipboard_text) + self.main_window.clipboard.setText(clipboard_text) def copyHtmlText(self): """ Copies the display text to the clipboard as Html """ self.update_song_usage() - self.mainWindow.clipboard.setText(self.document.toHtml()) + self.main_window.clipboard.setText(self.document.toHtml()) def printServiceOrder(self): """ @@ -393,6 +391,26 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): # Only continue when we include the song's text. if not self.slideTextCheckBox.isChecked(): return - for item in self.serviceManager.serviceItems: + for item in self.service_manager.serviceItems: # Trigger Audit requests Receiver.send_message(u'print_service_started', [item[u'service_item']]) + + def _get_service_manager(self): + """ + Adds the service manager to the class dynamically + """ + if not hasattr(self, u'_service_manager'): + self._service_manager = Registry().get(u'service_manager') + return self._service_manager + + service_manager = property(_get_service_manager) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) \ No newline at end of file diff --git a/openlp/core/ui/serviceitemeditdialog.py b/openlp/core/ui/serviceitemeditdialog.py index b8537d557..638bf4460 100644 --- a/openlp/core/ui/serviceitemeditdialog.py +++ b/openlp/core/ui/serviceitemeditdialog.py @@ -35,29 +35,29 @@ from openlp.core.lib.ui import create_button_box, create_button class Ui_ServiceItemEditDialog(object): def setupUi(self, serviceItemEditDialog): serviceItemEditDialog.setObjectName(u'serviceItemEditDialog') - self.dialogLayout = QtGui.QGridLayout(serviceItemEditDialog) - self.dialogLayout.setContentsMargins(8, 8, 8, 8) - self.dialogLayout.setSpacing(8) - self.dialogLayout.setObjectName(u'dialogLayout') - self.listWidget = QtGui.QListWidget(serviceItemEditDialog) - self.listWidget.setAlternatingRowColors(True) - self.listWidget.setObjectName(u'listWidget') - self.dialogLayout.addWidget(self.listWidget, 0, 0) - self.buttonLayout = QtGui.QVBoxLayout() - self.buttonLayout.setObjectName(u'buttonLayout') - self.deleteButton = create_button(serviceItemEditDialog, u'deleteButton', role=u'delete', - click=serviceItemEditDialog.onDeleteButtonClicked) - self.buttonLayout.addWidget(self.deleteButton) - self.buttonLayout.addStretch() - self.upButton = create_button(serviceItemEditDialog, u'upButton', role=u'up', - click=serviceItemEditDialog.onUpButtonClicked) - self.downButton = create_button(serviceItemEditDialog, u'downButton', role=u'down', - click=serviceItemEditDialog.onDownButtonClicked) - self.buttonLayout.addWidget(self.upButton) - self.buttonLayout.addWidget(self.downButton) - self.dialogLayout.addLayout(self.buttonLayout, 0, 1) - self.buttonBox = create_button_box(serviceItemEditDialog, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) + self.dialog_layout = QtGui.QGridLayout(serviceItemEditDialog) + self.dialog_layout.setContentsMargins(8, 8, 8, 8) + self.dialog_layout.setSpacing(8) + self.dialog_layout.setObjectName(u'dialog_layout') + self.list_widget = QtGui.QListWidget(serviceItemEditDialog) + self.list_widget.setAlternatingRowColors(True) + self.list_widget.setObjectName(u'list_widget') + self.dialog_layout.addWidget(self.list_widget, 0, 0) + self.button_layout = QtGui.QVBoxLayout() + self.button_layout.setObjectName(u'button_layout') + self.delete_button = create_button(serviceItemEditDialog, u'deleteButton', role=u'delete', + click=serviceItemEditDialog.on_delete_button_clicked) + self.button_layout.addWidget(self.delete_button) + self.button_layout.addStretch() + self.up_button = create_button(serviceItemEditDialog, u'upButton', role=u'up', + click=serviceItemEditDialog.on_up_button_clicked) + self.down_button = create_button(serviceItemEditDialog, u'downButton', role=u'down', + click=serviceItemEditDialog.on_down_button_clicked) + self.button_layout.addWidget(self.up_button) + self.button_layout.addWidget(self.down_button) + self.dialog_layout.addLayout(self.button_layout, 0, 1) + self.button_box = create_button_box(serviceItemEditDialog, u'button_box', [u'cancel', u'save']) + self.dialog_layout.addWidget(self.button_box, 1, 0, 1, 2) self.retranslateUi(serviceItemEditDialog) def retranslateUi(self, serviceItemEditDialog): diff --git a/openlp/core/ui/serviceitemeditform.py b/openlp/core/ui/serviceitemeditform.py index 5392d6418..58d8a5399 100644 --- a/openlp/core/ui/serviceitemeditform.py +++ b/openlp/core/ui/serviceitemeditform.py @@ -28,6 +28,7 @@ ############################################################################### from PyQt4 import QtCore, QtGui +from openlp.core.lib import Registry from serviceitemeditdialog import Ui_ServiceItemEditDialog @@ -35,91 +36,92 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog): """ This is the form that is used to edit the verses of the song. """ - def __init__(self, parent=None): + def __init__(self): """ Constructor """ - QtGui.QDialog.__init__(self, parent) + QtGui.QDialog.__init__(self, self.main_window) self.setupUi(self) - self.itemList = [] - QtCore.QObject.connect(self.listWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) + self.item_list = [] + QtCore.QObject.connect(self.list_widget, QtCore.SIGNAL(u'currentRowChanged(int)'), + self.on_current_row_changed) - def setServiceItem(self, item): + def set_service_item(self, item): self.item = item - self.itemList = [] + self.item_list = [] if self.item.is_image(): self.data = True for frame in self.item._raw_frames: - self.itemList.append(frame) - self.loadData() - self.listWidget.setCurrentItem(self.listWidget.currentItem()) + self.item_list.append(frame) + self.load_data() + self.list_widget.setCurrentItem(self.list_widget.currentItem()) - def getServiceItem(self): + def get_service_item(self): if self.data: self.item._raw_frames = [] if self.item.is_image(): - for item in self.itemList: + for item in self.item_list: self.item.add_from_image(item[u'path'], item[u'title']) self.item.render() return self.item - def loadData(self): + def load_data(self): """ Loads the image list. """ - self.listWidget.clear() - for frame in self.itemList: + self.list_widget.clear() + for frame in self.item_list: item_name = QtGui.QListWidgetItem(frame[u'title']) - self.listWidget.addItem(item_name) + self.list_widget.addItem(item_name) - def onDeleteButtonClicked(self): + def on_delete_button_clicked(self): """ Delete the current row. """ - item = self.listWidget.currentItem() + item = self.list_widget.currentItem() if not item: return - row = self.listWidget.row(item) - self.itemList.pop(row) - self.loadData() - if row == self.listWidget.count(): - self.listWidget.setCurrentRow(row - 1) + row = self.list_widget.row(item) + self.item_list.pop(row) + self.load_data() + if row == self.list_widget.count(): + self.list_widget.setCurrentRow(row - 1) else: - self.listWidget.setCurrentRow(row) + self.list_widget.setCurrentRow(row) - def onUpButtonClicked(self): + def on_up_button_clicked(self): """ Move the current row up in the list. """ - self.__moveItem(u'up') + self.__move_item(u'up') - def onDownButtonClicked(self): + def on_down_button_clicked(self): """ Move the current row down in the list """ - self.__moveItem(u'down') + self.__move_item(u'down') - def __moveItem(self, direction=u''): + def __move_item(self, direction=u''): """ Move the current item. """ if not direction: return - item = self.listWidget.currentItem() + item = self.list_widget.currentItem() if not item: return - row = self.listWidget.row(item) - temp = self.itemList[row] - self.itemList.pop(row) + row = self.list_widget.row(item) + temp = self.item_list[row] + self.item_list.pop(row) if direction == u'up': row -= 1 else: row += 1 - self.itemList.insert(row, temp) - self.loadData() - self.listWidget.setCurrentRow(row) + self.item_list.insert(row, temp) + self.load_data() + self.list_widget.setCurrentRow(row) - def onCurrentRowChanged(self, row): + def on_current_row_changed(self, row): """ Called when the currentRow has changed. @@ -127,19 +129,29 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog): The row number (int). """ # Disable all buttons, as no row is selected or only one image is left. - if row == -1 or self.listWidget.count() == 1: - self.downButton.setEnabled(False) - self.upButton.setEnabled(False) - self.deleteButton.setEnabled(False) + if row == -1 or self.list_widget.count() == 1: + self.down_button.setEnabled(False) + self.up_button.setEnabled(False) + self.delete_button.setEnabled(False) else: # Check if we are at the end of the list. - if self.listWidget.count() == row + 1: - self.downButton.setEnabled(False) + if self.list_widget.count() == row + 1: + self.down_button.setEnabled(False) else: - self.downButton.setEnabled(True) + self.down_button.setEnabled(True) # Check if we are at the beginning of the list. if row == 0: - self.upButton.setEnabled(False) + self.up_button.setEnabled(False) else: - self.upButton.setEnabled(True) - self.deleteButton.setEnabled(True) + self.up_button.setEnabled(True) + self.delete_button.setEnabled(True) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) \ No newline at end of file diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 8a9b01d04..fe1023bbf 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -40,9 +40,9 @@ log = logging.getLogger(__name__) from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \ - translate, str_to_bool, check_directory_exists, Settings, PluginStatus + translate, str_to_bool, check_directory_exists, Settings, PluginStatus, Registry, UiStrings from openlp.core.lib.theme import ThemeLevel -from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_widget_action, find_and_set_in_combo_box +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 from openlp.core.utils import AppLocation, delete_file, split_filename, format_time @@ -57,13 +57,16 @@ class ServiceManagerList(QtGui.QTreeWidget): self.serviceManager = serviceManager def keyPressEvent(self, event): + """ + Capture Key press and respond accordingly. + """ if isinstance(event, QtGui.QKeyEvent): # here accept the event and do something if event.key() == QtCore.Qt.Key_Up: - self.serviceManager.onMoveSelectionUp() + self.serviceManager.on_move_selection_up() event.accept() elif event.key() == QtCore.Qt.Key_Down: - self.serviceManager.onMoveSelectionDown() + self.serviceManager.on_move_selection_down() event.accept() elif event.key() == QtCore.Qt.Key_Delete: self.serviceManager.onDeleteFromService() @@ -85,153 +88,128 @@ class ServiceManagerList(QtGui.QTreeWidget): event.ignore() return drag = QtGui.QDrag(self) - mimeData = QtCore.QMimeData() - drag.setMimeData(mimeData) - mimeData.setText(u'ServiceManager') + mime_data = QtCore.QMimeData() + drag.setMimeData(mime_data) + mime_data.setText(u'ServiceManager') drag.start(QtCore.Qt.CopyAction) - -class ServiceManager(QtGui.QWidget): +class ServiceManagerDialog(object): """ - Manages the services. This involves taking text strings from plugins and - adding them to the service. This service can then be zipped up with all - the resources used into one OSZ or oszl file for use on any OpenLP v2 - installation. Also handles the UI tasks of moving things up and down etc. """ - def __init__(self, mainwindow, parent=None): - """ - Sets up the service manager, toolbars, list view, et al. - """ - QtGui.QWidget.__init__(self, parent) - self.active = build_icon(QtGui.QImage(u':/media/auto-start_active.png')) - self.inactive = build_icon(QtGui.QImage(u':/media/auto-start_inactive.png')) - self.mainwindow = mainwindow - self.serviceItems = [] - self.suffixes = [] - self.dropPosition = 0 - self.expandTabs = False - self.serviceId = 0 - # is a new service and has not been saved - self._modified = False - self._fileName = u'' - self.service_has_all_original_files = True - self.serviceNoteForm = ServiceNoteForm(self.mainwindow) - self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow) - self.startTimeForm = StartTimeForm(self.mainwindow) - # start with the layout - self.layout = QtGui.QVBoxLayout(self) - self.layout.setSpacing(0) - self.layout.setMargin(0) + def setup_ui(self,widget): # Create the top toolbar self.toolbar = OpenLPToolbar(self) self.toolbar.addToolbarAction(u'newService', text=UiStrings().NewService, icon=u':/general/general_new.png', - tooltip=UiStrings().CreateService, triggers=self.onNewServiceClicked) + tooltip=UiStrings().CreateService, triggers=self.on_new_service_clicked) self.toolbar.addToolbarAction(u'openService', text=UiStrings().OpenService, icon=u':/general/general_open.png', - tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'), triggers=self.onLoadServiceClicked) + tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'), triggers=self.on_load_service_clicked) self.toolbar.addToolbarAction(u'saveService', text=UiStrings().SaveService, icon=u':/general/general_save.png', - tooltip=translate('OpenLP.ServiceManager', 'Save this service.'), triggers=self.decideSaveMethod) + tooltip=translate('OpenLP.ServiceManager', 'Save this service.'), triggers=self.decide_save_method) self.toolbar.addSeparator() - self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self) - self.themeLabel.setMargin(3) - self.themeLabel.setObjectName(u'themeLabel') - self.toolbar.addToolbarWidget(self.themeLabel) - self.themeComboBox = QtGui.QComboBox(self.toolbar) - self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager', 'Select a theme for the service.')) - self.themeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength) - self.themeComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.themeComboBox.setObjectName(u'themeComboBox') - self.toolbar.addToolbarWidget(self.themeComboBox) + self.theme_label = QtGui.QLabel(u'%s:' % UiStrings().Theme, self) + self.theme_label.setMargin(3) + self.theme_label.setObjectName(u'theme_label') + self.toolbar.addToolbarWidget(self.theme_label) + self.theme_combo_box = QtGui.QComboBox(self.toolbar) + self.theme_combo_box.setToolTip(translate('OpenLP.ServiceManager', 'Select a theme for the service.')) + self.theme_combo_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength) + self.theme_combo_box.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) + self.theme_combo_box.setObjectName(u'theme_combo_box') + self.toolbar.addToolbarWidget(self.theme_combo_box) self.toolbar.setObjectName(u'toolbar') self.layout.addWidget(self.toolbar) # Create the service manager list - self.serviceManagerList = ServiceManagerList(self) - self.serviceManagerList.setEditTriggers( + self.service_manager_list = ServiceManagerList(self) + self.service_manager_list.setEditTriggers( QtGui.QAbstractItemView.CurrentChanged | QtGui.QAbstractItemView.DoubleClicked | QtGui.QAbstractItemView.EditKeyPressed) - self.serviceManagerList.setDragDropMode(QtGui.QAbstractItemView.DragDrop) - self.serviceManagerList.setAlternatingRowColors(True) - self.serviceManagerList.setHeaderHidden(True) - self.serviceManagerList.setExpandsOnDoubleClick(False) - self.serviceManagerList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - QtCore.QObject.connect(self.serviceManagerList, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), - self.contextMenu) - self.serviceManagerList.setObjectName(u'serviceManagerList') + self.service_manager_list.setDragDropMode(QtGui.QAbstractItemView.DragDrop) + self.service_manager_list.setAlternatingRowColors(True) + self.service_manager_list.setHeaderHidden(True) + self.service_manager_list.setExpandsOnDoubleClick(False) + self.service_manager_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), + self.context_menu) + self.service_manager_list.setObjectName(u'service_manager_list') # enable drop - self.serviceManagerList.__class__.dragEnterEvent = self.dragEnterEvent - self.serviceManagerList.__class__.dragMoveEvent = self.dragEnterEvent - self.serviceManagerList.__class__.dropEvent = self.dropEvent - self.layout.addWidget(self.serviceManagerList) + self.service_manager_list.__class__.dragEnterEvent = self.drag_enter_event + self.service_manager_list.__class__.dragMoveEvent = self.drag_enter_event + self.service_manager_list.__class__.dropEvent = self.drop_event + self.layout.addWidget(self.service_manager_list) # Add the bottom toolbar - self.orderToolbar = OpenLPToolbar(self) + self.order_toolbar = OpenLPToolbar(self) action_list = ActionList.get_instance() - action_list.add_category( - UiStrings().Service, CategoryOrder.standardToolbar) - self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(u'moveTop', + action_list.add_category(UiStrings().Service, CategoryOrder.standardToolbar) + self.service_manager_list.moveTop = self.order_toolbar.addToolbarAction(u'moveTop', text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=u':/services/service_top.png', tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'), shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service, triggers=self.onServiceTop) - self.serviceManagerList.moveUp = self.orderToolbar.addToolbarAction(u'moveUp', + self.service_manager_list.moveUp = self.order_toolbar.addToolbarAction(u'moveUp', text=translate('OpenLP.ServiceManager', 'Move &up'), icon=u':/services/service_up.png', tooltip=translate('OpenLP.ServiceManager', 'Move item up one position in the service.'), shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service, triggers=self.onServiceUp) - self.serviceManagerList.moveDown = self.orderToolbar.addToolbarAction(u'moveDown', + self.service_manager_list.moveDown = self.order_toolbar.addToolbarAction(u'moveDown', text=translate('OpenLP.ServiceManager', 'Move &down'), icon=u':/services/service_down.png', tooltip=translate('OpenLP.ServiceManager', 'Move item down one position in the service.'), shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service, triggers=self.onServiceDown) - self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarAction(u'moveBottom', + self.service_manager_list.moveBottom = self.order_toolbar.addToolbarAction(u'moveBottom', text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=u':/services/service_bottom.png', tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'), shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service, triggers=self.onServiceEnd) - self.serviceManagerList.down = self.orderToolbar.addToolbarAction(u'down', + self.service_manager_list.down = self.order_toolbar.addToolbarAction(u'down', text=translate('OpenLP.ServiceManager', 'Move &down'), tooltip=translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), visible=False, - shortcuts=[QtCore.Qt.Key_Down], triggers=self.onMoveSelectionDown) - action_list.add_action(self.serviceManagerList.down) - self.serviceManagerList.up = self.orderToolbar.addToolbarAction(u'up', + shortcuts=[QtCore.Qt.Key_Down], triggers=self.on_move_selection_down) + action_list.add_action(self.service_manager_list.down) + self.service_manager_list.up = self.order_toolbar.addToolbarAction(u'up', text=translate('OpenLP.ServiceManager', 'Move up'), tooltip=translate('OpenLP.ServiceManager', - 'Moves the selection up the window.'), visible=False, shortcuts=[QtCore.Qt.Key_Up], - triggers=self.onMoveSelectionUp) - action_list.add_action(self.serviceManagerList.up) - self.orderToolbar.addSeparator() - self.serviceManagerList.delete = self.orderToolbar.addToolbarAction(u'delete', + 'Moves the selection up the window.'), visible=False, shortcuts=[QtCore.Qt.Key_Up], + triggers=self.on_move_selection_up) + action_list.add_action(self.service_manager_list.up) + self.order_toolbar.addSeparator() + self.service_manager_list.delete = self.order_toolbar.addToolbarAction(u'delete', text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=u':/general/general_delete.png', tooltip=translate('OpenLP.ServiceManager', 'Delete the selected item from the service.'), shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteFromService) - self.orderToolbar.addSeparator() - self.serviceManagerList.expand = self.orderToolbar.addToolbarAction(u'expand', + self.order_toolbar.addSeparator() + self.service_manager_list.expand = self.order_toolbar.addToolbarAction(u'expand', text=translate('OpenLP.ServiceManager', '&Expand all'), icon=u':/services/service_expand_all.png', tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'), shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service, triggers=self.onExpandAll) - self.serviceManagerList.collapse = self.orderToolbar.addToolbarAction(u'collapse', + self.service_manager_list.collapse = self.order_toolbar.addToolbarAction(u'collapse', text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=u':/services/service_collapse_all.png', tooltip=translate('OpenLP.ServiceManager', 'Collapse all the service items.'), shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service, triggers=self.onCollapseAll) - self.orderToolbar.addSeparator() - self.serviceManagerList.makeLive = self.orderToolbar.addToolbarAction(u'makeLive', + self.order_toolbar.addSeparator() + self.service_manager_list.make_live = self.order_toolbar.addToolbarAction(u'make_live', text=translate('OpenLP.ServiceManager', 'Go Live'), icon=u':/general/general_live.png', tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'), - shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], category=UiStrings().Service, triggers=self.makeLive) - self.layout.addWidget(self.orderToolbar) + shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], category=UiStrings().Service, triggers=self.make_live) + self.layout.addWidget(self.order_toolbar) # Connect up our signals and slots - QtCore.QObject.connect(self.themeComboBox, QtCore.SIGNAL(u'activated(int)'), self.onThemeComboBoxSelected) - QtCore.QObject.connect(self.serviceManagerList, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onMakeLive) - QtCore.QObject.connect(self.serviceManagerList, QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), + QtCore.QObject.connect(self.theme_combo_box, QtCore.SIGNAL(u'activated(int)'), + self.on_theme_combo_box_selected) + QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), + self.on_make_live) + QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), self.collapsed) - QtCore.QObject.connect(self.serviceManagerList, QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_preview_live'), self.previewLive) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) + QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), + self.expanded) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.update_theme_list) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_preview_live'), + self.preview_live) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_next_item'), self.next_item) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_previous_item'), - self.previousItem) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_set_item'), self.onSetItem) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated) + self.previous_item) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_set_item'), self.on_set_item) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), - self.regenerateServiceItems) + self.regenerate_service_Items) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_global'), self.themeChange) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate) # Last little bits of setting up - self.service_theme = Settings().value(self.mainwindow.serviceManagerSettingsSection + u'/service theme', u'') + self.service_theme = Settings().value(self.main_window.serviceManagerSettingsSection + u'/service theme') self.servicePath = AppLocation.get_section_data_path(u'servicemanager') # build the drag and drop context menu self.dndMenu = QtGui.QMenu() @@ -241,109 +219,151 @@ class ServiceManager(QtGui.QWidget): self.addToAction.setIcon(build_icon(u':/general/general_edit.png')) # build the context menu self.menu = QtGui.QMenu() - self.editAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'), - icon=u':/general/general_edit.png', triggers=self.remoteEdit) - self.maintainAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Reorder Item'), - icon=u':/general/general_edit.png', triggers=self.onServiceItemEditForm) - self.notesAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Notes'), - icon=u':/services/service_notes.png', triggers=self.onServiceItemNoteForm) - self.timeAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Start Time'), - icon=u':/media/media_time.png', triggers=self.onStartTimeForm) - self.autoStartAction = create_widget_action(self.menu, text=u'', - icon=u':/media/auto-start_active.png', triggers=self.onAutoStart) + self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'), + icon=u':/general/general_edit.png', triggers=self.remote_edit) + self.maintain_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Reorder Item'), + icon=u':/general/general_edit.png', triggers=self.on_service_item_edit_form) + self.notes_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Notes'), + icon=u':/services/service_notes.png', triggers=self.on_service_item_note_form) + self.time_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Start Time'), + icon=u':/media/media_time.png', triggers=self.on_start_time_form) + self.auto_start_action = create_widget_action(self.menu, text=u'', + icon=u':/media/auto-start_active.png', triggers=self.on_auto_start) # Add already existing delete action to the menu. - self.menu.addAction(self.serviceManagerList.delete) + self.menu.addAction(self.service_manager_list.delete) self.create_custom_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Create New &Custom Slide'), icon=u':/general/general_edit.png', triggers=self.create_custom) self.menu.addSeparator() # Add AutoPlay menu actions - self.autoPlaySlidesGroup = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Auto play slides')) - self.menu.addMenu(self.autoPlaySlidesGroup) - self.autoPlaySlidesLoop = create_widget_action(self.autoPlaySlidesGroup, + self.auto_play_slides_group = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Auto play slides')) + self.menu.addMenu(self.auto_play_slides_group) + self.auto_play_slides_loop = create_widget_action(self.auto_play_slides_group, text=translate('OpenLP.ServiceManager', 'Auto play slides &Loop'), - checked=False, triggers=self.toggleAutoPlaySlidesLoop) - self.autoPlaySlidesOnce = create_widget_action(self.autoPlaySlidesGroup, + checked=False, triggers=self.toggle_auto_play_slides_loop) + self.auto_play_slides_once = create_widget_action(self.auto_play_slides_group, text=translate('OpenLP.ServiceManager', 'Auto play slides &Once'), - checked=False, triggers=self.toggleAutoPlaySlidesOnce) - self.autoPlaySlidesGroup.addSeparator() - self.timedSlideInterval = create_widget_action(self.autoPlaySlidesGroup, + checked=False, triggers=self.toggle_auto_play_slides_once) + self.auto_play_slides_group.addSeparator() + self.timed_slide_interval = create_widget_action(self.auto_play_slides_group, text=translate('OpenLP.ServiceManager', '&Delay between slides'), - checked=False, triggers=self.onTimedSlideInterval) + checked=False, triggers=self.on_timed_slide_interval) self.menu.addSeparator() - self.previewAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'), - icon=u':/general/general_preview.png', triggers=self.makePreview) + self.preview_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'), + icon=u':/general/general_preview.png', triggers=self.make_preview) # Add already existing make live action to the menu. - self.menu.addAction(self.serviceManagerList.makeLive) + self.menu.addAction(self.service_manager_list.make_live) self.menu.addSeparator() - self.themeMenu = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme')) - self.menu.addMenu(self.themeMenu) - self.serviceManagerList.addActions( - [self.serviceManagerList.moveDown, - self.serviceManagerList.moveUp, - self.serviceManagerList.makeLive, - self.serviceManagerList.moveTop, - self.serviceManagerList.moveBottom, - self.serviceManagerList.up, - self.serviceManagerList.down, - self.serviceManagerList.expand, - self.serviceManagerList.collapse + self.theme_menu = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme')) + self.menu.addMenu(self.theme_menu) + self.service_manager_list.addActions( + [self.service_manager_list.moveDown, + self.service_manager_list.moveUp, + self.service_manager_list.make_live, + self.service_manager_list.moveTop, + self.service_manager_list.moveBottom, + self.service_manager_list.up, + self.service_manager_list.down, + self.service_manager_list.expand, + self.service_manager_list.collapse ]) - self.configUpdated() - def setModified(self, modified=True): + def drag_enter_event(self, event): + """ + Accept Drag events + + ``event`` + Handle of the event pint passed + """ + event.accept() + + +class ServiceManager(QtGui.QWidget, ServiceManagerDialog): + """ + Manages the services. This involves taking text strings from plugins and + adding them to the service. This service can then be zipped up with all + the resources used into one OSZ or oszl file for use on any OpenLP v2 + installation. Also handles the UI tasks of moving things up and down etc. + """ + def __init__(self, parent=None): + """ + Sets up the service manager, toolbars, list view, et al. + """ + QtGui.QWidget.__init__(self, parent) + self.active = build_icon(QtGui.QImage(u':/media/auto-start_active.png')) + self.inactive = build_icon(QtGui.QImage(u':/media/auto-start_inactive.png')) + Registry().register(u'service_manager', self) + self.service_items = [] + self.suffixes = [] + self.drop_position = 0 + self.expand_tabs = False + self.service_id = 0 + # is a new service and has not been saved + self._modified = False + self._file_name = u'' + self.service_has_all_original_files = True + self.serviceNoteForm = ServiceNoteForm() + self.serviceItemEditForm = ServiceItemEditForm() + self.startTimeForm = StartTimeForm() + # start with the layout + self.layout = QtGui.QVBoxLayout(self) + self.layout.setSpacing(0) + self.layout.setMargin(0) + self.setup_ui(self) + self.config_updated() + + def set_modified(self, modified=True): """ Setter for property "modified". Sets whether or not the current service has been modified. """ if modified: - self.serviceId += 1 + self.service_id += 1 self._modified = modified - serviceFile = self.shortFileName() or translate('OpenLP.ServiceManager', 'Untitled Service') - self.mainwindow.setServiceModified(modified, serviceFile) + service_file = self.short_file_name() or translate('OpenLP.ServiceManager', 'Untitled Service') + self.main_window.setServiceModified(modified, service_file) - def isModified(self): + def is_modified(self): """ Getter for boolean property "modified". """ return self._modified - def setFileName(self, fileName): + def set_file_name(self, file_name): """ Setter for service file. """ - self._fileName = unicode(fileName) - self.mainwindow.setServiceModified(self.isModified(), - self.shortFileName()) - Settings().setValue(u'servicemanager/last file', fileName) - self._saveLite = self._fileName.endswith(u'.oszl') + self._file_name = unicode(file_name) + self.main_window.setServiceModified(self.is_modified(), self.short_file_name()) + Settings().setValue(u'servicemanager/last file', file_name) + self._saveLite = self._file_name.endswith(u'.oszl') - def fileName(self): + def file_name(self): """ Return the current file name including path. """ - return self._fileName + return self._file_name - def shortFileName(self): + def short_file_name(self): """ Return the current file name, excluding the path. """ - return split_filename(self._fileName)[1] + return split_filename(self._file_name)[1] - def configUpdated(self): + def config_updated(self): """ Triggered when Config dialog is updated. """ - self.expandTabs = Settings().value(u'advanced/expand service item', False) + self.expand_tabs = Settings().value(u'advanced/expand service item') - def resetSupportedSuffixes(self): + def reset_supported_suffixes(self): """ Resets the Suffixes list. """ self.suffixes = [] - def supportedSuffixes(self, suffix): + def supported_suffixes(self, suffix): """ Adds Suffixes supported to the master list. Called from Plugins. @@ -353,70 +373,77 @@ class ServiceManager(QtGui.QWidget): if not suffix in self.suffixes: self.suffixes.append(suffix) - def onNewServiceClicked(self): + def on_new_service_clicked(self): """ Create a new service. """ - if self.isModified(): - result = self.saveModifiedService() + if self.is_modified(): + result = self.save_modified_service() if result == QtGui.QMessageBox.Cancel: return False elif result == QtGui.QMessageBox.Save: - if not self.decideSaveMethod(): + if not self.decide_save_method(): return False - self.newFile() + self.new_file() - def onLoadServiceClicked(self, loadFile=None): + def on_load_service_clicked(self, load_file=None): """ Loads the service file and saves the existing one it there is one unchanged - ``loadFile`` + ``load_file`` The service file to the loaded. Will be None is from menu so selection will be required. """ - if self.isModified(): - result = self.saveModifiedService() + if self.is_modified(): + result = self.save_modified_service() if result == QtGui.QMessageBox.Cancel: return False elif result == QtGui.QMessageBox.Save: - self.decideSaveMethod() - if not loadFile: - fileName = QtGui.QFileDialog.getOpenFileName(self.mainwindow, + self.decide_save_method() + if not load_file: + file_name = QtGui.QFileDialog.getOpenfile_name(self.main_window, translate('OpenLP.ServiceManager', 'Open File'), - SettingsManager.get_last_dir(self.mainwindow.serviceManagerSettingsSection), - translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)')) - if not fileName: + SettingsManager.get_last_dir(self.main_window.serviceManagerSettingsSection), + translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)')) + if not file_name: return False else: - fileName = loadFile - SettingsManager.set_last_dir(self.mainwindow.serviceManagerSettingsSection, split_filename(fileName)[0]) - self.loadFile(fileName) + file_name = load_file + Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', + split_filename(file_name)[0]) + self.load_file(file_name) - def saveModifiedService(self): - return QtGui.QMessageBox.question(self.mainwindow, + def save_modified_service(self): + """ + Check to see if a service needs to be saved. + """ + return QtGui.QMessageBox.question(self.main_window, translate('OpenLP.ServiceManager', 'Modified Service'), translate('OpenLP.ServiceManager', 'The current service has been modified. Would you like to save this service?'), QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save) - def onRecentServiceClicked(self): + def on_recent_service_clicked(self): + """ + Load a recent file as the service triggered by mainwindow recent service list. + """ sender = self.sender() - self.loadFile(sender.data()) + self.load_file(sender.data()) - def newFile(self): + def new_file(self): """ Create a blank new service file. """ - self.serviceManagerList.clear() - self.serviceItems = [] - self.setFileName(u'') - self.serviceId += 1 - self.setModified(False) + self.service_manager_list.clear() + self.service_items = [] + self.set_file_name(u'') + self.service_id += 1 + self.set_modified(False) Settings().setValue(u'servicemanager/last file', u'') Receiver.send_message(u'servicemanager_new_service') - def saveFile(self): + def save_file(self): """ Save the current service file. @@ -425,18 +452,18 @@ class ServiceManager(QtGui.QWidget): Audio files are also copied into the service manager directory, and then packaged into the zip file. """ - if not self.fileName(): - return self.saveFileAs() + if not self.file_name(): + return self.save_file_as() temp_file, temp_file_name = mkstemp(u'.osz', u'openlp_') # We don't need the file handle. os.close(temp_file) log.debug(temp_file_name) - path_file_name = unicode(self.fileName()) + path_file_name = unicode(self.file_name()) path, file_name = os.path.split(path_file_name) - basename = os.path.splitext(file_name)[0] - service_file_name = '%s.osd' % basename - log.debug(u'ServiceManager.saveFile - %s', path_file_name) - SettingsManager.set_last_dir(self.mainwindow.serviceManagerSettingsSection, path) + base_name = os.path.splitext(file_name)[0] + service_file_name = '%s.osd' % base_name + log.debug(u'ServiceManager.save_file - %s', path_file_name) + Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path) service = [] write_list = [] missing_list = [] @@ -444,9 +471,9 @@ class ServiceManager(QtGui.QWidget): total_size = 0 Receiver.send_message(u'cursor_busy') # Number of items + 1 to zip it - self.mainwindow.displayProgressBar(len(self.serviceItems) + 1) + self.main_window.displayProgressBar(len(self.service_items) + 1) # Get list of missing files, and list of files to write - for item in self.serviceItems: + for item in self.service_items: if not item[u'service_item'].uses_file(): continue for frame in item[u'service_item'].get_frames(): @@ -466,50 +493,48 @@ class ServiceManager(QtGui.QWidget): answer = QtGui.QMessageBox.critical(self, title, message, QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)) if answer == QtGui.QMessageBox.Cancel: - self.mainwindow.finishedProgressBar() + self.main_window.finishedProgressBar() return False Receiver.send_message(u'cursor_busy') # Check if item contains a missing file. - for item in list(self.serviceItems): - self.mainwindow.incrementProgressBar() + for item in list(self.service_items): + self.main_window.incrementProgressBar() item[u'service_item'].remove_invalid_frames(missing_list) if item[u'service_item'].missing_frames(): - self.serviceItems.remove(item) + self.service_items.remove(item) else: service_item = item[u'service_item'].get_service_repr(self._saveLite) if service_item[u'header'][u'background_audio']: - for i, filename in enumerate( - service_item[u'header'][u'background_audio']): - new_file = os.path.join(u'audio', - item[u'service_item']._uuid, filename) - audio_files.append((filename, new_file)) + for i, file_name in enumerate(service_item[u'header'][u'background_audio']): + new_file = os.path.join(u'audio', item[u'service_item'].unique_identifier, file_name) + audio_files.append((file_name, new_file)) service_item[u'header'][u'background_audio'][i] = new_file # Add the service item to the service. service.append({u'serviceitem': service_item}) - self.repaintServiceList(-1, -1) - for file in write_list: - file_size = os.path.getsize(file) + self.repaint_service_list(-1, -1) + for file_item in write_list: + file_size = os.path.getsize(file_item) total_size += file_size - log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' % total_size) + log.debug(u'ServiceManager.save_file - ZIP contents size is %i bytes' % total_size) service_content = cPickle.dumps(service) # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be # extracted using unzip in UNIX. allow_zip_64 = (total_size > 2147483648 + len(service_content)) - log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64) - zip = None + log.debug(u'ServiceManager.save_file - allowZip64 is %s' % allow_zip_64) + zip_file = None success = True - self.mainwindow.incrementProgressBar() + self.main_window.incrementProgressBar() try: - zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) + zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) # First we add service contents. - # We save ALL filenames into ZIP using UTF-8. - zip.writestr(service_file_name.encode(u'utf-8'), service_content) + # We save ALL file_names into ZIP using UTF-8. + zip_file.writestr(service_file_name.encode(u'utf-8'), service_content) # Finally add all the listed media files. for write_from in write_list: - zip.write(write_from, write_from.encode(u'utf-8')) + zip_file.write(write_from, write_from.encode(u'utf-8')) for audio_from, audio_to in audio_files: if audio_from.startswith(u'audio'): - # When items are saved, they get new UUID's. Let's copy the + # When items are saved, they get new unique_identifier. Let's copy the # file to the new location. Unused files can be ignored, # OpenLP automatically cleans up the service manager dir on # exit. @@ -519,7 +544,7 @@ class ServiceManager(QtGui.QWidget): check_directory_exists(save_path) if not os.path.exists(save_file): shutil.copy(audio_from, save_file) - zip.write(audio_from, audio_to.encode(u'utf-8')) + zip_file.write(audio_from, audio_to.encode(u'utf-8')) except IOError: log.exception(u'Failed to save service to disk: %s', temp_file_name) Receiver.send_message(u'openlp_error_message', { @@ -528,60 +553,56 @@ class ServiceManager(QtGui.QWidget): }) success = False finally: - if zip: - zip.close() - self.mainwindow.finishedProgressBar() + if zip_file: + zip_file.close() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') if success: try: shutil.copy(temp_file_name, path_file_name) except: - return self.saveFileAs() - self.mainwindow.addRecentFile(path_file_name) - self.setModified(False) + return self.save_file_as() + self.main_window.addRecentFile(path_file_name) + self.set_modified(False) delete_file(temp_file_name) return success - def saveLocalFile(self): + def save_local_file(self): """ - Save the current service file. - - A temporary file is created so that we don't overwrite the existing one - and leave a mangled service file should there be an error when saving. - No files are added to this version of the service as it is deisgned - to only work on the machine it was save on if there are files. + Save the current service file but leave all the file references alone to point to the current machine. + This format is not transportable as it will not contain any files. """ - if not self.fileName(): - return self.saveFileAs() + if not self.file_name(): + return self.save_file_as() temp_file, temp_file_name = mkstemp(u'.oszl', u'openlp_') # We don't need the file handle. os.close(temp_file) log.debug(temp_file_name) - path_file_name = unicode(self.fileName()) + path_file_name = unicode(self.file_name()) path, file_name = os.path.split(path_file_name) - basename = os.path.splitext(file_name)[0] - service_file_name = '%s.osd' % basename - log.debug(u'ServiceManager.saveFile - %s', path_file_name) - SettingsManager.set_last_dir(self.mainwindow.serviceManagerSettingsSection, path) + base_name = os.path.splitext(file_name)[0] + service_file_name = '%s.osd' % base_name + log.debug(u'ServiceManager.save_file - %s', path_file_name) + Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path) service = [] Receiver.send_message(u'cursor_busy') # Number of items + 1 to zip it - self.mainwindow.displayProgressBar(len(self.serviceItems) + 1) - for item in self.serviceItems: - self.mainwindow.incrementProgressBar() + self.main_window.displayProgressBar(len(self.service_items) + 1) + for item in self.service_items: + self.main_window.incrementProgressBar() service_item = item[u'service_item'].get_service_repr(self._saveLite) #@todo check for file item on save. service.append({u'serviceitem': service_item}) - self.mainwindow.incrementProgressBar() + self.main_window.incrementProgressBar() service_content = cPickle.dumps(service) - zip = None + zip_file = None success = True - self.mainwindow.incrementProgressBar() + self.main_window.incrementProgressBar() try: - zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, + zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, True) # First we add service contents. - zip.writestr(service_file_name.encode(u'utf-8'), service_content) + zip_file.writestr(service_file_name.encode(u'utf-8'), service_content) except IOError: log.exception(u'Failed to save service to disk: %s', temp_file_name) Receiver.send_message(u'openlp_error_message', { @@ -590,97 +611,93 @@ class ServiceManager(QtGui.QWidget): }) success = False finally: - if zip: - zip.close() - self.mainwindow.finishedProgressBar() + if zip_file: + zip_file.close() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') if success: try: shutil.copy(temp_file_name, path_file_name) except: - return self.saveFileAs() - self.mainwindow.addRecentFile(path_file_name) - self.setModified(False) + return self.save_file_as() + self.main_window.addRecentFile(path_file_name) + self.set_modified(False) delete_file(temp_file_name) return success - def saveFileAs(self): + def save_file_as(self): """ - Get a file name and then call :func:`ServiceManager.saveFile` to + Get a file name and then call :func:`ServiceManager.save_file` to save the file. """ - default_service_enabled = Settings().value(u'advanced/default service enabled', True) + default_service_enabled = Settings().value(u'advanced/default service enabled') if default_service_enabled: - service_day = Settings().value(u'advanced/default service day', 7) + service_day = Settings().value(u'advanced/default service day') if service_day == 7: local_time = datetime.now() else: - service_hour = Settings().value(u'advanced/default service hour', 11) - service_minute = Settings().value(u'advanced/default service minute', 0) + service_hour = Settings().value(u'advanced/default service hour') + service_minute = Settings().value(u'advanced/default service minute') now = datetime.now() day_delta = service_day - now.weekday() if day_delta < 0: day_delta += 7 time = now + timedelta(days=day_delta) local_time = time.replace(hour=service_hour, minute=service_minute) - default_pattern = Settings().value(u'advanced/default service name', - translate('OpenLP.AdvancedTab', 'Service %Y-%m-%d %H-%M', - 'This may not contain any of the following characters: ' - '/\\?*|<>\[\]":+\nSee http://docs.python.org/library/' - 'datetime.html#strftime-strptime-behavior for more information.')) - default_filename = format_time(default_pattern, local_time) + default_pattern = Settings().value(u'advanced/default service name') + default_file_name = format_time(default_pattern, local_time) else: - default_filename = u'' - directory = SettingsManager.get_last_dir(self.mainwindow.serviceManagerSettingsSection) - path = os.path.join(directory, default_filename) + default_file_name = u'' + directory = Settings().value(self.main_window.serviceManagerSettingsSection + u'/last directory') + path = os.path.join(directory, default_file_name) # SaveAs from osz to oszl is not valid as the files will be deleted # on exit which is not sensible or usable in the long term. - if self._fileName.endswith(u'oszl') or self.service_has_all_original_files: - fileName = QtGui.QFileDialog.getSaveFileName(self.mainwindow, UiStrings().SaveService, path, + if self._file_name.endswith(u'oszl') or self.service_has_all_original_files: + file_name = QtGui.QFileDialog.getSavefile_name(self.main_window, UiStrings().SaveService, path, translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);; OpenLP Service Files - lite (*.oszl)')) else: - fileName = QtGui.QFileDialog.getSaveFileName(self.mainwindow, UiStrings().SaveService, path, + file_name = QtGui.QFileDialog.getSavefile_name(self.main_window, UiStrings().SaveService, path, translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);;')) - if not fileName: + if not file_name: return False - if os.path.splitext(fileName)[1] == u'': - fileName += u'.osz' + if os.path.splitext(file_name)[1] == u'': + file_name += u'.osz' else: - ext = os.path.splitext(fileName)[1] - fileName.replace(ext, u'.osz') - self.setFileName(fileName) - self.decideSaveMethod() + ext = os.path.splitext(file_name)[1] + file_name.replace(ext, u'.osz') + self.set_file_name(file_name) + self.decide_save_method() - def decideSaveMethod(self): + def decide_save_method(self): """ Determine which type of save method to use. """ - if not self.fileName(): - return self.saveFileAs() + if not self.file_name(): + return self.save_file_as() if self._saveLite: - return self.saveLocalFile() + return self.save_local_file() else: - return self.saveFile() + return self.save_file() - def loadFile(self, fileName): + def load_file(self, file_name): """ Load an existing service file """ - if not fileName: + if not file_name: return False - fileName = unicode(fileName) - if not os.path.exists(fileName): + file_name = unicode(file_name) + if not os.path.exists(file_name): return False - zip = None - fileTo = None + zip_file = None + file_to = None try: - zip = zipfile.ZipFile(fileName) - for zipinfo in zip.infolist(): + zip_file = zipfile.ZipFile(file_name) + for zip_info in zip_file.infolist(): try: - ucsfile = zipinfo.filename.decode(u'utf-8') + ucsfile = zip_info.filename.decode(u'utf-8') except UnicodeDecodeError: - log.exception(u'Filename "%s" is not valid UTF-8' % zipinfo.filename.decode(u'utf-8', u'replace')) + log.exception(u'file_name "%s" is not valid UTF-8' % zip_info.file_name.decode(u'utf-8', u'replace')) critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.\n The content encoding is not UTF-8.')) continue @@ -688,197 +705,202 @@ class ServiceManager(QtGui.QWidget): if not osfile.startswith(u'audio'): osfile = os.path.split(osfile)[1] log.debug(u'Extract file: %s', osfile) - zipinfo.filename = osfile - zip.extract(zipinfo, self.servicePath) + zip_info.filename = osfile + zip_file.extract(zip_info, self.servicePath) if osfile.endswith(u'osd'): p_file = os.path.join(self.servicePath, osfile) if 'p_file' in locals(): Receiver.send_message(u'cursor_busy') - fileTo = open(p_file, u'r') - items = cPickle.load(fileTo) - fileTo.close() - self.newFile() - self.setFileName(fileName) - self.mainwindow.displayProgressBar(len(items)) + file_to = open(p_file, u'r') + items = cPickle.load(file_to) + file_to.close() + self.new_file() + self.set_file_name(file_name) + self.main_window.displayProgressBar(len(items)) for item in items: - self.mainwindow.incrementProgressBar() - serviceItem = ServiceItem() - serviceItem.renderer = self.mainwindow.renderer + self.main_window.incrementProgressBar() + service_item = ServiceItem() if self._saveLite: - serviceItem.set_from_service(item) + service_item.set_from_service(item) else: - serviceItem.set_from_service(item, self.servicePath) - serviceItem.validate_item(self.suffixes) - self.load_item_uuid = 0 - if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate): - Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) + service_item.set_from_service(item, self.servicePath) + service_item.validate_item(self.suffixes) + self.load_item_unique_identifier = 0 + if service_item.is_capable(ItemCapabilities.OnLoadUpdate): + Receiver.send_message(u'%s_service_load' % service_item.name.lower(), service_item) # if the item has been processed - if serviceItem._uuid == self.load_item_uuid: - serviceItem.edit_id = int(self.load_item_edit_id) - serviceItem.temporary_edit = self.load_item_temporary - self.addServiceItem(serviceItem, repaint=False) + if service_item.unique_identifier == self.load_item_unique_identifier: + service_item.edit_id = int(self.load_item_edit_id) + service_item.temporary_edit = self.load_item_temporary + self.add_service_item(service_item, repaint=False) delete_file(p_file) - self.mainwindow.addRecentFile(fileName) - self.setModified(False) - Settings().setValue('servicemanager/last file', fileName) + self.main_window.addRecentFile(file_name) + self.set_modified(False) + Settings().setValue('servicemanager/last file', file_name) else: critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) log.exception(u'File contains no service data') except (IOError, NameError, zipfile.BadZipfile): - log.exception(u'Problem loading service file %s' % fileName) + log.exception(u'Problem loading service file %s' % file_name) critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File could not be opened because it is corrupt.')) except zipfile.BadZipfile: - if os.path.getsize(fileName) == 0: - log.exception(u'Service file is zero sized: %s' % fileName) + if os.path.getsize(file_name) == 0: + log.exception(u'Service file is zero sized: %s' % file_name) QtGui.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'), translate('OpenLP.ServiceManager', 'This service file does not contain any data.')) else: log.exception(u'Service file is cannot be extracted as zip: ' - u'%s' % fileName) + u'%s' % file_name) QtGui.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'), translate('OpenLP.ServiceManager', 'This file is either corrupt or it is not an OpenLP 2 service file.')) return finally: - if fileTo: - fileTo.close() - if zip: - zip.close() - self.mainwindow.finishedProgressBar() + if file_to: + file_to.close() + if zip_file: + zip_file.close() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') - self.repaintServiceList(-1, -1) + self.repaint_service_list(-1, -1) - def loadLastFile(self): + def load_Last_file(self): """ Load the last service item from the service manager when the service was last closed. Can be blank if there was no service present. """ - fileName = Settings().value(u'servicemanager/last file', u'') - if fileName: - self.loadFile(fileName) + file_name = Settings().value(u'servicemanager/last file') + if file_name: + self.load_file(file_name) - def contextMenu(self, point): - item = self.serviceManagerList.itemAt(point) + def context_menu(self, point): + """ + The Right click context menu from the Serviceitem list + """ + item = self.service_manager_list.itemAt(point) if item is None: return if item.parent(): pos = item.parent().data(0, QtCore.Qt.UserRole) else: pos = item.data(0, QtCore.Qt.UserRole) - serviceItem = self.serviceItems[pos - 1] - self.editAction.setVisible(False) + service_item = self.service_items[pos - 1] + self.edit_action.setVisible(False) self.create_custom_action.setVisible(False) - self.maintainAction.setVisible(False) - self.notesAction.setVisible(False) - self.timeAction.setVisible(False) - self.autoStartAction.setVisible(False) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanEdit) and serviceItem[u'service_item'].edit_id: - self.editAction.setVisible(True) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanMaintain): - self.maintainAction.setVisible(True) + self.maintain_action.setVisible(False) + self.notes_action.setVisible(False) + self.time_action.setVisible(False) + self.auto_start_action.setVisible(False) + if service_item[u'service_item'].is_capable(ItemCapabilities.CanEdit) and service_item[u'service_item'].edit_id: + self.edit_action.setVisible(True) + if service_item[u'service_item'].is_capable(ItemCapabilities.CanMaintain): + self.maintain_action.setVisible(True) if item.parent() is None: - self.notesAction.setVisible(True) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \ - len(serviceItem[u'service_item'].get_frames()) > 1: - self.autoPlaySlidesGroup.menuAction().setVisible(True) - self.autoPlaySlidesOnce.setChecked(serviceItem[u'service_item'].auto_play_slides_once) - self.autoPlaySlidesLoop.setChecked(serviceItem[u'service_item'].auto_play_slides_loop) - self.timedSlideInterval.setChecked(serviceItem[u'service_item'].timed_slide_interval > 0) - if serviceItem[u'service_item'].timed_slide_interval > 0: - delay_suffix = u' ' - delay_suffix += unicode(serviceItem[u'service_item'].timed_slide_interval) - delay_suffix += u' s' + self.notes_action.setVisible(True) + if service_item[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \ + len(service_item[u'service_item'].get_frames()) > 1: + self.auto_play_slides_group.menuAction().setVisible(True) + self.auto_play_slides_once.setChecked(service_item[u'service_item'].auto_play_slides_once) + self.auto_play_slides_loop.setChecked(service_item[u'service_item'].auto_play_slides_loop) + self.timed_slide_interval.setChecked(service_item[u'service_item'].timed_slide_interval > 0) + if service_item[u'service_item'].timed_slide_interval > 0: + delay_suffix = u' %s s' % unicode(service_item[u'service_item'].timed_slide_interval) else: delay_suffix = u' ...' - self.timedSlideInterval.setText(translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix) + self.timed_slide_interval.setText(translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix) # TODO for future: make group explains itself more visually else: - self.autoPlaySlidesGroup.menuAction().setVisible(False) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.HasVariableStartTime): - self.timeAction.setVisible(True) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.CanAutoStartForLive): - self.autoStartAction.setVisible(True) - self.autoStartAction.setIcon(self.inactive) - self.autoStartAction.setText(translate('OpenLP.ServiceManager','&Auto Start - inactive')) - if serviceItem[u'service_item'].will_auto_start: - self.autoStartAction.setText(translate('OpenLP.ServiceManager', '&Auto Start - active')) - self.autoStartAction.setIcon(self.active) - if serviceItem[u'service_item'].is_text(): - for plugin in self.mainwindow.pluginManager.plugins: + self.auto_play_slides_group.menuAction().setVisible(False) + if service_item[u'service_item'].is_capable(ItemCapabilities.HasVariableStartTime): + self.time_action.setVisible(True) + if service_item[u'service_item'].is_capable(ItemCapabilities.CanAutoStartForLive): + self.auto_start_action.setVisible(True) + self.auto_start_action.setIcon(self.inactive) + self.auto_start_action.setText(translate('OpenLP.ServiceManager','&Auto Start - inactive')) + if service_item[u'service_item'].will_auto_start: + self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - active')) + self.auto_start_action.setIcon(self.active) + if service_item[u'service_item'].is_text(): + for plugin in self.plugin_manager.plugins: if plugin.name == u'custom' and plugin.status == PluginStatus.Active: self.create_custom_action.setVisible(True) break - self.themeMenu.menuAction().setVisible(False) + self.theme_menu.menuAction().setVisible(False) # Set up the theme menu. - if serviceItem[u'service_item'].is_text() and self.mainwindow.renderer.theme_level == ThemeLevel.Song: - self.themeMenu.menuAction().setVisible(True) + if service_item[u'service_item'].is_text() and self.renderer.theme_level == ThemeLevel.Song: + self.theme_menu.menuAction().setVisible(True) # The service item does not have a theme, check the "Default". - if serviceItem[u'service_item'].theme is None: - themeAction = self.themeMenu.defaultAction() + if service_item[u'service_item'].theme is None: + theme_action = self.theme_menu.defaultAction() else: - themeAction = self.themeMenu.findChild(QtGui.QAction, serviceItem[u'service_item'].theme) - if themeAction is not None: - themeAction.setChecked(True) - self.menu.exec_(self.serviceManagerList.mapToGlobal(point)) + theme_action = self.theme_menu.findChild(QtGui.QAction, service_item[u'service_item'].theme) + if theme_action is not None: + theme_action.setChecked(True) + self.menu.exec_(self.service_manager_list.mapToGlobal(point)) - def onServiceItemNoteForm(self): - item = self.findServiceItem()[0] - self.serviceNoteForm.textEdit.setPlainText( - self.serviceItems[item][u'service_item'].notes) + def on_service_item_note_form(self): + """ + Allow the service note to be edited + """ + item = self.find_service_item()[0] + self.serviceNoteForm.text_edit.setPlainText(self.service_items[item][u'service_item'].notes) if self.serviceNoteForm.exec_(): - self.serviceItems[item][u'service_item'].notes = self.serviceNoteForm.textEdit.toPlainText() - self.repaintServiceList(item, -1) - self.setModified() + self.service_items[item][u'service_item'].notes = self.serviceNoteForm.text_edit.toPlainText() + self.repaint_service_list(item, -1) + self.set_modified() - def onStartTimeForm(self): + def on_start_time_form(self): """ Opens a dialog to type in service item notes. """ - item = self.findServiceItem()[0] - self.startTimeForm.item = self.serviceItems[item] + item = self.find_service_item()[0] + self.startTimeForm.item = self.service_items[item] if self.startTimeForm.exec_(): - self.repaintServiceList(item, -1) + self.repaint_service_list(item, -1) - def toggleAutoPlaySlidesOnce(self): + def toggle_auto_play_slides_once(self): """ Toggle Auto play slide once. Inverts auto play once option for the item """ - item = self.findServiceItem()[0] - service_item = self.serviceItems[item][u'service_item'] + item = self.find_service_item()[0] + service_item = self.service_items[item][u'service_item'] service_item.auto_play_slides_once = not service_item.auto_play_slides_once if service_item.auto_play_slides_once: service_item.auto_play_slides_loop = False - self.autoPlaySlidesLoop.setChecked(False) + self.auto_play_slides_loop.setChecked(False) if service_item.auto_play_slides_once and service_item.timed_slide_interval == 0: - service_item.timed_slide_interval = Settings().value(u'loop delay', 5) - self.setModified() + service_item.timed_slide_interval = Settings().value( + self.main_window.generalSettingsSection + u'/loop delay') + self.set_modified() - def toggleAutoPlaySlidesLoop(self): + + def toggle_auto_play_slides_loop(self): """ Toggle Auto play slide loop. """ - item = self.findServiceItem()[0] - service_item = self.serviceItems[item][u'service_item'] + item = self.find_service_item()[0] + service_item = self.service_items[item][u'service_item'] service_item.auto_play_slides_loop = not service_item.auto_play_slides_loop if service_item.auto_play_slides_loop: service_item.auto_play_slides_once = False - self.autoPlaySlidesOnce.setChecked(False) + self.auto_play_slides_once.setChecked(False) if service_item.auto_play_slides_loop and service_item.timed_slide_interval == 0: - service_item.timed_slide_interval = Settings().value(u'loop delay', 5) - self.setModified() + service_item.timed_slide_interval = Settings().value( + self.main_window.generalSettingsSection + u'/loop delay') + self.set_modified() - def onTimedSlideInterval(self): + + def on_timed_slide_interval(self): """ - on set times slide interval. Shows input dialog for enter interval in seconds for delay """ - item = self.findServiceItem()[0] - service_item = self.serviceItems[item][u'service_item'] + item = self.find_service_item()[0] + service_item = self.service_items[item][u'service_item'] if service_item.timed_slide_interval == 0: - timed_slide_interval = Settings().value(u'loop delay', 5) + timed_slide_interval = Settings().value(self.mainwindow.generalSettingsSection + u'/loop delay') else: timed_slide_interval = service_item.timed_slide_interval timed_slide_interval, ok = QtGui.QInputDialog.getInteger(self, translate('OpenLP.ServiceManager', @@ -886,88 +908,87 @@ class ServiceManager(QtGui.QWidget): timed_slide_interval, 0, 180, 1) if ok: service_item.timed_slide_interval = timed_slide_interval - if service_item.timed_slide_interval <> 0 and not service_item.auto_play_slides_loop\ - and not service_item.auto_play_slides_once: + if service_item.timed_slide_interval != 0 and not service_item.auto_play_slides_loop \ + and not service_item.auto_play_slides_once: service_item.auto_play_slides_loop = True elif service_item.timed_slide_interval == 0: service_item.auto_play_slides_loop = False service_item.auto_play_slides_once = False - self.setModified() + self.set_modified() - def onAutoStart(self): + def on_auto_start(self): """ Toggles to Auto Start Setting. """ - item = self.findServiceItem()[0] - self.serviceItems[item][u'service_item'].will_auto_start = \ - not self.serviceItems[item][u'service_item'].will_auto_start + item = self.find_service_item()[0] + self.service_items[item][u'service_item'].will_auto_start = \ + not self.service_items[item][u'service_item'].will_auto_start - def onServiceItemEditForm(self): + def on_service_item_edit_form(self): """ Opens a dialog to edit the service item and update the service display if changes are saved. """ - item = self.findServiceItem()[0] - self.serviceItemEditForm.setServiceItem( - self.serviceItems[item][u'service_item']) + item = self.find_service_item()[0] + self.serviceItemEditForm.set_service_item(self.service_items[item][u'service_item']) if self.serviceItemEditForm.exec_(): - self.addServiceItem(self.serviceItemEditForm.getServiceItem(), - replace=True, expand=self.serviceItems[item][u'expanded']) + self.add_service_item(self.serviceItemEditForm.get_service_item(), + replace=True, expand=self.service_items[item][u'expanded']) - def previewLive(self, message): + def preview_live(self, message): """ Called by the SlideController to request a preview item be made live and allows the next preview to be updated if relevant. """ - uuid, row = message.split(u':') - for sitem in self.serviceItems: - if sitem[u'service_item']._uuid == uuid: - item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1) - self.serviceManagerList.setCurrentItem(item) - self.makeLive(int(row)) + unique_identifier, row = message.split(u':') + for sitem in self.service_items: + if sitem[u'service_item'].unique_identifier == unique_identifier: + item = self.service_manager_list.topLevelItem(sitem[u'order'] - 1) + self.service_manager_list.setCurrentItem(item) + self.make_live(int(row)) return - def nextItem(self): + def next_item(self): """ Called by the SlideController to select the next service item. """ - if not self.serviceManagerList.selectedItems(): + if not self.service_manager_list.selectedItems(): return - selected = self.serviceManagerList.selectedItems()[0] + selected = self.service_manager_list.selectedItems()[0] lookFor = 0 - serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) + serviceIterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list) while serviceIterator.value(): if lookFor == 1 and serviceIterator.value().parent() is None: - self.serviceManagerList.setCurrentItem(serviceIterator.value()) - self.makeLive() + self.service_manager_list.setCurrentItem(serviceIterator.value()) + self.make_live() return if serviceIterator.value() == selected: lookFor = 1 serviceIterator += 1 - def previousItem(self, message): + def previous_item(self, message): """ Called by the SlideController to select the previous service item. """ - if not self.serviceManagerList.selectedItems(): + if not self.service_manager_list.selectedItems(): return - selected = self.serviceManagerList.selectedItems()[0] + selected = self.service_manager_list.selectedItems()[0] prevItem = None prevItemLastSlide = None - serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) + serviceIterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list) while serviceIterator.value(): if serviceIterator.value() == selected: if message == u'last slide' and prevItemLastSlide: pos = prevItem.data(0, QtCore.Qt.UserRole) - check_expanded = self.serviceItems[pos - 1][u'expanded'] - self.serviceManagerList.setCurrentItem(prevItemLastSlide) + check_expanded = self.service_items[pos - 1][u'expanded'] + self.service_manager_list.setCurrentItem(prevItemLastSlide) if not check_expanded: - self.serviceManagerList.collapseItem(prevItem) - self.makeLive() - self.serviceManagerList.setCurrentItem(prevItem) + self.service_manager_list.collapseItem(prevItem) + self.make_live() + self.service_manager_list.setCurrentItem(prevItem) elif prevItem: - self.serviceManagerList.setCurrentItem(prevItem) - self.makeLive() + self.service_manager_list.setCurrentItem(prevItem) + self.make_live() return if serviceIterator.value().parent() is None: prevItem = serviceIterator.value() @@ -975,50 +996,50 @@ class ServiceManager(QtGui.QWidget): prevItemLastSlide = serviceIterator.value() serviceIterator += 1 - def onSetItem(self, message): + def on_set_item(self, message): """ Called by a signal to select a specific item. """ - self.setItem(int(message)) + self.set_item(int(message)) - def setItem(self, index): + def set_item(self, index): """ Makes a specific item in the service live. """ - if index >= 0 and index < self.serviceManagerList.topLevelItemCount: - item = self.serviceManagerList.topLevelItem(index) - self.serviceManagerList.setCurrentItem(item) - self.makeLive() + if index >= 0 and index < self.service_manager_list.topLevelItemCount: + item = self.service_manager_list.topLevelItem(index) + self.service_manager_list.setCurrentItem(item) + self.make_live() - def onMoveSelectionUp(self): + def on_move_selection_up(self): """ Moves the cursor selection up the window. Called by the up arrow. """ - item = self.serviceManagerList.currentItem() - itemBefore = self.serviceManagerList.itemAbove(item) + item = self.service_manager_list.currentItem() + itemBefore = self.service_manager_list.itemAbove(item) if itemBefore is None: return - self.serviceManagerList.setCurrentItem(itemBefore) + self.service_manager_list.setCurrentItem(itemBefore) - def onMoveSelectionDown(self): + def on_move_selection_down(self): """ Moves the cursor selection down the window. Called by the down arrow. """ - item = self.serviceManagerList.currentItem() - itemAfter = self.serviceManagerList.itemBelow(item) + item = self.service_manager_list.currentItem() + itemAfter = self.service_manager_list.itemBelow(item) if itemAfter is None: return - self.serviceManagerList.setCurrentItem(itemAfter) + self.service_manager_list.setCurrentItem(itemAfter) def onCollapseAll(self): """ Collapse all the service items. """ - for item in self.serviceItems: + for item in self.service_items: item[u'expanded'] = False - self.serviceManagerList.collapseAll() + self.service_manager_list.collapseAll() def collapsed(self, item): """ @@ -1026,15 +1047,15 @@ class ServiceManager(QtGui.QWidget): correct state. """ pos = item.data(0, QtCore.Qt.UserRole) - self.serviceItems[pos - 1][u'expanded'] = False + self.service_items[pos - 1][u'expanded'] = False def onExpandAll(self): """ Collapse all the service items. """ - for item in self.serviceItems: + for item in self.service_items: item[u'expanded'] = True - self.serviceManagerList.expandAll() + self.service_manager_list.expandAll() def expanded(self, item): """ @@ -1042,67 +1063,67 @@ class ServiceManager(QtGui.QWidget): correct state. """ pos = item.data(0, QtCore.Qt.UserRole) - self.serviceItems[pos - 1][u'expanded'] = True + self.service_items[pos - 1][u'expanded'] = True def onServiceTop(self): """ Move the current ServiceItem to the top of the list. """ - item, child = self.findServiceItem() - if item < len(self.serviceItems) and item != -1: - temp = self.serviceItems[item] - self.serviceItems.remove(self.serviceItems[item]) - self.serviceItems.insert(0, temp) - self.repaintServiceList(0, child) - self.setModified() + item, child = self.find_service_item() + if item < len(self.service_items) and item != -1: + temp = self.service_items[item] + self.service_items.remove(self.service_items[item]) + self.service_items.insert(0, temp) + self.repaint_service_list(0, child) + self.set_modified() def onServiceUp(self): """ Move the current ServiceItem one position up in the list. """ - item, child = self.findServiceItem() + item, child = self.find_service_item() if item > 0: - temp = self.serviceItems[item] - self.serviceItems.remove(self.serviceItems[item]) - self.serviceItems.insert(item - 1, temp) - self.repaintServiceList(item - 1, child) - self.setModified() + temp = self.service_items[item] + self.service_items.remove(self.service_items[item]) + self.service_items.insert(item - 1, temp) + self.repaint_service_list(item - 1, child) + self.set_modified() def onServiceDown(self): """ Move the current ServiceItem one position down in the list. """ - item, child = self.findServiceItem() - if item < len(self.serviceItems) and item != -1: - temp = self.serviceItems[item] - self.serviceItems.remove(self.serviceItems[item]) - self.serviceItems.insert(item + 1, temp) - self.repaintServiceList(item + 1, child) - self.setModified() + item, child = self.find_service_item() + if item < len(self.service_items) and item != -1: + temp = self.service_items[item] + self.service_items.remove(self.service_items[item]) + self.service_items.insert(item + 1, temp) + self.repaint_service_list(item + 1, child) + self.set_modified() def onServiceEnd(self): """ Move the current ServiceItem to the bottom of the list. """ - item, child = self.findServiceItem() - if item < len(self.serviceItems) and item != -1: - temp = self.serviceItems[item] - self.serviceItems.remove(self.serviceItems[item]) - self.serviceItems.insert(len(self.serviceItems), temp) - self.repaintServiceList(len(self.serviceItems) - 1, child) - self.setModified() + item, child = self.find_service_item() + if item < len(self.service_items) and item != -1: + temp = self.service_items[item] + self.service_items.remove(self.service_items[item]) + self.service_items.insert(len(self.service_items), temp) + self.repaint_service_list(len(self.service_items) - 1, child) + self.set_modified() def onDeleteFromService(self): """ Remove the current ServiceItem from the list. """ - item = self.findServiceItem()[0] + item = self.find_service_item()[0] if item != -1: - self.serviceItems.remove(self.serviceItems[item]) - self.repaintServiceList(item - 1, -1) - self.setModified() + self.service_items.remove(self.service_items[item]) + self.repaint_service_list(item - 1, -1) + self.set_modified() - def repaintServiceList(self, serviceItem, serviceItemChild): + def repaint_service_list(self, serviceItem, serviceItemChild): """ Clear the existing service list and prepaint all the items. This is used when moving items as the move takes place in a supporting list, @@ -1117,16 +1138,16 @@ class ServiceManager(QtGui.QWidget): # Correct order of items in array count = 1 self.service_has_all_original_files = True - for item in self.serviceItems: + for item in self.service_items: item[u'order'] = count count += 1 if not item[u'service_item'].has_original_files: self.service_has_all_original_files = False # Repaint the screen - self.serviceManagerList.clear() - for itemcount, item in enumerate(self.serviceItems): + self.service_manager_list.clear() + for item_count, item in enumerate(self.service_items): serviceitem = item[u'service_item'] - treewidgetitem = QtGui.QTreeWidgetItem(self.serviceManagerList) + treewidgetitem = QtGui.QTreeWidgetItem(self.service_manager_list) if serviceitem.is_valid: if serviceitem.notes: icon = QtGui.QImage(serviceitem.icon) @@ -1173,11 +1194,11 @@ class ServiceManager(QtGui.QWidget): text = frame[u'title'].replace(u'\n', u' ') child.setText(0, text[:40]) child.setData(0, QtCore.Qt.UserRole, count) - if serviceItem == itemcount: + if serviceItem == item_count: if item[u'expanded'] and serviceItemChild == count: - self.serviceManagerList.setCurrentItem(child) + self.service_manager_list.setCurrentItem(child) elif serviceItemChild == -1: - self.serviceManagerList.setCurrentItem(treewidgetitem) + self.service_manager_list.setCurrentItem(treewidgetitem) treewidgetitem.setExpanded(item[u'expanded']) def cleanUp(self): @@ -1191,15 +1212,15 @@ class ServiceManager(QtGui.QWidget): if os.path.exists(os.path.join(self.servicePath, u'audio')): shutil.rmtree(os.path.join(self.servicePath, u'audio'), True) - def onThemeComboBoxSelected(self, currentIndex): + def on_theme_combo_box_selected(self, currentIndex): """ Set the theme for the current service. """ - log.debug(u'onThemeComboBoxSelected') - self.service_theme = self.themeComboBox.currentText() - self.mainwindow.renderer.set_service_theme(self.service_theme) - Settings().setValue(self.mainwindow.serviceManagerSettingsSection + u'/service theme', self.service_theme) - self.regenerateServiceItems(True) + log.debug(u'ontheme_combo_box_selected') + self.service_theme = self.theme_combo_box.currentText() + self.renderer.set_service_theme(self.service_theme) + Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/service theme', self.service_theme) + self.regenerate_service_Items(True) def themeChange(self): """ @@ -1207,23 +1228,23 @@ class ServiceManager(QtGui.QWidget): sure the theme combo box is in the correct state. """ log.debug(u'themeChange') - visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global - self.themeLabel.setVisible(visible) - self.themeComboBox.setVisible(visible) + visible = self.renderer.theme_level == ThemeLevel.Global + self.theme_label.setVisible(visible) + self.theme_combo_box.setVisible(visible) - def regenerateServiceItems(self, changed=False): + def regenerate_service_Items(self, changed=False): """ Rebuild the service list as things have changed and a repaint is the easiest way to do this. """ Receiver.send_message(u'cursor_busy') - log.debug(u'regenerateServiceItems') + log.debug(u'regenerate_service_Items') # force reset of renderer as theme data has changed self.service_has_all_original_files = True - if self.serviceItems: - for item in self.serviceItems: + if self.service_items: + for item in self.service_items: item[u'selected'] = False - serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) + serviceIterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list) selectedItem = None while serviceIterator.value(): if serviceIterator.value().isSelected(): @@ -1234,20 +1255,20 @@ class ServiceManager(QtGui.QWidget): pos = selectedItem.data(0, QtCore.Qt.UserRole) else: pos = selectedItem.parent().data(0, QtCore.Qt.UserRole) - self.serviceItems[pos - 1][u'selected'] = True - tempServiceItems = self.serviceItems - self.serviceManagerList.clear() - self.serviceItems = [] + self.service_items[pos - 1][u'selected'] = True + tempServiceItems = self.service_items + self.service_manager_list.clear() + self.service_items = [] self.isNew = True for item in tempServiceItems: - self.addServiceItem(item[u'service_item'], False, expand=item[u'expanded'], repaint=False, + self.add_service_item(item[u'service_item'], False, expand=item[u'expanded'], repaint=False, selected=item[u'selected']) # Set to False as items may have changed rendering # does not impact the saved song so True may also be valid if changed: - self.setModified() + self.set_modified() # Repaint it once only at the end - self.repaintServiceList(-1, -1) + self.repaint_service_list(-1, -1) Receiver.send_message(u'cursor_normal') def serviceItemUpdate(self, message): @@ -1255,25 +1276,25 @@ class ServiceManager(QtGui.QWidget): Triggered from plugins to update service items. Save the values as they will be used as part of the service load """ - edit_id, self.load_item_uuid, temporary = message.split(u':') + edit_id, self.load_item_unique_identifier, temporary = message.split(u':') self.load_item_edit_id = int(edit_id) self.load_item_temporary = str_to_bool(temporary) - def replaceServiceItem(self, newItem): + def replace_service_item(self, newItem): """ Using the service item passed replace the one with the same edit id if found. """ - for itemcount, item in enumerate(self.serviceItems): + for item_count, item in enumerate(self.service_items): if item[u'service_item'].edit_id == newItem.edit_id and item[u'service_item'].name == newItem.name: newItem.render() newItem.merge(item[u'service_item']) item[u'service_item'] = newItem - self.repaintServiceList(itemcount + 1, 0) - self.mainwindow.liveController.replaceServiceManagerItem(newItem) - self.setModified() + self.repaint_service_list(item_count + 1, 0) + self.live_controller.replaceServiceManagerItem(newItem) + self.set_modified() - def addServiceItem(self, item, rebuild=False, expand=None, replace=False, repaint=True, selected=False): + def add_service_item(self, item, rebuild=False, expand=None, replace=False, repaint=True, selected=False): """ Add a Service item to the list @@ -1285,73 +1306,72 @@ class ServiceManager(QtGui.QWidget): """ # if not passed set to config value if expand is None: - expand = self.expandTabs + expand = self.expand_tabs item.from_service = True if replace: - sitem, child = self.findServiceItem() - item.merge(self.serviceItems[sitem][u'service_item']) - self.serviceItems[sitem][u'service_item'] = item - self.repaintServiceList(sitem, child) - self.mainwindow.liveController.replaceServiceManagerItem(item) + sitem, child = self.find_service_item() + item.merge(self.service_items[sitem][u'service_item']) + self.service_items[sitem][u'service_item'] = item + self.repaint_service_list(sitem, child) + self.live_controller.replaceServiceManagerItem(item) else: item.render() # nothing selected for dnd - if self.dropPosition == 0: + if self.drop_position == 0: if isinstance(item, list): for inditem in item: - self.serviceItems.append({u'service_item': inditem, - u'order': len(self.serviceItems) + 1, + self.service_items.append({u'service_item': inditem, + u'order': len(self.service_items) + 1, u'expanded': expand, u'selected': selected}) else: - self.serviceItems.append({u'service_item': item, - u'order': len(self.serviceItems) + 1, + self.service_items.append({u'service_item': item, + u'order': len(self.service_items) + 1, u'expanded': expand, u'selected': selected}) if repaint: - self.repaintServiceList(len(self.serviceItems) - 1, -1) + self.repaint_service_list(len(self.service_items) - 1, -1) else: - self.serviceItems.insert(self.dropPosition, - {u'service_item': item, u'order': self.dropPosition, + self.service_items.insert(self.drop_position, + {u'service_item': item, u'order': self.drop_position, u'expanded': expand, u'selected': selected}) - self.repaintServiceList(self.dropPosition, -1) + self.repaint_service_list(self.drop_position, -1) # if rebuilding list make sure live is fixed. if rebuild: - self.mainwindow.liveController.replaceServiceManagerItem(item) - self.dropPosition = 0 - self.setModified() + self.live_controller.replaceServiceManagerItem(item) + self.drop_position = 0 + self.set_modified() - def makePreview(self): + def make_preview(self): """ Send the current item to the Preview slide controller """ Receiver.send_message(u'cursor_busy') - item, child = self.findServiceItem() - if self.serviceItems[item][u'service_item'].is_valid: - self.mainwindow.previewController.addServiceManagerItem( - self.serviceItems[item][u'service_item'], child) + item, child = self.find_service_item() + if self.service_items[item][u'service_item'].is_valid: + self.preview_controller.addServiceManagerItem(self.service_items[item][u'service_item'], child) else: critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be displayed as there is no handler to display it')) Receiver.send_message(u'cursor_normal') - def getServiceItem(self): + def get_service_item(self): """ Send the current item to the Preview slide controller """ - item = self.findServiceItem()[0] + item = self.find_service_item()[0] if item == -1: return False else: - return self.serviceItems[item][u'service_item'] + return self.service_items[item][u'service_item'] - def onMakeLive(self): + def on_make_live(self): """ Send the current item to the Live slide controller but triggered by a tablewidget click event. """ - self.makeLive() + self.make_live() - def makeLive(self, row=-1): + def make_live(self, row=-1): """ Send the current item to the Live slide controller @@ -1359,47 +1379,48 @@ class ServiceManager(QtGui.QWidget): Row number to be displayed if from preview. -1 is passed if the value is not set """ - item, child = self.findServiceItem() + item, child = self.find_service_item() # No items in service if item == -1: return if row != -1: child = row Receiver.send_message(u'cursor_busy') - if self.serviceItems[item][u'service_item'].is_valid: - self.mainwindow.liveController.addServiceManagerItem( - self.serviceItems[item][u'service_item'], child) - if Settings().value(self.mainwindow.generalSettingsSection + u'/auto preview', False): + if self.service_items[item][u'service_item'].is_valid: + self.live_controller.addServiceManagerItem(self.service_items[item][u'service_item'], child) + if Settings().value(self.main_window.generalSettingsSection + u'/auto preview'): item += 1 - if self.serviceItems and item < len(self.serviceItems) and \ - self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.CanPreview): - self.mainwindow.previewController.addServiceManagerItem(self.serviceItems[item][u'service_item'], 0) - next_item = self.serviceManagerList.topLevelItem(item) - self.serviceManagerList.setCurrentItem(next_item) - self.mainwindow.liveController.previewListWidget.setFocus() + if self.service_items and item < len(self.service_items) and \ + self.service_items[item][u'service_item'].is_capable(ItemCapabilities.CanPreview): + self.preview_controller.addServiceManagerItem(self.service_items[item][u'service_item'], 0) + next_item = self.service_manager_list.topLevelItem(item) + self.service_manager_list.setCurrentItem(next_item) + self.live_controller.previewListWidget.setFocus() else: critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be displayed as the plugin required to display it is missing or inactive')) Receiver.send_message(u'cursor_normal') - def remoteEdit(self): + def remote_edit(self): """ - Posts a remote edit message to a plugin to allow item to be edited. + Triggers a remote edit to a plugin to allow item to be edited. """ - item = self.findServiceItem()[0] - if self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.CanEdit): - Receiver.send_message(u'%s_edit' % self.serviceItems[item][u'service_item'].name.lower(), - u'L:%s' % self.serviceItems[item][u'service_item'].edit_id) + item, child = self.find_service_item() + if self.service_items[item][u'service_item'].is_capable(ItemCapabilities.CanEdit): + new_item = Registry().get(self.service_items[item][u'service_item'].name). \ + onRemoteEdit(self.service_items[item][u'service_item'].edit_id) + if new_item: + self.add_service_item(new_item, replace=True) def create_custom(self): """ Saves the current text item as a custom slide """ - item = self.findServiceItem()[0] - Receiver.send_message(u'custom_create_from_service', self.serviceItems[item][u'service_item']) + item = self.find_service_item()[0] + Receiver.send_message(u'custom_create_from_service', self.service_items[item][u'service_item']) - def findServiceItem(self): + def find_service_item(self): """ Finds the first selected ServiceItem in the list and returns the position of the serviceitem and its selected child item. For example, @@ -1408,15 +1429,15 @@ class ServiceManager(QtGui.QWidget): (1, 2) """ - items = self.serviceManagerList.selectedItems() + items = self.service_manager_list.selectedItems() serviceItem = -1 serviceItemChild = -1 for item in items: - parentitem = item.parent() - if parentitem is None: + parent_item = item.parent() + if parent_item is None: serviceItem = item.data(0, QtCore.Qt.UserRole) else: - serviceItem = parentitem.data(0, QtCore.Qt.UserRole) + serviceItem = parent_item.data(0, QtCore.Qt.UserRole) serviceItemChild = item.data(0, QtCore.Qt.UserRole) # Adjust for zero based arrays. serviceItem -= 1 @@ -1424,16 +1445,7 @@ class ServiceManager(QtGui.QWidget): break return serviceItem, serviceItemChild - def dragEnterEvent(self, event): - """ - Accept Drag events - - ``event`` - Handle of the event pint passed - """ - event.accept() - - def dropEvent(self, event): + def drop_event(self, event): """ Receive drop event and trigger an internal event to get the plugins to build and push the correct service item @@ -1447,101 +1459,157 @@ class ServiceManager(QtGui.QWidget): event.setDropAction(QtCore.Qt.CopyAction) event.accept() for url in link.urls(): - filename = url.toLocalFile() - if filename.endswith(u'.osz'): - self.onLoadServiceClicked(filename) - elif filename.endswith(u'.oszl'): + file_name = url.toLocalFile() + if file_name.endswith(u'.osz'): + self.on_load_service_clicked(file_name) + elif file_name.endswith(u'.oszl'): # todo correct - self.onLoadServiceClicked(filename) + self.on_load_service_clicked(file_name) elif link.hasText(): plugin = link.text() - item = self.serviceManagerList.itemAt(event.pos()) + item = self.service_manager_list.itemAt(event.pos()) # ServiceManager started the drag and drop if plugin == u'ServiceManager': - startpos, child = self.findServiceItem() + startpos, child = self.find_service_item() # If no items selected if startpos == -1: return if item is None: - endpos = len(self.serviceItems) + endpos = len(self.service_items) else: - endpos = self._getParentItemData(item) - 1 - serviceItem = self.serviceItems[startpos] - self.serviceItems.remove(serviceItem) - self.serviceItems.insert(endpos, serviceItem) - self.repaintServiceList(endpos, child) - self.setModified() + endpos = self._get_parent_item_data(item) - 1 + serviceItem = self.service_items[startpos] + self.service_items.remove(serviceItem) + self.service_items.insert(endpos, serviceItem) + self.repaint_service_list(endpos, child) + self.set_modified() else: # we are not over anything so drop replace = False if item is None: - self.dropPosition = len(self.serviceItems) + self.drop_position = len(self.service_items) else: # we are over something so lets investigate - pos = self._getParentItemData(item) - 1 - serviceItem = self.serviceItems[pos] + pos = self._get_parent_item_data(item) - 1 + serviceItem = self.service_items[pos] if (plugin == serviceItem[u'service_item'].name and serviceItem[u'service_item'].is_capable(ItemCapabilities.CanAppend)): action = self.dndMenu.exec_(QtGui.QCursor.pos()) # New action required if action == self.newAction: - self.dropPosition = self._getParentItemData(item) + self.drop_position = self._get_parent_item_data(item) # Append to existing action if action == self.addToAction: - self.dropPosition = self._getParentItemData(item) + self.drop_position = self._get_parent_item_data(item) item.setSelected(True) replace = True else: - self.dropPosition = self._getParentItemData(item) + self.drop_position = self._get_parent_item_data(item) Receiver.send_message(u'%s_add_service_item' % plugin, replace) - def updateThemeList(self, theme_list): + def update_theme_list(self, theme_list): """ Called from ThemeManager when the Themes have changed ``theme_list`` A list of current themes to be displayed """ - self.themeComboBox.clear() - self.themeMenu.clear() - self.themeComboBox.addItem(u'') - themeGroup = QtGui.QActionGroup(self.themeMenu) - themeGroup.setExclusive(True) - themeGroup.setObjectName(u'themeGroup') + self.theme_combo_box.clear() + self.theme_menu.clear() + self.theme_combo_box.addItem(u'') + theme_group = QtGui.QActionGroup(self.theme_menu) + theme_group.setExclusive(True) + theme_group.setObjectName(u'theme_group') # Create a "Default" theme, which allows the user to reset the item's # theme to the service theme or global theme. - defaultTheme = create_widget_action(self.themeMenu, text=UiStrings().Default, checked=False, - triggers=self.onThemeChangeAction) - self.themeMenu.setDefaultAction(defaultTheme) - themeGroup.addAction(defaultTheme) - self.themeMenu.addSeparator() + defaultTheme = create_widget_action(self.theme_menu, text=UiStrings().Default, checked=False, + triggers=self.on_theme_change_action) + self.theme_menu.setDefaultAction(defaultTheme) + theme_group.addAction(defaultTheme) + self.theme_menu.addSeparator() for theme in theme_list: - self.themeComboBox.addItem(theme) - themeGroup.addAction(create_widget_action(self.themeMenu, theme, text=theme, checked=False, - triggers=self.onThemeChangeAction)) - find_and_set_in_combo_box(self.themeComboBox, self.service_theme) - self.mainwindow.renderer.set_service_theme(self.service_theme) - self.regenerateServiceItems() + self.theme_combo_box.addItem(theme) + theme_group.addAction(create_widget_action(self.theme_menu, theme, text=theme, checked=False, + triggers=self.on_theme_change_action)) + find_and_set_in_combo_box(self.theme_combo_box, self.service_theme) + self.renderer.set_service_theme(self.service_theme) + self.regenerate_service_Items() - def onThemeChangeAction(self): + def on_theme_change_action(self): + """ + Handles theme change events + """ theme = self.sender().objectName() # No object name means that the "Default" theme is supposed to be used. if not theme: theme = None - item = self.findServiceItem()[0] - self.serviceItems[item][u'service_item'].update_theme(theme) - self.regenerateServiceItems(True) + item = self.find_service_item()[0] + self.service_items[item][u'service_item'].update_theme(theme) + self.regenerate_service_Items(True) - def _getParentItemData(self, item): - parentitem = item.parent() - if parentitem is None: + def _get_parent_item_data(self, item): + """ + Finds and returns the parent item for any item + """ + parent_item = item.parent() + if parent_item is None: return item.data(0, QtCore.Qt.UserRole) else: - return parentitem.data(0, QtCore.Qt.UserRole) + return parent_item.data(0, QtCore.Qt.UserRole) - def printServiceOrder(self): + def print_service_order(self): """ Print a Service Order Sheet. """ - settingDialog = PrintServiceForm(self.mainwindow, self) + settingDialog = PrintServiceForm() settingDialog.exec_() + + def _get_renderer(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_renderer'): + self._renderer = Registry().get(u'renderer') + return self._renderer + + renderer = property(_get_renderer) + + def _get_live_controller(self): + """ + Adds the live controller to the class dynamically + """ + if not hasattr(self, u'_live_controller'): + self._live_controller = Registry().get(u'live_controller') + return self._live_controller + + live_controller = property(_get_live_controller) + + def _get_preview_controller(self): + """ + Adds the preview controller to the class dynamically + """ + if not hasattr(self, u'_preview_controller'): + self._preview_controller = Registry().get(u'preview_controller') + return self._preview_controller + + preview_controller = property(_get_preview_controller) + + def _get_plugin_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) \ No newline at end of file diff --git a/openlp/core/ui/servicenoteform.py b/openlp/core/ui/servicenoteform.py index d14675d6a..7e30b18ad 100644 --- a/openlp/core/ui/servicenoteform.py +++ b/openlp/core/ui/servicenoteform.py @@ -29,36 +29,46 @@ from PyQt4 import QtGui -from openlp.core.lib import translate, SpellTextEdit +from openlp.core.lib import translate, SpellTextEdit, Registry from openlp.core.lib.ui import create_button_box class ServiceNoteForm(QtGui.QDialog): """ This is the form that is used to edit the verses of the song. """ - def __init__(self, parent=None): + def __init__(self): """ Constructor """ - QtGui.QDialog.__init__(self, parent) + QtGui.QDialog.__init__(self, self.main_window) self.setupUi() self.retranslateUi() def exec_(self): - self.textEdit.setFocus() + self.text_edit.setFocus() return QtGui.QDialog.exec_(self) def setupUi(self): self.setObjectName(u'serviceNoteEdit') - self.dialogLayout = QtGui.QVBoxLayout(self) - self.dialogLayout.setContentsMargins(8, 8, 8, 8) - self.dialogLayout.setSpacing(8) - self.dialogLayout.setObjectName(u'verticalLayout') - self.textEdit = SpellTextEdit(self, False) - self.textEdit.setObjectName(u'textEdit') - self.dialogLayout.addWidget(self.textEdit) - self.buttonBox = create_button_box(self, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox) + self.dialog_layout = QtGui.QVBoxLayout(self) + self.dialog_layout.setContentsMargins(8, 8, 8, 8) + self.dialog_layout.setSpacing(8) + self.dialog_layout.setObjectName(u'verticalLayout') + self.text_edit = SpellTextEdit(self, False) + self.text_edit.setObjectName(u'textEdit') + self.dialog_layout.addWidget(self.text_edit) + self.button_box = create_button_box(self, u'button_box', [u'cancel', u'save']) + self.dialog_layout.addWidget(self.button_box) def retranslateUi(self): self.setWindowTitle(translate('OpenLP.ServiceNoteForm', 'Service Item Notes')) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) \ No newline at end of file diff --git a/openlp/core/ui/settingsdialog.py b/openlp/core/ui/settingsdialog.py index cd23737e3..f88e6c81e 100644 --- a/openlp/core/ui/settingsdialog.py +++ b/openlp/core/ui/settingsdialog.py @@ -38,7 +38,7 @@ class Ui_SettingsDialog(object): settingsDialog.resize(800, 500) settingsDialog.setWindowIcon(build_icon(u':/system/system_settings.png')) self.dialogLayout = QtGui.QGridLayout(settingsDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.dialogLayout.setMargin(8) self.settingListWidget = QtGui.QListWidget(settingsDialog) self.settingListWidget.setUniformItemSizes(True) @@ -49,8 +49,8 @@ class Ui_SettingsDialog(object): self.stackedLayout = QtGui.QStackedLayout() self.stackedLayout.setObjectName(u'stackedLayout') self.dialogLayout.addLayout(self.stackedLayout, 0, 1, 1, 1) - self.buttonBox = create_button_box(settingsDialog, u'buttonBox', [u'cancel', u'ok']) - self.dialogLayout.addWidget(self.buttonBox, 1, 1, 1, 1) + self.button_box = create_button_box(settingsDialog, u'button_box', [u'cancel', u'ok']) + self.dialogLayout.addWidget(self.button_box, 1, 1, 1, 1) self.retranslateUi(settingsDialog) QtCore.QObject.connect(self.settingListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.tabChanged) diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index 2807f215a..992128dc3 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -33,7 +33,7 @@ import logging from PyQt4 import QtGui -from openlp.core.lib import Receiver, build_icon, PluginStatus +from openlp.core.lib import Receiver, build_icon, PluginStatus, Registry from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab from openlp.core.ui.media import PlayerTab from settingsdialog import Ui_SettingsDialog @@ -44,21 +44,21 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): """ Provide the form to manipulate the settings for OpenLP """ - def __init__(self, mainWindow, parent=None): + def __init__(self, parent=None): """ Initialise the settings form """ - self.mainWindow = mainWindow + Registry().register(u'settings_form', self) QtGui.QDialog.__init__(self, parent) self.setupUi(self) # General tab self.generalTab = GeneralTab(self) # Themes tab - self.themesTab = ThemesTab(self, mainWindow) + self.themesTab = ThemesTab(self, self.main_window) # Advanced tab self.advancedTab = AdvancedTab(self) # Advanced tab - self.playerTab = PlayerTab(self, mainWindow) + self.playerTab = PlayerTab(self, self.main_window) def exec_(self): # load all the settings @@ -140,5 +140,25 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): per save. """ if self.resetSuffixes: - self.mainWindow.serviceManagerContents.resetSupportedSuffixes() + self.service_manager.reset_supported_suffixes() self.resetSuffixes = False + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) + + def _get_service_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_service_manager'): + self._service_manager = Registry().get(u'service_manager') + return self._service_manager + + service_manager = property(_get_service_manager) \ No newline at end of file diff --git a/openlp/core/ui/shortcutlistdialog.py b/openlp/core/ui/shortcutlistdialog.py index c49d1a912..dd72778ef 100644 --- a/openlp/core/ui/shortcutlistdialog.py +++ b/openlp/core/ui/shortcutlistdialog.py @@ -107,9 +107,9 @@ class Ui_ShortcutListDialog(object): self.alternateLabel.setObjectName(u'alternateLabel') self.detailsLayout.addWidget(self.alternateLabel, 0, 2, 1, 1) self.shortcutListLayout.addLayout(self.detailsLayout) - self.buttonBox = create_button_box(shortcutListDialog, u'buttonBox', [u'cancel', u'ok', u'defaults']) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.shortcutListLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(shortcutListDialog, u'button_box', [u'cancel', u'ok', u'defaults']) + self.button_box.setOrientation(QtCore.Qt.Horizontal) + self.shortcutListLayout.addWidget(self.button_box) self.retranslateUi(shortcutListDialog) def retranslateUi(self, shortcutListDialog): diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 959a95bfe..5c534ca37 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -41,6 +41,7 @@ REMOVE_AMPERSAND = re.compile(r'&{1}') log = logging.getLogger(__name__) + class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): """ The shortcut list dialog @@ -63,7 +64,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.onClearPrimaryButtonClicked) QtCore.QObject.connect(self.clearAlternateButton, QtCore.SIGNAL(u'clicked(bool)'), self.onClearAlternateButtonClicked) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), + QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onRestoreDefaultsClicked) QtCore.QObject.connect(self.defaultRadioButton, QtCore.SIGNAL(u'clicked(bool)'), self.onDefaultRadioButtonClicked) @@ -273,7 +274,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): """ Restores all default shortcuts. """ - if self.buttonBox.buttonRole(button) != QtGui.QDialogButtonBox.ResetRole: + if self.button_box.buttonRole(button) != QtGui.QDialogButtonBox.ResetRole: return if QtGui.QMessageBox.question(self, translate('OpenLP.ShortcutListDialog', 'Restore Default Shortcuts'), translate('OpenLP.ShortcutListDialog', 'Do you want to restore all ' diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 7e6879bdf..75028a514 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -34,14 +34,10 @@ from collections import deque from PyQt4 import QtCore, QtGui -from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \ - translate, build_icon, build_html, PluginManager, ServiceItem, \ - ImageSource, SlideLimits, ServiceItemAction, Settings -from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList -from openlp.core.lib.ui import UiStrings, create_action -from openlp.core.lib import SlideLimits, ServiceItemAction -from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList, \ - DisplayControllerType +from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, translate, build_icon, build_html, \ + ServiceItem, ImageSource, SlideLimits, ServiceItemAction, Settings, Registry, UiStrings, ScreenList +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 log = logging.getLogger(__name__) @@ -86,8 +82,6 @@ class SlideController(DisplayController): self.ratio = float(self.screens.current[u'size'].width()) / float(self.screens.current[u'size'].height()) except ZeroDivisionError: self.ratio = 1 - self.imageManager = self.parent().imageManager - self.mediaController = self.parent().mediaController self.loopList = [ u'playSlidesMenu', u'loopSeparator', @@ -113,6 +107,7 @@ class SlideController(DisplayController): # Type label for the top of the slide controller self.typeLabel = QtGui.QLabel(self.panel) if self.isLive: + Registry().register(u'live_controller', self) self.typeLabel.setText(UiStrings().Live) self.split = 1 self.typePrefix = u'live' @@ -121,6 +116,7 @@ class SlideController(DisplayController): self.category = UiStrings().LiveToolbar ActionList.get_instance().add_category(unicode(self.category), CategoryOrder.standardToolbar) else: + Registry().register(u'preview_controller', self) self.typeLabel.setText(UiStrings().Preview) self.split = 0 self.typePrefix = u'preview' @@ -211,7 +207,7 @@ class SlideController(DisplayController): self.playSlidesOnce = create_action(self, u'playSlidesOnce', text=UiStrings().PlaySlidesToEnd, icon=u':/media/media_time.png', checked=False, shortcuts=[], category=self.category, triggers=self.onPlaySlidesOnce) - if Settings().value(self.parent().generalSettingsSection + u'/enable slide loop', True): + if Settings().value(self.parent().generalSettingsSection + u'/enable slide loop'): self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) else: self.playSlidesMenu.setDefaultAction(self.playSlidesOnce) @@ -234,7 +230,7 @@ class SlideController(DisplayController): tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.'), triggers=self.onEditSong) self.controllerLayout.addWidget(self.toolbar) # Build the Media Toolbar - self.mediaController.register_controller(self) + self.media_controller.register_controller(self) if self.isLive: # Build the Song Toolbar self.songMenu = QtGui.QToolButton(self.toolbar) @@ -301,8 +297,7 @@ class SlideController(DisplayController): sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth( - self.slidePreview.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth(self.slidePreview.sizePolicy().hasHeightForWidth()) self.slidePreview.setSizePolicy(sizePolicy) self.slidePreview.setFrameShape(QtGui.QFrame.Box) self.slidePreview.setFrameShadow(QtGui.QFrame.Plain) @@ -357,8 +352,7 @@ class SlideController(DisplayController): self.setLiveHotkeys(self) self.__addActionsToWidget(self.previewListWidget) else: - self.previewListWidget.addActions( - [self.nextItem, self.previousItem]) + self.previewListWidget.addActions([self.nextItem, self.previousItem]) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix), self.onStopLoop) QtCore.QObject.connect(Receiver.get_receiver(), @@ -453,7 +447,7 @@ class SlideController(DisplayController): def liveEscape(self): self.display.setVisible(False) - self.mediaController.media_stop(self) + self.media_controller.media_stop(self) def toggleDisplay(self, action): """ @@ -510,7 +504,7 @@ class SlideController(DisplayController): # rebuild display as screen size changed if self.display: self.display.close() - self.display = MainDisplay(self, self.imageManager, self.isLive, self) + self.display = MainDisplay(self, self.isLive, self) self.display.setup() if self.isLive: self.__addActionsToWidget(self.display) @@ -520,13 +514,13 @@ class SlideController(DisplayController): self.ratio = float(self.screens.current[u'size'].width()) / float(self.screens.current[u'size'].height()) except ZeroDivisionError: self.ratio = 1 - self.mediaController.setup_display(self.display, False) + self.media_controller.setup_display(self.display, False) self.previewSizeChanged() self.previewDisplay.setup() serviceItem = ServiceItem() self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.screen, None, self.isLive, - plugins=PluginManager.get_instance().plugins)) - self.mediaController.setup_display(self.previewDisplay,True) + plugins=self.plugin_manager.plugins)) + self.media_controller.setup_display(self.previewDisplay,True) if self.serviceItem: self.refreshServiceItem() @@ -585,7 +579,7 @@ class SlideController(DisplayController): """ Updates the Slide Limits variable from the settings. """ - self.slide_limits = Settings().value(self.parent().advancedSettingsSection + u'/slide limits', SlideLimits.End) + self.slide_limits = Settings().value(self.parent().advancedSettingsSection + u'/slide limits') def enableToolBar(self, item): """ @@ -613,7 +607,7 @@ class SlideController(DisplayController): self.playSlidesLoop.setChecked(False) self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png')) if item.is_text(): - if Settings().value(self.parent().songsSettingsSection + u'/display songbar', True) and self.slideList: + if Settings().value(self.parent().songsSettingsSection + u'/display songbar') and self.slideList: self.songMenu.show() if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1: self.toolbar.setWidgetVisible(self.loopList) @@ -654,12 +648,12 @@ class SlideController(DisplayController): item.render() self._processItem(item, self.selectedRow) - def addServiceItem(self, item): + def add_service_item(self, item): """ Method to install the service item into the controller Called by plugins """ - log.debug(u'addServiceItem live = %s' % self.isLive) + log.debug(u'add_service_item live = %s' % self.isLive) item.render() slideno = 0 if self.songEdit: @@ -735,8 +729,8 @@ class SlideController(DisplayController): action.setData(counter) QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), self.onTrackTriggered) self.display.audioPlayer.repeat = Settings().value( - self.parent().generalSettingsSection + u'/audio repeat list', False) - if Settings().value(self.parent().generalSettingsSection + u'/audio start paused', True): + self.parent().generalSettingsSection + u'/audio repeat list') + if Settings().value(self.parent().generalSettingsSection + u'/audio start paused'): self.audioPauseItem.setChecked(True) self.display.audioPlayer.pause() else: @@ -776,9 +770,9 @@ class SlideController(DisplayController): else: # If current slide set background to image if framenumber == slideno: - self.serviceItem.bg_image_bytes = self.imageManager.getImageBytes(frame[u'path'], + self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes(frame[u'path'], ImageSource.ImagePlugin) - image = self.imageManager.getImage(frame[u'path'], ImageSource.ImagePlugin) + image = self.image_manager.getImage(frame[u'path'], ImageSource.ImagePlugin) label.setPixmap(QtGui.QPixmap.fromImage(image)) self.previewListWidget.setCellWidget(framenumber, 0, label) slideHeight = width * (1 / self.ratio) @@ -845,8 +839,7 @@ class SlideController(DisplayController): Allow the main display to blank the main display at startup time """ log.debug(u'mainDisplaySetBackground live = %s' % self.isLive) - display_type = Settings().value(self.parent().generalSettingsSection + u'/screen blank', - u'') + display_type = Settings().value(self.parent().generalSettingsSection + u'/screen blank') if self.screens.which_screen(self.window()) != self.screens.which_screen(self.display): # Order done to handle initial conversion if display_type == u'themed': @@ -1189,20 +1182,22 @@ class SlideController(DisplayController): From the preview display requires the service Item to be editied """ self.songEdit = True - Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(), u'P:%s' % self.serviceItem.edit_id) + new_item = Registry().get(self.serviceItem.name).onRemoteEdit(self.serviceItem.edit_id, True) + if new_item: + self.add_service_item(new_item) def onPreviewAddToService(self): """ From the preview display request the Item to be added to service """ if self.serviceItem: - self.parent().serviceManagerContents.addServiceItem(self.serviceItem) + self.service_manager.add_service_item(self.serviceItem) def onGoLiveClick(self): """ triggered by clicking the Preview slide items """ - if Settings().value(u'advanced/double click live', False): + if Settings().value(u'advanced/double click live'): # Live and Preview have issues if we have video or presentations # playing in both at the same time. if self.serviceItem.is_command(): @@ -1218,16 +1213,17 @@ class SlideController(DisplayController): row = self.previewListWidget.currentRow() if -1 < row < self.previewListWidget.rowCount(): if self.serviceItem.from_service: - Receiver.send_message('servicemanager_preview_live', u'%s:%s' % (self.serviceItem._uuid, row)) + Receiver.send_message('servicemanager_preview_live', u'%s:%s' % + (self.serviceItem.unique_identifier, row)) else: - self.parent().liveController.addServiceManagerItem(self.serviceItem, row) + self.live_controller.addServiceManagerItem(self.serviceItem, row) def onMediaStart(self, item): """ Respond to the arrival of a media service item """ log.debug(u'SlideController onMediaStart') - self.mediaController.video(self.controllerType, item, self.hideMode()) + self.media_controller.video(self.controllerType, item, self.hideMode()) if not self.isLive: self.previewDisplay.show() self.slidePreview.hide() @@ -1237,7 +1233,7 @@ class SlideController(DisplayController): Respond to a request to close the Video """ log.debug(u'SlideController onMediaClose') - self.mediaController.media_reset(self) + self.media_controller.media_reset(self) self.previewDisplay.hide() self.slidePreview.show() @@ -1283,3 +1279,53 @@ class SlideController(DisplayController): def onTrackTriggered(self): action = self.sender() self.display.audioPlayer.goTo(action.data()) + + def _get_plugin_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) + + def _get_media_controller(self): + """ + Adds the media controller to the class dynamically + """ + if not hasattr(self, u'_media_controller'): + self._media_controller = Registry().get(u'media_controller') + return self._media_controller + + media_controller = property(_get_media_controller) + + def _get_service_manager(self): + """ + Adds the service manager to the class dynamically + """ + if not hasattr(self, u'_service_manager'): + self._service_manager = Registry().get(u'service_manager') + return self._service_manager + + service_manager = property(_get_service_manager) + + def _get_live_controller(self): + """ + Adds the live controller to the class dynamically + """ + if not hasattr(self, u'_live_controller'): + self._live_controller = Registry().get(u'live_controller') + return self._live_controller + + live_controller = property(_get_live_controller) \ No newline at end of file diff --git a/openlp/core/ui/starttimedialog.py b/openlp/core/ui/starttimedialog.py index c0977ab52..0e2f7dc13 100644 --- a/openlp/core/ui/starttimedialog.py +++ b/openlp/core/ui/starttimedialog.py @@ -29,15 +29,16 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings, create_button_box +from openlp.core.lib import translate, UiStrings +from openlp.core.lib.ui import create_button_box + class Ui_StartTimeDialog(object): def setupUi(self, StartTimeDialog): StartTimeDialog.setObjectName(u'StartTimeDialog') StartTimeDialog.resize(350, 10) self.dialogLayout = QtGui.QGridLayout(StartTimeDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.startLabel = QtGui.QLabel(StartTimeDialog) self.startLabel.setObjectName(u'startLabel') self.startLabel.setAlignment(QtCore.Qt.AlignHCenter) @@ -101,8 +102,8 @@ class Ui_StartTimeDialog(object): self.secondFinishLabel.setAlignment(QtCore.Qt.AlignRight) self.dialogLayout.addWidget(self.secondFinishLabel, 3, 3, 1, 1) self.dialogLayout.addWidget(self.secondSpinBox, 3, 1, 1, 1) - self.buttonBox = create_button_box(StartTimeDialog, u'buttonBox', [u'cancel', u'ok']) - self.dialogLayout.addWidget(self.buttonBox, 5, 2, 1, 2) + self.button_box = create_button_box(StartTimeDialog, u'button_box', [u'cancel', u'ok']) + self.dialogLayout.addWidget(self.button_box, 5, 2, 1, 2) self.retranslateUi(StartTimeDialog) self.setMaximumHeight(self.sizeHint().height()) diff --git a/openlp/core/ui/starttimeform.py b/openlp/core/ui/starttimeform.py index 2e2f4ee4f..f53b995b1 100644 --- a/openlp/core/ui/starttimeform.py +++ b/openlp/core/ui/starttimeform.py @@ -31,15 +31,15 @@ from PyQt4 import QtGui from starttimedialog import Ui_StartTimeDialog -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import translate, UiStrings, Registry +from openlp.core.lib.ui import critical_error_message_box class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): """ The exception dialog """ - def __init__(self, parent): - QtGui.QDialog.__init__(self, parent) + def __init__(self): + QtGui.QDialog.__init__(self, self.main_window) self.setupUi(self) def exec_(self): @@ -84,3 +84,13 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): minutes = seconds / 60 seconds -= 60 * minutes return hours, minutes, seconds + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) \ No newline at end of file diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 54bcb91c8..37af3b7b9 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -32,9 +32,9 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, translate +from openlp.core.lib import Receiver, translate, UiStrings from openlp.core.lib.theme import BackgroundType, BackgroundGradientType -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui import ThemeLayoutForm from openlp.core.utils import get_images_filter from themewizard import Ui_ThemeWizard @@ -72,7 +72,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): self.onGradientStartButtonClicked) QtCore.QObject.connect(self.gradientEndButton, QtCore.SIGNAL(u'clicked()'), self.onGradientEndButtonClicked) QtCore.QObject.connect(self.imageBrowseButton, QtCore.SIGNAL(u'clicked()'), self.onImageBrowseButtonClicked) - QtCore.QObject.connect(self.mainColorButton, QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked) + QtCore.QObject.connect(self.mainColorButton, QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked) QtCore.QObject.connect(self.outlineColorButton, QtCore.SIGNAL(u'clicked()'), self.onOutlineColorButtonClicked) QtCore.QObject.connect(self.shadowColorButton, QtCore.SIGNAL(u'clicked()'), self.onShadowColorButtonClicked) QtCore.QObject.connect(self.outlineCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), diff --git a/openlp/core/ui/themelayoutdialog.py b/openlp/core/ui/themelayoutdialog.py index fa3a2eb29..123fcbfec 100644 --- a/openlp/core/ui/themelayoutdialog.py +++ b/openlp/core/ui/themelayoutdialog.py @@ -58,8 +58,8 @@ class Ui_ThemeLayoutDialog(object): self.footerColourLabel = QtGui.QLabel(self.previewArea) self.footerColourLabel.setObjectName(u'footerColourLabel') self.previewLayout.addWidget(self.footerColourLabel) - self.buttonBox = create_button_box(themeLayoutDialog, u'buttonBox', [u'ok']) - self.previewLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(themeLayoutDialog, u'button_box', [u'ok']) + self.previewLayout.addWidget(self.button_box) self.retranslateUi(themeLayoutDialog) def retranslateUi(self, themeLayoutDialog): diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 8a3bbc28c..1c7921121 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -37,9 +37,10 @@ from xml.etree.ElementTree import ElementTree, XML from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, Receiver, SettingsManager, translate, \ - check_item_selected, check_directory_exists, create_thumb, validate_thumb, ImageSource, Settings + check_item_selected, check_directory_exists, create_thumb, validate_thumb, ImageSource, Settings, Registry, \ + UiStrings from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, BackgroundGradientType -from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_widget_action +from openlp.core.lib.ui import critical_error_message_box, create_widget_action from openlp.core.theme import Theme from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.utils import AppLocation, delete_file, locale_compare, get_filesystem_encoding @@ -50,9 +51,9 @@ class ThemeManager(QtGui.QWidget): """ Manages the orders of Theme. """ - def __init__(self, mainwindow, parent=None): + def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) - self.mainwindow = mainwindow + Registry().register(u'theme_manager', self) self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm(self) @@ -158,7 +159,7 @@ class ThemeManager(QtGui.QWidget): """ Triggered when Config dialog is updated. """ - self.global_theme = Settings().value(self.settingsSection + u'/global theme', u'') + self.global_theme = Settings().value(self.settingsSection + u'/global theme') def checkListState(self, item): """ @@ -261,11 +262,10 @@ class ThemeManager(QtGui.QWidget): old_theme_data = self.getThemeData(old_theme_name) self.cloneThemeData(old_theme_data, new_theme_name) self.deleteTheme(old_theme_name) - for plugin in self.mainwindow.pluginManager.plugins: + for plugin in self.plugin_manager.plugins: if plugin.usesTheme(old_theme_name): plugin.renameTheme(old_theme_name, new_theme_name) - self.mainwindow.renderer.update_theme( - new_theme_name, old_theme_name) + self.renderer.update_theme(new_theme_name, old_theme_name) self.loadThemes() def onCopyTheme(self): @@ -312,7 +312,7 @@ class ThemeManager(QtGui.QWidget): self.themeForm.theme = theme self.themeForm.exec_(True) self.oldBackgroundImage = None - self.mainwindow.renderer.update_theme(theme.theme_name) + self.renderer.update_theme(theme.theme_name) self.loadThemes() def onDeleteTheme(self): @@ -327,7 +327,7 @@ class ThemeManager(QtGui.QWidget): row = self.themeListWidget.row(item) self.themeListWidget.takeItem(row) self.deleteTheme(theme) - self.mainwindow.renderer.update_theme(theme, only_delete=True) + self.renderer.update_theme(theme, only_delete=True) # As we do not reload the themes, push out the change. Reload the # list as the internal lists and events need to be triggered. self._pushThemes() @@ -360,12 +360,12 @@ class ThemeManager(QtGui.QWidget): theme = item.data(QtCore.Qt.UserRole) path = QtGui.QFileDialog.getExistingDirectory(self, translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme, - SettingsManager.get_last_dir(self.settingsSection, 1)) - path = unicode(path) + Settings().value(self.settingsSection + u'/last directory export')) Receiver.send_message(u'cursor_busy') if path: - SettingsManager.set_last_dir(self.settingsSection, path, 1) + Settings().setValue(self.settingsSection + u'/last directory export', path) theme_path = os.path.join(path, theme + u'.otz') + # FIXME: Do not overwrite build-in. zip = None try: zip = zipfile.ZipFile(theme_path, u'w') @@ -396,14 +396,14 @@ class ThemeManager(QtGui.QWidget): """ files = QtGui.QFileDialog.getOpenFileNames(self, translate('OpenLP.ThemeManager', 'Select Theme Import File'), - SettingsManager.get_last_dir(self.settingsSection), + Settings().value(self.settingsSection + u'/last directory import'), translate('OpenLP.ThemeManager', 'OpenLP Themes (*.theme *.otz)')) log.info(u'New Themes %s', unicode(files)) if not files: return Receiver.send_message(u'cursor_busy') for file in files: - SettingsManager.set_last_dir(self.settingsSection, unicode(file)) + Settings().setValue(self.settingsSection + u'/last directory import', unicode(file)) self.unzipTheme(file, self.path) self.loadThemes() Receiver.send_message(u'cursor_normal') @@ -429,7 +429,7 @@ class ThemeManager(QtGui.QWidget): Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name) self.configUpdated() files = SettingsManager.get_files(self.settingsSection, u'.png') - # Sort the themes by its name considering language specific + # Sort the themes by its name considering language specific files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare) # now process the file list of png files @@ -474,8 +474,7 @@ class ThemeManager(QtGui.QWidget): Name of the theme to load from file """ log.debug(u'getthemedata for theme %s', theme_name) - xml_file = os.path.join(self.path, unicode(theme_name), - unicode(theme_name) + u'.xml') + xml_file = os.path.join(self.path, unicode(theme_name), unicode(theme_name) + u'.xml') xml = get_text_file_string(xml_file) if not xml: log.debug(u'No theme data - using default theme') @@ -631,9 +630,9 @@ class ThemeManager(QtGui.QWidget): """ self._writeTheme(theme, image_from, image_to) if theme.background_type == BackgroundType.to_string(BackgroundType.Image): - self.mainwindow.imageManager.updateImageBorder(theme.background_filename, + self.image_manager.updateImageBorder(theme.background_filename, ImageSource.Theme, QtGui.QColor(theme.background_border_color)) - self.mainwindow.imageManager.processUpdates() + self.image_manager.processUpdates() def _writeTheme(self, theme, image_from, image_to): """ @@ -680,11 +679,11 @@ class ThemeManager(QtGui.QWidget): """ Called to update the themes' preview images. """ - self.mainwindow.displayProgressBar(len(self.themeList)) + self.main_window.displayProgressBar(len(self.themeList)) for theme in self.themeList: - self.mainwindow.incrementProgressBar() + self.main_window.incrementProgressBar() self.generateAndSaveImage(self.path, theme, self.getThemeData(theme)) - self.mainwindow.finishedProgressBar() + self.main_window.finishedProgressBar() self.loadThemes() def generateImage(self, theme_data, forcePage=False): @@ -698,7 +697,7 @@ class ThemeManager(QtGui.QWidget): Flag to tell message lines per page need to be generated. """ log.debug(u'generateImage \n%s ', theme_data) - return self.mainwindow.renderer.generate_preview(theme_data, forcePage) + return self.renderer.generate_preview(theme_data, forcePage) def getPreviewImage(self, theme): """ @@ -729,8 +728,7 @@ class ThemeManager(QtGui.QWidget): Check to see if theme has been selected and the destructive action is allowed. """ - self.global_theme = Settings().value( - self.settingsSection + u'/global theme', u'') + self.global_theme = Settings().value(self.settingsSection + u'/global theme') if check_item_selected(self.themeListWidget, select_text): item = self.themeListWidget.currentItem() theme = item.text() @@ -748,7 +746,7 @@ class ThemeManager(QtGui.QWidget): return False # check for use in the system else where. if testPlugin: - for plugin in self.mainwindow.pluginManager.plugins: + for plugin in self.plugin_manager.plugins: if plugin.usesTheme(theme): critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') % @@ -806,3 +804,42 @@ class ThemeManager(QtGui.QWidget): new_theme.display_vertical_align = vAlignCorrection return new_theme.extract_xml() + def _get_renderer(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_renderer'): + self._renderer = Registry().get(u'renderer') + return self._renderer + + renderer = property(_get_renderer) + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) + + def _get_plugin_manager(self): + """ + Adds the Renderer to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 45188d075..1867fe872 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -29,9 +29,10 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, SettingsTab, translate +from openlp.core.lib import Receiver, Settings, SettingsTab, translate, UiStrings from openlp.core.lib.theme import ThemeLevel -from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box +from openlp.core.lib.ui import find_and_set_in_combo_box + class ThemesTab(SettingsTab): """ @@ -118,8 +119,8 @@ class ThemesTab(SettingsTab): def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.theme_level = settings.value(u'theme level', ThemeLevel.Song) - self.global_theme = settings.value(u'global theme', u'') + self.theme_level = settings.value(u'theme level') + self.global_theme = settings.value(u'global theme') settings.endGroup() if self.theme_level == ThemeLevel.Global: self.GlobalLevelRadioButton.setChecked(True) @@ -165,7 +166,7 @@ class ThemesTab(SettingsTab): [u'Bible Theme', u'Song Theme'] """ # Reload as may have been triggered by the ThemeManager. - self.global_theme = Settings().value(self.settingsSection + u'/global theme', u'') + self.global_theme = Settings().value(self.settingsSection + u'/global theme') self.DefaultComboBox.clear() self.DefaultComboBox.addItems(theme_list) find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme) diff --git a/openlp/core/ui/themewizard.py b/openlp/core/ui/themewizard.py index c6f30c96d..7cabae2bc 100644 --- a/openlp/core/ui/themewizard.py +++ b/openlp/core/ui/themewizard.py @@ -29,9 +29,9 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate, build_icon +from openlp.core.lib import translate, build_icon, UiStrings from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType -from openlp.core.lib.ui import UiStrings, add_welcome_page, create_valign_selection_widgets +from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets class Ui_ThemeWizard(object): def setupUi(self, themeWizard): diff --git a/openlp/core/ui/wizard.py b/openlp/core/ui/wizard.py index e79a5d5e0..fd7c9b35b 100644 --- a/openlp/core/ui/wizard.py +++ b/openlp/core/ui/wizard.py @@ -34,8 +34,8 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon, Receiver, SettingsManager, translate -from openlp.core.lib.ui import UiStrings, add_welcome_page +from openlp.core.lib import build_icon, Receiver, Settings, translate, UiStrings +from openlp.core.lib.ui import add_welcome_page log = logging.getLogger(__name__) @@ -254,7 +254,7 @@ class OpenLPWizard(QtGui.QWizard): self.cancelButton.setVisible(False) Receiver.send_message(u'openlp_process_events') - def getFileName(self, title, editbox, filters=u''): + def getFileName(self, title, editbox, setting_name, filters=u''): """ Opens a QFileDialog and saves the filename to the given editbox. @@ -264,6 +264,9 @@ class OpenLPWizard(QtGui.QWizard): ``editbox`` An editbox (QLineEdit). + ``setting_name`` + The place where to save the last opened directory. + ``filters`` The file extension filters. It should contain the file description as well as the file extension. For example:: @@ -273,15 +276,13 @@ class OpenLPWizard(QtGui.QWizard): if filters: filters += u';;' filters += u'%s (*)' % UiStrings().AllFiles - filename = unicode(QtGui.QFileDialog.getOpenFileName(self, title, - os.path.dirname(SettingsManager.get_last_dir( - self.plugin.settingsSection, 1)), filters)) + filename = QtGui.QFileDialog.getOpenFileName(self, title, + os.path.dirname(Settings().value(self.plugin.settingsSection + u'/' + setting_name)), filters) if filename: editbox.setText(filename) - SettingsManager.set_last_dir(self.plugin.settingsSection, - filename, 1) + Settings().setValue(self.plugin.settingsSection + u'/' + setting_name, filename) - def getFolder(self, title, editbox): + def getFolder(self, title, editbox, setting_name): """ Opens a QFileDialog and saves the selected folder to the given editbox. @@ -290,10 +291,13 @@ class OpenLPWizard(QtGui.QWizard): ``editbox`` An editbox (QLineEdit). + + ``setting_name`` + The place where to save the last opened directory. """ - folder = unicode(QtGui.QFileDialog.getExistingDirectory(self, title, - os.path.dirname(SettingsManager.get_last_dir(self.plugin.settingsSection, 1)), - QtGui.QFileDialog.ShowDirsOnly)) + folder = QtGui.QFileDialog.getExistingDirectory(self, title, + Settings().value(self.plugin.settingsSection + u'/' + setting_name), + QtGui.QFileDialog.ShowDirsOnly) if folder: editbox.setText(folder) - SettingsManager.set_last_dir(self.plugin.settingsSection, folder, 1) + Settings().setValue(self.plugin.settingsSection + u'/' + setting_name, folder) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 21b1b4f30..ba5e08c7f 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -127,7 +127,7 @@ class AppLocation(object): """ # Check if we have a different data location. if Settings().contains(u'advanced/data path'): - path = Settings().value(u'advanced/data path', u'') + path = Settings().value(u'advanced/data path') else: path = AppLocation.get_directory(AppLocation.DataDir) check_directory_exists(path) @@ -154,16 +154,13 @@ def _get_os_dir_path(dir_type): return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp', u'data') elif dir_type == AppLocation.LanguageDir: return os.path.split(openlp.__file__)[0] - return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), - u'openlp') + return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp') elif sys.platform == u'darwin': if dir_type == AppLocation.DataDir: - return os.path.join(unicode(os.getenv(u'HOME'), encoding), - u'Library', u'Application Support', u'openlp', u'Data') + return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp', u'Data') elif dir_type == AppLocation.LanguageDir: return os.path.split(openlp.__file__)[0] - return os.path.join(unicode(os.getenv(u'HOME'), encoding), - u'Library', u'Application Support', u'openlp') + return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp') else: if dir_type == AppLocation.LanguageDir: prefixes = [u'/usr/local', u'/usr'] @@ -288,8 +285,7 @@ def check_latest_version(current_version): # set to prod in the distribution config file. settings = Settings() settings.beginGroup(u'general') - # This defaults to yesterday in order to force the update check to run when you've never run it before. - last_test = settings.value(u'last version test', datetime.now().date() - timedelta(days=1)) + last_test = settings.value(u'last version test') this_test = datetime.now().date() settings.setValue(u'last version test', this_test) settings.endGroup() @@ -333,8 +329,7 @@ def add_actions(target, actions): def get_filesystem_encoding(): """ - Returns the name of the encoding used to convert Unicode filenames into - system file names. + Returns the name of the encoding used to convert Unicode filenames into system file names. """ encoding = sys.getfilesystemencoding() if encoding is None: @@ -344,8 +339,7 @@ def get_filesystem_encoding(): def get_images_filter(): """ - Returns a filter string for a file dialog containing all the supported - image formats. + Returns a filter string for a file dialog containing all the supported image formats. """ global IMAGES_FILTER if not IMAGES_FILTER: @@ -465,7 +459,7 @@ def get_uno_instance(resolver): def format_time(text, local_time): """ - Workaround for Python built-in time formatting fuction time.strftime(). + Workaround for Python built-in time formatting function time.strftime(). time.strftime() accepts only ascii characters. This function accepts unicode string and passes individual % placeholders to time.strftime(). @@ -473,6 +467,7 @@ def format_time(text, local_time): ``text`` The text to be processed. + ``local_time`` The time to be used to add to the string. This is a time object """ @@ -489,8 +484,7 @@ def locale_compare(string1, string2): or 0, depending on whether string1 collates before or after string2 or is equal to it. Comparison is case insensitive. """ - # Function locale.strcoll() from standard Python library does not work - # properly on Windows. + # Function locale.strcoll() from standard Python library does not work properly on Windows. return locale.strcoll(string1.lower(), string2.lower()) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 5cf7e810a..88bcbb44a 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -233,7 +233,7 @@ class ActionList(object): # Load the shortcut from the config. settings = Settings() settings.beginGroup(u'shortcuts') - shortcuts = settings.value(action.objectName(), action.shortcuts()) + shortcuts = settings.value(action.objectName()) settings.endGroup() if not shortcuts: action.setShortcuts([]) diff --git a/openlp/core/utils/languagemanager.py b/openlp/core/utils/languagemanager.py index 2d6e2746d..355f35915 100644 --- a/openlp/core/utils/languagemanager.py +++ b/openlp/core/utils/languagemanager.py @@ -98,7 +98,7 @@ class LanguageManager(object): """ Retrieve a saved language to use from settings """ - language = Settings().value(u'general/language', u'[en]') + language = Settings().value(u'general/language') language = str(language) log.info(u'Language file: \'%s\' Loaded from conf file' % language) if re.match(r'[[].*[]]', language): diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index e81c53d67..29727b79d 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -29,12 +29,13 @@ import logging -from PyQt4 import QtCore +from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings from openlp.core.lib.db import Manager from openlp.core.lib.ui import create_action, UiStrings from openlp.core.lib.theme import VerticalType +from openlp.core.ui import AlertLocation from openlp.core.utils.actions import ActionList from openlp.plugins.alerts.lib import AlertsManager, AlertsTab from openlp.plugins.alerts.lib.db import init_schema @@ -113,11 +114,22 @@ HTML = """ """ +__default_settings__ = { + u'alerts/font face': QtGui.QFont().family(), + u'alerts/font size': 40, + u'alerts/db type': u'sqlite', + u'alerts/location': AlertLocation.Bottom, + u'alerts/background color': u'#660000', + u'alerts/font color': u'#ffffff', + u'alerts/timeout': 5 + } + + class AlertsPlugin(Plugin): log.info(u'Alerts Plugin loaded') - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'alerts', plugin_helpers, settings_tab_class=AlertsTab) + def __init__(self): + Plugin.__init__(self, u'alerts', __default_settings__, settings_tab_class=AlertsTab) self.weight = -3 self.iconPath = u':/plugins/plugin_alerts.png' self.icon = build_icon(self.iconPath) @@ -139,7 +151,7 @@ class AlertsPlugin(Plugin): text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png', statustip=translate('AlertsPlugin', 'Show an alert message.'), visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger) - self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem) + self.main_window.toolsMenu.addAction(self.toolsAlertItem) def initialise(self): log.info(u'Alerts Initialising') diff --git a/openlp/plugins/alerts/forms/alertdialog.py b/openlp/plugins/alerts/forms/alertdialog.py index dfd895db2..1ca5a1113 100644 --- a/openlp/plugins/alerts/forms/alertdialog.py +++ b/openlp/plugins/alerts/forms/alertdialog.py @@ -77,9 +77,9 @@ class Ui_AlertDialog(object): displayIcon = build_icon(u':/general/general_live.png') self.displayButton = create_button(alertDialog, u'displayButton', icon=displayIcon, enabled=False) self.displayCloseButton = create_button(alertDialog, u'displayCloseButton', icon=displayIcon, enabled=False) - self.buttonBox = create_button_box(alertDialog, u'buttonBox', [u'close'], + self.button_box = create_button_box(alertDialog, u'button_box', [u'close'], [self.displayButton, self.displayCloseButton]) - self.alertDialogLayout.addWidget(self.buttonBox, 2, 0, 1, 2) + self.alertDialogLayout.addWidget(self.button_box, 2, 0, 1, 2) self.retranslateUi(alertDialog) def retranslateUi(self, alertDialog): diff --git a/openlp/plugins/alerts/forms/alertform.py b/openlp/plugins/alerts/forms/alertform.py index 8af7b3e21..cedb7acfc 100644 --- a/openlp/plugins/alerts/forms/alertform.py +++ b/openlp/plugins/alerts/forms/alertform.py @@ -45,7 +45,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): self.manager = plugin.manager self.plugin = plugin self.item_id = None - QtGui.QDialog.__init__(self, plugin.formParent) + QtGui.QDialog.__init__(self, self.plugin.main_window) self.setupUi(self) QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked) QtCore.QObject.connect(self.displayCloseButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked) diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index 2007ab72e..60451f20c 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -29,9 +29,9 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, translate, Receiver, Settings +from openlp.core.lib import SettingsTab, translate, Receiver, Settings, UiStrings from openlp.core.ui import AlertLocation -from openlp.core.lib.ui import UiStrings, create_valign_selection_widgets +from openlp.core.lib.ui import create_valign_selection_widgets class AlertsTab(SettingsTab): """ @@ -141,12 +141,12 @@ class AlertsTab(SettingsTab): def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.timeout = settings.value(u'timeout', 5) - self.font_color = settings.value(u'font color', u'#ffffff') - self.font_size = settings.value(u'font size', 40) - self.bg_color = settings.value(u'background color', u'#660000') - self.font_face = settings.value(u'font face', QtGui.QFont().family()) - self.location = settings.value(u'location', AlertLocation.Bottom) + self.timeout = settings.value(u'timeout') + self.font_color = settings.value(u'font color') + self.font_size = settings.value(u'font size') + self.bg_color = settings.value(u'background color') + self.font_face = settings.value(u'font face') + self.location = settings.value(u'location') settings.endGroup() self.fontSizeSpinBox.setValue(self.font_size) self.timeoutSpinBox.setValue(self.timeout) @@ -163,7 +163,7 @@ class AlertsTab(SettingsTab): settings = Settings() settings.beginGroup(self.settingsSection) # Check value has changed as no event handles this field - if settings.value(u'location', 1) != self.verticalComboBox.currentIndex(): + if settings.value(u'location') != self.verticalComboBox.currentIndex(): self.changed = True settings.setValue(u'background color', self.bg_color) settings.setValue(u'font color', self.font_color) diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index f22fc8bf8..d24858db5 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -34,16 +34,42 @@ from PyQt4 import QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings from openlp.core.lib.ui import create_action, UiStrings from openlp.core.utils.actions import ActionList -from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem +from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem, LayoutStyle, DisplayStyle, \ + LanguageSelection +from openlp.plugins.bibles.lib.mediaitem import BibleSearch from openlp.plugins.bibles.forms import BibleUpgradeForm log = logging.getLogger(__name__) + +__default_settings__ = { + u'bibles/db type': u'sqlite', + u'bibles/last search type': BibleSearch.Reference, + u'bibles/verse layout style': LayoutStyle.VersePerSlide, + u'bibles/book name language': LanguageSelection.Bible, + u'bibles/display brackets': DisplayStyle.NoBrackets, + u'bibles/display new chapter': False, + u'bibles/second bibles': True, + u'bibles/advanced bible': u'', + u'bibles/quick bible': u'', + u'bibles/proxy name': u'', + u'bibles/proxy address': u'', + u'bibles/proxy username': u'', + u'bibles/proxy password': u'', + u'bibles/bible theme': u'', + u'bibles/verse separator': u'', + u'bibles/range separator': u'', + u'bibles/list separator': u'', + u'bibles/end separator': u'', + u'bibles/last directory import': u'' + } + + class BiblePlugin(Plugin): log.info(u'Bible Plugin loaded') - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'bibles', plugin_helpers, BibleMediaItem, BiblesTab) + def __init__(self): + Plugin.__init__(self, u'bibles', __default_settings__, BibleMediaItem, BiblesTab) self.weight = -9 self.iconPath = u':/plugins/plugin_bibles.png' self.icon = build_icon(self.iconPath) @@ -80,20 +106,15 @@ class BiblePlugin(Plugin): """ Perform tasks on application startup """ + Plugin.appStartup(self) if self.manager.old_bible_databases: - if QtGui.QMessageBox.information(self.formParent, + if QtGui.QMessageBox.information(self.main_window, translate('OpenLP', 'Information'), translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your existing Bibles.\n' 'Should OpenLP upgrade now?'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == \ QtGui.QMessageBox.Yes: self.onToolsUpgradeItemTriggered() - settings = Settings() - settings.beginGroup(self.settingsSection) - if settings.contains(u'bookname language'): - settings.setValue(u'book name language', settings.value(u'bookname language', 0)) - settings.remove(u'bookname language') - settings.endGroup() def addImportMenuItem(self, import_menu): self.importBibleItem = create_action(import_menu, u'importBibleItem', @@ -128,7 +149,7 @@ class BiblePlugin(Plugin): Upgrade older bible databases. """ if not hasattr(self, u'upgrade_wizard'): - self.upgrade_wizard = BibleUpgradeForm(self.formParent, self.manager, self) + self.upgrade_wizard = BibleUpgradeForm(self.main_window, self.manager, self) # If the import was not cancelled then reload. if self.upgrade_wizard.exec_(): self.mediaItem.reloadBibles() diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index d2d9cf8e4..05469eae9 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -34,9 +34,9 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, translate, Settings +from openlp.core.lib import Receiver, translate, Settings, UiStrings from openlp.core.lib.db import delete_database -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard, WizardStrings from openlp.core.utils import AppLocation, locale_compare from openlp.plugins.bibles.lib.manager import BibleFormat @@ -469,34 +469,34 @@ class BibleImportForm(OpenLPWizard): """ Show the file open dialog for the OSIS file. """ - self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OSIS, self.osisFileEdit) + self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OSIS, self.osisFileEdit, u'last directory import') def onCsvBooksBrowseButtonClicked(self): """ Show the file open dialog for the books CSV file. """ - self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csvBooksEdit, u'%s (*.csv)' - % translate('BiblesPlugin.ImportWizardForm', 'CSV File')) + self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csvBooksEdit, u'last directory import', + u'%s (*.csv)' % translate('BiblesPlugin.ImportWizardForm', 'CSV File')) def onCsvVersesBrowseButtonClicked(self): """ Show the file open dialog for the verses CSV file. """ - self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csvVersesEdit, u'%s (*.csv)' - % translate('BiblesPlugin.ImportWizardForm', 'CSV File')) + self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csvVersesEdit, u'last directory import', + u'%s (*.csv)' % translate('BiblesPlugin.ImportWizardForm', 'CSV File')) def onOpenSongBrowseButtonClicked(self): """ Show the file open dialog for the OpenSong file. """ - self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OS, self.openSongFileEdit) + self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OS, self.openSongFileEdit, u'last directory import') def onOpenlp1BrowseButtonClicked(self): """ Show the file open dialog for the openlp.org 1.x file. """ - self.getFileName(WizardStrings.OpenTypeFile % UiStrings().OLPV1, self.openlp1FileEdit, u'%s (*.bible)' % - translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x Bible Files')) + self.getFileName(WizardStrings.OpenTypeFile % UiStrings().OLPV1, self.openlp1FileEdit, u'last directory import', + u'%s (*.bible)' % translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x Bible Files')) def registerFields(self): """ @@ -533,9 +533,9 @@ class BibleImportForm(OpenLPWizard): self.setField(u'opensong_file', '') self.setField(u'web_location', WebDownload.Crosswalk) self.setField(u'web_biblename', self.webTranslationComboBox.currentIndex()) - self.setField(u'proxy_server', settings.value(u'proxy address', u'')) - self.setField(u'proxy_username', settings.value(u'proxy username', u'')) - self.setField(u'proxy_password', settings.value(u'proxy password', u'')) + self.setField(u'proxy_server', settings.value(u'proxy address')) + self.setField(u'proxy_username', settings.value(u'proxy username')) + self.setField(u'proxy_password', settings.value(u'proxy password')) self.setField(u'openlp1_location', '') self.setField(u'license_version', self.versionNameEdit.text()) self.setField(u'license_copyright', self.copyrightEdit.text()) diff --git a/openlp/plugins/bibles/forms/bibleupgradeform.py b/openlp/plugins/bibles/forms/bibleupgradeform.py index b42dfd710..0b2f214f7 100644 --- a/openlp/plugins/bibles/forms/bibleupgradeform.py +++ b/openlp/plugins/bibles/forms/bibleupgradeform.py @@ -36,8 +36,8 @@ from tempfile import gettempdir from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, SettingsManager, translate, check_directory_exists, Settings -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import Receiver, translate, check_directory_exists, Settings, UiStrings +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard, WizardStrings from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB, BiblesResourcesDB @@ -116,11 +116,9 @@ class BibleUpgradeForm(OpenLPWizard): Show the file open dialog for the OSIS file. """ filename = QtGui.QFileDialog.getExistingDirectory(self, - translate('BiblesPlugin.UpgradeWizardForm', 'Select a Backup Directory'), - os.path.dirname(SettingsManager.get_last_dir(self.plugin.settingsSection, 1))) + translate('BiblesPlugin.UpgradeWizardForm', 'Select a Backup Directory'), u'') if filename: self.backupDirectoryEdit.setText(filename) - SettingsManager.set_last_dir(self.plugin.settingsSection, filename, 1) def onNoBackupCheckBoxToggled(self, checked): """ diff --git a/openlp/plugins/bibles/forms/booknamedialog.py b/openlp/plugins/bibles/forms/booknamedialog.py index c1908a650..df86b4380 100644 --- a/openlp/plugins/bibles/forms/booknamedialog.py +++ b/openlp/plugins/bibles/forms/booknamedialog.py @@ -80,8 +80,8 @@ class Ui_BookNameDialog(object): self.apocryphaCheckBox.setCheckState(QtCore.Qt.Checked) self.optionsLayout.addWidget(self.apocryphaCheckBox) self.bookNameLayout.addWidget(self.optionsGroupBox) - self.buttonBox = create_button_box(bookNameDialog, u'buttonBox', [u'cancel', u'ok']) - self.bookNameLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(bookNameDialog, u'button_box', [u'cancel', u'ok']) + self.bookNameLayout.addWidget(self.button_box) self.retranslateUi(bookNameDialog) diff --git a/openlp/plugins/bibles/forms/editbibledialog.py b/openlp/plugins/bibles/forms/editbibledialog.py index a74baaca5..aecfb7a98 100644 --- a/openlp/plugins/bibles/forms/editbibledialog.py +++ b/openlp/plugins/bibles/forms/editbibledialog.py @@ -44,7 +44,7 @@ class Ui_EditBibleDialog(object): self.dialogLayout = QtGui.QVBoxLayout(editBibleDialog) self.dialogLayout.setSpacing(8) self.dialogLayout.setContentsMargins(8, 8, 8, 8) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.bibleTabWidget = QtGui.QTabWidget(editBibleDialog) self.bibleTabWidget.setObjectName(u'BibleTabWidget') # Meta tab @@ -121,8 +121,8 @@ class Ui_EditBibleDialog(object): self.bibleTabWidget.addTab(self.bookNameTab, u'') # Last few bits self.dialogLayout.addWidget(self.bibleTabWidget) - self.buttonBox = create_button_box(editBibleDialog, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(editBibleDialog, u'button_box', [u'cancel', u'save']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(editBibleDialog) QtCore.QMetaObject.connectSlotsByName(editBibleDialog) diff --git a/openlp/plugins/bibles/forms/editbibleform.py b/openlp/plugins/bibles/forms/editbibleform.py index 517111c73..26a58d14b 100644 --- a/openlp/plugins/bibles/forms/editbibleform.py +++ b/openlp/plugins/bibles/forms/editbibleform.py @@ -32,8 +32,8 @@ import re from PyQt4 import QtGui -from openlp.core.lib import Receiver, translate -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import Receiver, translate, UiStrings +from openlp.core.lib.ui import critical_error_message_box from editbibledialog import Ui_EditBibleDialog from openlp.plugins.bibles.lib import BibleStrings from openlp.plugins.bibles.lib.db import BiblesResourcesDB diff --git a/openlp/plugins/bibles/forms/languagedialog.py b/openlp/plugins/bibles/forms/languagedialog.py index 9ed915d34..9ad16bb30 100644 --- a/openlp/plugins/bibles/forms/languagedialog.py +++ b/openlp/plugins/bibles/forms/languagedialog.py @@ -62,8 +62,8 @@ class Ui_LanguageDialog(object): self.languageComboBox.setObjectName(u'languageComboBox') self.languageHBoxLayout.addWidget(self.languageComboBox) self.languageLayout.addLayout(self.languageHBoxLayout) - self.buttonBox = create_button_box(languageDialog, u'buttonBox', [u'cancel', u'ok']) - self.languageLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(languageDialog, u'button_box', [u'cancel', u'ok']) + self.languageLayout.addWidget(self.button_box) self.retranslateUi(languageDialog) diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 01314ddc9..2ba2ff590 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -187,10 +187,10 @@ def update_reference_separators(): settings = Settings() settings.beginGroup(u'bibles') custom_separators = [ - settings.value(u'verse separator', u''), - settings.value(u'range separator', u''), - settings.value(u'list separator', u''), - settings.value(u'end separator', u'')] + settings.value(u'verse separator'), + settings.value(u'range separator'), + settings.value(u'list separator'), + settings.value(u'end separator')] settings.endGroup() for index, role in enumerate([u'v', u'r', u'l', u'e']): if custom_separators[index].strip(u'|') == u'': diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index e3d7acb35..291930a4b 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -31,8 +31,8 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, SettingsTab, translate, Settings -from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box +from openlp.core.lib import Receiver, SettingsTab, translate, Settings, UiStrings +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 @@ -331,16 +331,16 @@ class BiblesTab(SettingsTab): def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.show_new_chapters = settings.value(u'display new chapter', False) - self.display_style = settings.value(u'display brackets', 0) - self.layout_style = settings.value(u'verse layout style', 0) - self.bible_theme = settings.value(u'bible theme', u'') - self.second_bibles = settings.value(u'second bibles', True) + self.show_new_chapters = settings.value(u'display new chapter') + self.display_style = settings.value(u'display brackets') + self.layout_style = settings.value(u'verse layout style') + self.bible_theme = settings.value(u'bible theme') + self.second_bibles = settings.value(u'second bibles') self.newChaptersCheckBox.setChecked(self.show_new_chapters) self.displayStyleComboBox.setCurrentIndex(self.display_style) self.layoutStyleComboBox.setCurrentIndex(self.layout_style) self.bibleSecondCheckBox.setChecked(self.second_bibles) - verse_separator = settings.value(u'verse separator', u'') + verse_separator = settings.value(u'verse separator') if (verse_separator.strip(u'|') == u'') or (verse_separator == get_reference_separator(u'sep_v_default')): self.verseSeparatorLineEdit.setText(get_reference_separator(u'sep_v_default')) self.verseSeparatorLineEdit.setPalette(self.getGreyTextPalette(True)) @@ -349,7 +349,7 @@ class BiblesTab(SettingsTab): self.verseSeparatorLineEdit.setText(verse_separator) self.verseSeparatorLineEdit.setPalette(self.getGreyTextPalette(False)) self.verseSeparatorCheckBox.setChecked(True) - range_separator = settings.value(u'range separator', u'') + range_separator = settings.value(u'range separator') if (range_separator.strip(u'|') == u'') or (range_separator == get_reference_separator(u'sep_r_default')): self.rangeSeparatorLineEdit.setText(get_reference_separator(u'sep_r_default')) self.rangeSeparatorLineEdit.setPalette(self.getGreyTextPalette(True)) @@ -358,7 +358,7 @@ class BiblesTab(SettingsTab): self.rangeSeparatorLineEdit.setText(range_separator) self.rangeSeparatorLineEdit.setPalette(self.getGreyTextPalette(False)) self.rangeSeparatorCheckBox.setChecked(True) - list_separator = settings.value(u'list separator', u'') + list_separator = settings.value(u'list separator') if (list_separator.strip(u'|') == u'') or (list_separator == get_reference_separator(u'sep_l_default')): self.listSeparatorLineEdit.setText(get_reference_separator(u'sep_l_default')) self.listSeparatorLineEdit.setPalette(self.getGreyTextPalette(True)) @@ -367,7 +367,7 @@ class BiblesTab(SettingsTab): self.listSeparatorLineEdit.setText(list_separator) self.listSeparatorLineEdit.setPalette(self.getGreyTextPalette(False)) self.listSeparatorCheckBox.setChecked(True) - end_separator = settings.value(u'end separator', u'') + end_separator = settings.value(u'end separator') if (end_separator.strip(u'|') == u'') or (end_separator == get_reference_separator(u'sep_e_default')): self.endSeparatorLineEdit.setText(get_reference_separator(u'sep_e_default')) self.endSeparatorLineEdit.setPalette(self.getGreyTextPalette(True)) @@ -376,7 +376,7 @@ class BiblesTab(SettingsTab): self.endSeparatorLineEdit.setText(end_separator) self.endSeparatorLineEdit.setPalette(self.getGreyTextPalette(False)) self.endSeparatorCheckBox.setChecked(True) - self.language_selection = settings.value(u'book name language', 0) + self.language_selection = settings.value(u'book name language') self.languageSelectionComboBox.setCurrentIndex(self.language_selection) settings.endGroup() diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 69a3a663f..11bdd09e7 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -778,7 +778,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): The source of the webbible. """ log.debug(u'BiblesResourcesDB.get_webbibles("%s")', source) - if not isinstance(source, unicode): + if not isinstance(source, unicode): source = unicode(source) source = BiblesResourcesDB.get_download_source(source) bibles = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, ' @@ -953,7 +953,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager): return cursor.fetchall() @staticmethod - def get_book_reference_id(name, language_id=None): + def get_book_reference_id(name, language_id=None): """ Return a book_reference_id if the name matches. diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index ee48945e5..327f03565 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -526,7 +526,7 @@ class HTTPBible(BibleDB): books = handler.get_books_from_http(self.download_name) if not books: log.exception(u'Importing books from %s - download name: "%s" '\ - 'failed' % (self.download_source, self.download_name)) + 'failed' % (self.download_source, self.download_name)) return False self.wizard.progressBar.setMaximum(len(books)+2) self.wizard.incrementProgressBar(translate( @@ -552,7 +552,7 @@ class HTTPBible(BibleDB): language_id) if not book_ref_id: log.exception(u'Importing books from %s - download name: "%s" '\ - 'failed' % (self.download_source, self.download_name)) + 'failed' % (self.download_source, self.download_name)) return False book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) log.debug(u'Book details: Name:%s; id:%s; testament_id:%s', diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index 1fa07ba86..aaf91d2c0 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -124,7 +124,7 @@ class BibleManager(object): self.web = u'Web' self.db_cache = None self.path = AppLocation.get_section_data_path(self.settingsSection) - self.proxy_name = Settings().value(self.settingsSection + u'/proxy name', u'') + self.proxy_name = Settings().value(self.settingsSection + u'/proxy name') self.suffix = u'.sqlite' self.import_wizard = None self.reload_bibles() @@ -356,7 +356,7 @@ class BibleManager(object): if not language_selection or language_selection.value == "None" or language_selection.value == "-1": # If None is returned, it's not the singleton object but a # BibleMeta object with the value "None" - language_selection = Settings().value(self.settingsSection + u'/book name language', 0) + language_selection = Settings().value(self.settingsSection + u'/book name language') else: language_selection = language_selection.value try: diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index b4a1ec470..fd1109221 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -31,10 +31,10 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ - translate, create_separated_list, ServiceItemContext, Settings +from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, translate, create_separated_list, \ + ServiceItemContext, Settings, UiStrings from openlp.core.lib.searchedit import SearchEdit -from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \ +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 from openlp.core.utils import locale_compare from openlp.plugins.bibles.forms import BibleImportForm, EditBibleForm @@ -228,7 +228,7 @@ class BibleMediaItem(MediaManagerItem): self.addSearchFields(u'advanced', UiStrings().Advanced) # Combo Boxes QtCore.QObject.connect(self.quickVersionComboBox, QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) - QtCore.QObject.connect(self.quickSecondComboBox, QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) + QtCore.QObject.connect(self.quickSecondComboBox, QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) QtCore.QObject.connect(self.advancedVersionComboBox,QtCore.SIGNAL(u'activated(int)'), self.onAdvancedVersionComboBox) QtCore.QObject.connect(self.advancedSecondComboBox, QtCore.SIGNAL(u'activated(int)'), @@ -260,7 +260,7 @@ class BibleMediaItem(MediaManagerItem): def configUpdated(self): log.debug(u'configUpdated') - if Settings().value(self.settingsSection + u'/second bibles', True): + if Settings().value(self.settingsSection + u'/second bibles'): self.advancedSecondLabel.setVisible(True) self.advancedSecondComboBox.setVisible(True) self.quickSecondLabel.setVisible(True) @@ -312,8 +312,7 @@ class BibleMediaItem(MediaManagerItem): translate('BiblesPlugin.MediaItem', 'Text Search'), translate('BiblesPlugin.MediaItem', 'Search Text...')) ]) - self.quickSearchEdit.setCurrentSearchType(Settings().value(u'%s/last search type' % self.settingsSection, - BibleSearch.Reference)) + self.quickSearchEdit.setCurrentSearchType(Settings().value(u'%s/last search type' % self.settingsSection)) self.configUpdated() log.debug(u'bible manager initialise complete') @@ -335,13 +334,13 @@ class BibleMediaItem(MediaManagerItem): self.advancedVersionComboBox.addItems(bibles) self.advancedSecondComboBox.addItems(bibles) # set the default value - bible = Settings().value(self.settingsSection + u'/advanced bible', u'') + bible = Settings().value(self.settingsSection + u'/advanced bible') if bible in bibles: find_and_set_in_combo_box(self.advancedVersionComboBox, bible) self.initialiseAdvancedBible(unicode(bible)) elif bibles: self.initialiseAdvancedBible(bibles[0]) - bible = Settings().value(self.settingsSection + u'/quick bible', self.quickVersionComboBox.currentText()) + bible = Settings().value(self.settingsSection + u'/quick bible') find_and_set_in_combo_box(self.quickVersionComboBox, bible) def reloadBibles(self, process=False): @@ -480,7 +479,7 @@ class BibleMediaItem(MediaManagerItem): elif self.advancedTab.isVisible(): bible = self.advancedVersionComboBox.currentText() if bible: - self.editBibleForm = EditBibleForm(self, self.plugin.formParent, self.plugin.manager) + self.editBibleForm = EditBibleForm(self, self.main_window, self.plugin.manager) self.editBibleForm.loadBible(bible) if self.editBibleForm.exec_(): self.reloadBibles() diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index 3d57d1cc2..d80b8929d 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -37,9 +37,18 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib.db import Manager from openlp.plugins.custom.lib import CustomMediaItem, CustomTab from openlp.plugins.custom.lib.db import CustomSlide, init_schema +from openlp.plugins.custom.lib.mediaitem import CustomSearch log = logging.getLogger(__name__) +__default_settings__ = { + u'custom/db type': u'sqlite', + u'custom/last search type': CustomSearch.Titles, + u'custom/display footer': True, + u'custom/add custom from service': True + } + + class CustomPlugin(Plugin): """ This plugin enables the user to create, edit and display @@ -51,8 +60,8 @@ class CustomPlugin(Plugin): """ log.info(u'Custom Plugin loaded') - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'custom', plugin_helpers, CustomMediaItem, CustomTab) + def __init__(self): + Plugin.__init__(self, u'custom', __default_settings__, CustomMediaItem, CustomTab) self.weight = -5 self.manager = Manager(u'custom', init_schema) self.iconPath = u':/plugins/plugin_custom.png' diff --git a/openlp/plugins/custom/forms/editcustomdialog.py b/openlp/plugins/custom/forms/editcustomdialog.py index f9fc608dd..5792e7aae 100644 --- a/openlp/plugins/custom/forms/editcustomdialog.py +++ b/openlp/plugins/custom/forms/editcustomdialog.py @@ -29,8 +29,8 @@ from PyQt4 import QtGui -from openlp.core.lib import build_icon, translate -from openlp.core.lib.ui import UiStrings, create_button_box, create_button +from openlp.core.lib import build_icon, translate, UiStrings +from openlp.core.lib.ui import create_button_box, create_button class Ui_CustomEditDialog(object): def setupUi(self, customEditDialog): @@ -38,7 +38,7 @@ class Ui_CustomEditDialog(object): customEditDialog.resize(450, 350) customEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png')) self.dialogLayout = QtGui.QVBoxLayout(customEditDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.titleLayout = QtGui.QHBoxLayout() self.titleLayout.setObjectName(u'titleLayout') self.titleLabel = QtGui.QLabel(customEditDialog) @@ -97,8 +97,8 @@ class Ui_CustomEditDialog(object): self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit) self.dialogLayout.addLayout(self.bottomFormLayout) self.previewButton = QtGui.QPushButton() - self.buttonBox = create_button_box(customEditDialog, u'buttonBox', [u'cancel', u'save'], [self.previewButton]) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(customEditDialog, u'button_box', [u'cancel', u'save'], [self.previewButton]) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(customEditDialog) def retranslateUi(self, customEditDialog): diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 69058eb0c..8e7c18bdf 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -102,10 +102,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): # If not preview hide the preview button. self.previewButton.setVisible(preview) - def reject(self): - Receiver.send_message(u'custom_edit_clear') - QtGui.QDialog.reject(self) - def accept(self): log.debug(u'accept') if self.saveCustom(): diff --git a/openlp/plugins/custom/forms/editcustomslidedialog.py b/openlp/plugins/custom/forms/editcustomslidedialog.py index 4f226d89f..ee47ba52b 100644 --- a/openlp/plugins/custom/forms/editcustomslidedialog.py +++ b/openlp/plugins/custom/forms/editcustomslidedialog.py @@ -29,8 +29,8 @@ from PyQt4 import QtGui -from openlp.core.lib import translate, SpellTextEdit, build_icon -from openlp.core.lib.ui import UiStrings, create_button, create_button_box +from openlp.core.lib import translate, SpellTextEdit, build_icon, UiStrings +from openlp.core.lib.ui import create_button, create_button_box class Ui_CustomSlideEditDialog(object): def setupUi(self, customSlideEditDialog): @@ -42,9 +42,9 @@ class Ui_CustomSlideEditDialog(object): self.dialogLayout.addWidget(self.slideTextEdit) self.splitButton = create_button(customSlideEditDialog, u'splitButton', icon=u':/general/general_add.png') self.insertButton = create_button(customSlideEditDialog, u'insertButton', icon=u':/general/general_add.png') - self.buttonBox = create_button_box(customSlideEditDialog, u'buttonBox', [u'cancel', u'save'], + self.button_box = create_button_box(customSlideEditDialog, u'button_box', [u'cancel', u'save'], [self.splitButton, self.insertButton]) - self.dialogLayout.addWidget(self.buttonBox) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(customSlideEditDialog) def retranslateUi(self, customSlideEditDialog): diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index 531703297..5b0b7f11f 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -84,8 +84,8 @@ class CustomTab(SettingsTab): def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.displayFooter = settings.value(u'display footer', True) - self.update_load = settings.value(u'add custom from service', True) + self.displayFooter = settings.value(u'display footer') + self.update_load = settings.value(u'add custom from service') self.displayFooterCheckBox.setChecked(self.displayFooter) self.add_from_service_checkbox.setChecked(self.update_load) settings.endGroup() diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index f9478d6ff..e434f516a 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -33,8 +33,7 @@ from PyQt4 import QtCore, QtGui from sqlalchemy.sql import or_, func, and_ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, check_item_selected, translate, \ - ServiceItemContext, Settings, PluginStatus -from openlp.core.lib.ui import UiStrings + ServiceItemContext, Settings, PluginStatus, UiStrings from openlp.plugins.custom.forms import EditCustomForm from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder from openlp.plugins.custom.lib.db import CustomSlide @@ -58,7 +57,7 @@ class CustomMediaItem(MediaManagerItem): def __init__(self, parent, plugin, icon): self.IconPath = u'custom/custom' MediaManagerItem.__init__(self, parent, plugin, icon) - self.edit_custom_form = EditCustomForm(self, self.plugin.formParent, self.plugin.manager) + self.edit_custom_form = EditCustomForm(self, self.main_window, self.plugin.manager) self.singleServiceItem = False self.quickPreviewAllowed = True self.hasSearch = True @@ -74,8 +73,6 @@ class CustomMediaItem(MediaManagerItem): QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'searchTypeChanged(int)'), self.onSearchTextButtonClicked) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_edit'), self.onRemoteEdit) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_edit_clear'), self.onRemoteEditClear) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_load_list'), self.loadList) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated) @@ -83,7 +80,7 @@ class CustomMediaItem(MediaManagerItem): self.create_from_service_item) def config_updated(self): - self.add_custom_from_service = Settings().value(self.settingsSection + u'/add custom from service', True) + self.add_custom_from_service = Settings().value(self.settingsSection + u'/add custom from service') def retranslateUi(self): self.searchTextLabel.setText(u'%s:' % UiStrings().Search) @@ -97,8 +94,7 @@ class CustomMediaItem(MediaManagerItem): (CustomSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes) ]) self.loadList(self.manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title)) - self.searchTextEdit.setCurrentSearchType(Settings().value( u'%s/last search type' % self.settingsSection, - CustomSearch.Titles)) + self.searchTextEdit.setCurrentSearchType(Settings().value( u'%s/last search type' % self.settingsSection)) self.config_updated() def loadList(self, custom_slides): @@ -117,11 +113,6 @@ class CustomMediaItem(MediaManagerItem): # Called to redisplay the custom list screen edith from a search # or from the exit of the Custom edit dialog. If remote editing is # active trigger it and clean up so it will not update again. - if self.remoteTriggered == u'L': - self.onAddClick() - if self.remoteTriggered == u'P': - self.onPreviewClick() - self.onRemoteEditClear() def onNewClick(self): self.edit_custom_form.loadCustom(0) @@ -129,26 +120,27 @@ class CustomMediaItem(MediaManagerItem): self.onClearTextButtonClick() self.onSelectionChange() - def onRemoteEditClear(self): - self.remoteTriggered = None - self.remoteCustom = -1 - - def onRemoteEdit(self, message): + def onRemoteEdit(self, custom_id, preview=False): """ Called by ServiceManager or SlideController by event passing the custom Id in the payload along with an indicator to say which type of display is required. """ - remote_type, custom_id = message.split(u':') custom_id = int(custom_id) valid = self.manager.get_object(CustomSlide, custom_id) if valid: - self.remoteCustom = custom_id - self.remoteTriggered = remote_type - self.edit_custom_form.loadCustom(custom_id, (remote_type == u'P')) - self.edit_custom_form.exec_() - self.autoSelectId = -1 - self.onSearchTextButtonClicked() + self.edit_custom_form.loadCustom(custom_id, preview) + if self.edit_custom_form.exec_() == QtGui.QDialog.Accepted: + self.remoteTriggered = True + self.remoteCustom = custom_id + self.autoSelectId = -1 + self.onSearchTextButtonClicked() + item = self.buildServiceItem(remote=True) + self.remoteTriggered = None + self.remoteCustom = 1 + if item: + return item + return None def onEditClick(self): """ @@ -208,7 +200,7 @@ class CustomMediaItem(MediaManagerItem): service_item.title = title for slide in raw_slides: service_item.add_from_text(slide) - if Settings().value(self.settingsSection + u'/display footer', True) or credit: + if Settings().value(self.settingsSection + u'/display footer') or credit: service_item.raw_footer.append(u' '.join([title, credit])) else: service_item.raw_footer.append(u'') @@ -258,7 +250,7 @@ class CustomMediaItem(MediaManagerItem): and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme, CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:])) if custom: - Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False)) + Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item.unique_identifier, False)) else: if self.add_custom_from_service: self.create_from_service_item(item) @@ -288,7 +280,7 @@ class CustomMediaItem(MediaManagerItem): self.plugin.manager.save_object(custom) self.onSearchTextButtonClicked() if item.name.lower() == u'custom': - Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False)) + Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item.unique_identifier, False)) def onClearTextButtonClick(self): """ diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 810794469..11e542e60 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -36,11 +36,17 @@ from openlp.plugins.images.lib import ImageMediaItem, ImageTab log = logging.getLogger(__name__) +__default_settings__ = { + u'images/background color': u'#000000', + u'images/images files': [] + } + + class ImagePlugin(Plugin): log.info(u'Image Plugin loaded') - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem, ImageTab) + def __init__(self): + Plugin.__init__(self, u'images', __default_settings__, ImageMediaItem, ImageTab) self.weight = -7 self.iconPath = u':/plugins/plugin_images.png' self.icon = build_icon(self.iconPath) @@ -91,5 +97,5 @@ class ImagePlugin(Plugin): image manager to require updates. Actual update is triggered by the last part of saving the config. """ - background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color', u'#000000')) + background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color')) self.liveController.imageManager.updateImagesBorder(ImageSource.ImagePlugin, background) diff --git a/openlp/plugins/images/lib/imagetab.py b/openlp/plugins/images/lib/imagetab.py index a59ce6d10..8e3f1c657 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -29,8 +29,7 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, translate, Receiver, Settings -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import SettingsTab, translate, Receiver, Settings, UiStrings class ImageTab(SettingsTab): """ @@ -81,7 +80,7 @@ class ImageTab(SettingsTab): def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.bg_color = settings.value(u'background color', u'#000000') + self.bg_color = settings.value(u'background color') self.initial_color = self.bg_color settings.endGroup() self.backgroundColorButton.setStyleSheet(u'background-color: %s' % self.bg_color) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index c6fb3881a..85024229a 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -33,8 +33,9 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, SettingsManager, translate, \ - check_item_selected, check_directory_exists, Receiver, create_thumb, validate_thumb, ServiceItemContext, Settings -from openlp.core.lib.ui import UiStrings, critical_error_message_box + check_item_selected, check_directory_exists, Receiver, create_thumb, validate_thumb, ServiceItemContext, Settings, \ + UiStrings +from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import AppLocation, delete_file, locale_compare, get_images_filter log = logging.getLogger(__name__) @@ -77,7 +78,7 @@ class ImageMediaItem(MediaManagerItem): self.listView.setIconSize(QtCore.QSize(88, 50)) self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settingsSection), u'thumbnails') check_directory_exists(self.servicePath) - self.loadList(SettingsManager.load_list(self.settingsSection, u'images'), True) + self.loadList(Settings().value(self.settingsSection + u'/images files'), True) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) @@ -99,22 +100,22 @@ class ImageMediaItem(MediaManagerItem): row_list = [item.row() for item in self.listView.selectedIndexes()] row_list.sort(reverse=True) Receiver.send_message(u'cursor_busy') - self.plugin.formParent.displayProgressBar(len(row_list)) + self.main_window.displayProgressBar(len(row_list)) for row in row_list: text = self.listView.item(row) if text: delete_file(os.path.join(self.servicePath, text.text())) self.listView.takeItem(row) - self.plugin.formParent.incrementProgressBar() - SettingsManager.set_list(self.settingsSection, u'images', self.getFileList()) - self.plugin.formParent.finishedProgressBar() + self.main_window.incrementProgressBar() + SettingsManager.setValue(self.settingsSection + u'/images files', self.getFileList()) + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') self.listView.blockSignals(False) def loadList(self, images, initialLoad=False): if not initialLoad: Receiver.send_message(u'cursor_busy') - self.plugin.formParent.displayProgressBar(len(images)) + self.main_window.displayProgressBar(len(images)) # Sort the images by its filename considering language specific # characters. images.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1]) @@ -134,14 +135,14 @@ class ImageMediaItem(MediaManagerItem): item_name.setData(QtCore.Qt.UserRole, imageFile) self.listView.addItem(item_name) if not initialLoad: - self.plugin.formParent.incrementProgressBar() + self.main_window.incrementProgressBar() if not initialLoad: - self.plugin.formParent.finishedProgressBar() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') def generateSlideData(self, service_item, item=None, xmlVersion=False, remote=False, context=ServiceItemContext.Service): - background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color', u'#000000')) + background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color')) if item: items = [item] else: @@ -188,10 +189,10 @@ class ImageMediaItem(MediaManagerItem): def onResetClick(self): """ - Called to reset the Live backgound with the image selected, + Called to reset the Live background with the image selected, """ self.resetAction.setVisible(False) - self.plugin.liveController.display.resetImage() + self.live_controller.display.resetImage() def liveThemeChanged(self): """ @@ -205,12 +206,12 @@ class ImageMediaItem(MediaManagerItem): """ if check_item_selected(self.listView, translate('ImagePlugin.MediaItem', 'You must select an image to replace the background with.')): - background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color', u'#000000')) + background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color')) item = self.listView.selectedIndexes()[0] bitem = self.listView.item(item.row()) filename = bitem.data(QtCore.Qt.UserRole) if os.path.exists(filename): - if self.plugin.liveController.display.directImage(filename, background): + if self.live_controller.display.directImage(filename, background): self.resetAction.setVisible(True) else: critical_error_message_box(UiStrings().LiveBGError, @@ -221,7 +222,7 @@ class ImageMediaItem(MediaManagerItem): 'the image file "%s" no longer exists.') % filename) def search(self, string, showError): - files = SettingsManager.load_list(self.settingsSection, u'images') + files = Settings().value(self.settingsSection + u'/images files') results = [] string = string.lower() for file in files: diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 1c44a4cda..deca81f77 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -33,8 +33,9 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, SettingsManager, translate, \ - check_item_selected, Receiver, MediaType, ServiceItem, ServiceItemContext, Settings, check_directory_exists -from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_horizontal_adjusting_combo_box + check_item_selected, Receiver, MediaType, ServiceItem, ServiceItemContext, Settings, UiStrings, \ + check_directory_exists +from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.ui import DisplayController, Display, DisplayControllerType from openlp.core.ui.media import get_media_players, set_media_players from openlp.core.utils import AppLocation, locale_compare @@ -63,14 +64,14 @@ class MediaMediaItem(MediaManagerItem): self.mediaObject = None self.displayController = DisplayController(parent) self.displayController.controllerLayout = QtGui.QVBoxLayout() - self.plugin.mediaController.register_controller(self.displayController) - self.plugin.mediaController.set_controls_visible(self.displayController, False) + self.media_controller.register_controller(self.displayController) + self.media_controller.set_controls_visible(self.displayController, False) self.displayController.previewDisplay = Display(self.displayController, False, self.displayController) self.displayController.previewDisplay.hide() self.displayController.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300)) self.displayController.previewDisplay.screen = {u'size':self.displayController.previewDisplay.geometry()} self.displayController.previewDisplay.setup() - self.plugin.mediaController.setup_display(self.displayController.previewDisplay, False) + self.media_controller.setup_display(self.displayController.previewDisplay, False) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'video_background_replaced'), self.videobackgroundReplaced) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_media_rebuild'), self.rebuild_players) @@ -130,7 +131,7 @@ class MediaMediaItem(MediaManagerItem): """ Called to reset the Live background with the media selected, """ - self.plugin.liveController.mediaController.media_reset(self.plugin.liveController) + self.media_controller.media_reset(self.live_controller) self.resetAction.setVisible(False) def videobackgroundReplaced(self): @@ -153,7 +154,7 @@ class MediaMediaItem(MediaManagerItem): service_item.shortname = service_item.title (path, name) = os.path.split(filename) service_item.add_from_command(path, name,CLAPPERBOARD) - if self.plugin.liveController.mediaController.video(DisplayControllerType.Live, service_item, + if self.media_controller.video(DisplayControllerType.Live, service_item, videoBehindText=True): self.resetAction.setVisible(True) else: @@ -185,12 +186,12 @@ class MediaMediaItem(MediaManagerItem): # Only get start and end times if going to a service if context == ServiceItemContext.Service: # Start media and obtain the length - if not self.plugin.mediaController.media_length(service_item): + if not self.media_controller.media_length(service_item): return False service_item.add_capability(ItemCapabilities.CanAutoStartForLive) service_item.add_capability(ItemCapabilities.RequiresMedia) service_item.add_capability(ItemCapabilities.HasDetailedTitleDisplay) - if Settings().value(self.settingsSection + u'/media auto start', QtCore.Qt.Unchecked) == QtCore.Qt.Checked: + if Settings().value(self.settingsSection + u'/media auto start') == QtCore.Qt.Checked: service_item.will_auto_start = True # force a non-existent theme service_item.theme = -1 @@ -201,7 +202,7 @@ class MediaMediaItem(MediaManagerItem): self.listView.setIconSize(QtCore.QSize(88, 50)) self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settingsSection), u'thumbnails') check_directory_exists(self.servicePath) - self.loadList(SettingsManager.load_list(self.settingsSection, u'media')) + self.loadList(Settings().value(self.settingsSection + u'/media files')) self.populateDisplayTypes() def rebuild_players(self): @@ -211,11 +212,11 @@ class MediaMediaItem(MediaManagerItem): """ self.populateDisplayTypes() self.onNewFileMasks = translate('MediaPlugin.MediaItem', 'Videos (%s);;Audio (%s);;%s (*)') % ( - u' '.join(self.plugin.mediaController.video_extensions_list), - u' '.join(self.plugin.mediaController.audio_extensions_list), UiStrings().AllFiles) + u' '.join(self.media_controller.video_extensions_list), + u' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles) def displaySetup(self): - self.plugin.mediaController.setup_display(self.displayController.previewDisplay, False) + self.media_controller.setup_display(self.displayController.previewDisplay, False) def populateDisplayTypes(self): """ @@ -227,7 +228,7 @@ class MediaMediaItem(MediaManagerItem): self.displayTypeComboBox.blockSignals(True) self.displayTypeComboBox.clear() usedPlayers, overridePlayer = get_media_players() - mediaPlayers = self.plugin.mediaController.mediaPlayers + mediaPlayers = self.media_controller.mediaPlayers currentIndex = 0 for player in usedPlayers: # load the drop down selection @@ -253,7 +254,7 @@ class MediaMediaItem(MediaManagerItem): row_list.sort(reverse=True) for row in row_list: self.listView.takeItem(row) - SettingsManager.set_list(self.settingsSection, u'media', self.getFileList()) + Settings().setValue(self.settingsSection + u'/media files', self.getFileList()) def loadList(self, media): # Sort the media by its filename considering language specific @@ -269,7 +270,7 @@ class MediaMediaItem(MediaManagerItem): elif track_info.isFile(): filename = os.path.split(unicode(track))[1] item_name = QtGui.QListWidgetItem(filename) - if u'*.%s' % (filename.split(u'.')[-1].lower()) in self.plugin.mediaController.audio_extensions_list: + if u'*.%s' % (filename.split(u'.')[-1].lower()) in self.media_controller.audio_extensions_list: item_name.setIcon(AUDIO) else: item_name.setIcon(VIDEO) @@ -283,19 +284,19 @@ class MediaMediaItem(MediaManagerItem): self.listView.addItem(item_name) def getList(self, type=MediaType.Audio): - media = SettingsManager.load_list(self.settingsSection, u'media') + media = Settings().value(self.settingsSection + u'/media files') media.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1]) ext = [] if type == MediaType.Audio: - ext = self.plugin.mediaController.audio_extensions_list + ext = self.media_controller.audio_extensions_list else: - ext = self.plugin.mediaController.video_extensions_list + ext = self.media_controller.video_extensions_list ext = map(lambda x: x[1:], ext) media = filter(lambda x: os.path.splitext(x)[1] in ext, media) return media def search(self, string, showError): - files = SettingsManager.load_list(self.settingsSection, u'media') + files = Settings().value(self.settingsSection + u'/media files') results = [] string = string.lower() for file in files: diff --git a/openlp/plugins/media/lib/mediatab.py b/openlp/plugins/media/lib/mediatab.py index 420548038..87a56f238 100644 --- a/openlp/plugins/media/lib/mediatab.py +++ b/openlp/plugins/media/lib/mediatab.py @@ -29,8 +29,8 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, SettingsTab, translate -from openlp.core.lib.ui import UiStrings, create_button +from openlp.core.lib import Receiver, Settings, SettingsTab, translate, UiStrings +from openlp.core.lib.ui import create_button from openlp.core.ui.media import get_media_players, set_media_players class MediaQCheckBox(QtGui.QCheckBox): @@ -72,21 +72,19 @@ class MediaTab(SettingsTab): self.autoStartCheckBox.setText(translate('MediaPlugin.MediaTab', 'Start Live items automatically')) def load(self): - self.overridePlayerCheckBox.setChecked(Settings().value(self.settingsSection + u'/override player', - QtCore.Qt.Unchecked)) - self.autoStartCheckBox.setChecked(Settings().value(self.settingsSection + u'/media auto start', - QtCore.Qt.Unchecked)) + self.overridePlayerCheckBox.setChecked(Settings().value(self.settingsSection + u'/override player')) + self.autoStartCheckBox.setChecked(Settings().value(self.settingsSection + u'/media auto start')) def save(self): override_changed = False setting_key = self.settingsSection + u'/override player' - if Settings().value(setting_key, QtCore.Qt.Unchecked) != self.overridePlayerCheckBox.checkState(): + if Settings().value(setting_key) != self.overridePlayerCheckBox.checkState(): Settings().setValue(setting_key, self.overridePlayerCheckBox.checkState()) override_changed = True setting_key = self.settingsSection + u'/media auto start' - if Settings().value(setting_key, QtCore.Qt.Unchecked) != self.autoStartCheckBox.checkState(): + if Settings().value(setting_key) != self.autoStartCheckBox.checkState(): Settings().setValue(setting_key, self.autoStartCheckBox.checkState()) if override_changed: - self.parent.resetSupportedSuffixes() + self.parent.reset_supported_suffixes() Receiver.send_message(u'mediaitem_media_rebuild') Receiver.send_message(u'mediaitem_suffixes') diff --git a/openlp/plugins/media/mediaplugin.py b/openlp/plugins/media/mediaplugin.py index 9a67af766..d93f120ec 100644 --- a/openlp/plugins/media/mediaplugin.py +++ b/openlp/plugins/media/mediaplugin.py @@ -31,17 +31,23 @@ import logging from PyQt4 import QtCore -from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ - Settings +from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings, Registry from openlp.plugins.media.lib import MediaMediaItem, MediaTab log = logging.getLogger(__name__) +# Some settings starting with "media" are in core, because they are needed for core functionality. +__default_settings__ = { + u'media/media auto start': QtCore.Qt.Unchecked, + u'media/media files': [] + } + + class MediaPlugin(Plugin): log.info(u'%s MediaPlugin loaded', __name__) - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'media', plugin_helpers, MediaMediaItem) + def __init__(self): + Plugin.__init__(self, u'media', __default_settings__, MediaMediaItem) self.weight = -6 self.iconPath = u':/plugins/plugin_media.png' self.icon = build_icon(self.iconPath) @@ -91,26 +97,26 @@ class MediaPlugin(Plugin): Time to tidy up on exit """ log.info(u'Media Finalising') - self.mediaController.finalise() + self.media_controller.finalise() Plugin.finalise(self) def getDisplayCss(self): """ Add css style sheets to htmlbuilder """ - return self.mediaController.get_media_display_css() + return self.media_controller.get_media_display_css() def getDisplayJavaScript(self): """ Add javascript functions to htmlbuilder """ - return self.mediaController.get_media_display_javascript() + return self.media_controller.get_media_display_javascript() def getDisplayHtml(self): """ Add html code to htmlbuilder """ - return self.mediaController.get_media_display_html() + return self.media_controller.get_media_display_html() def appStartup(self): """ @@ -118,11 +124,12 @@ class MediaPlugin(Plugin): we want to check if we have the old "Use Phonon" setting, and convert it to "enable Phonon" and "make it the first one in the list". """ + Plugin.appStartup(self) settings = Settings() settings.beginGroup(self.settingsSection) if settings.contains(u'use phonon'): log.info(u'Found old Phonon setting') - players = self.mediaController.mediaPlayers.keys() + players = self.media_controller.mediaPlayers.keys() has_phonon = u'phonon' in players if settings.value(u'use phonon') and has_phonon: log.debug(u'Converting old setting to new setting') @@ -130,8 +137,18 @@ class MediaPlugin(Plugin): if players: new_players = [player for player in players if player != u'phonon'] new_players.insert(0, u'phonon') - self.mediaController.mediaPlayers[u'phonon'].isActive = True + self.media_controller.mediaPlayers[u'phonon'].isActive = True settings.setValue(u'players', u','.join(new_players)) self.settingsTab.load() settings.remove(u'use phonon') settings.endGroup() + + def _get_media_controller(self): + """ + Adds the media controller to the class dynamically + """ + if not hasattr(self, u'_media_controller'): + self._media_controller = Registry().get(u'media_controller') + return self._media_controller + + media_controller = property(_get_media_controller) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index c34a17562..eee1c5801 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -33,8 +33,8 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, translate, check_item_selected, Receiver, \ - ItemCapabilities, create_thumb, validate_thumb, ServiceItemContext, Settings -from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_horizontal_adjusting_combo_box + ItemCapabilities, create_thumb, validate_thumb, ServiceItemContext, Settings, UiStrings +from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.utils import locale_compare from openlp.plugins.presentations.lib import MessageListener @@ -85,7 +85,7 @@ class PresentationMediaItem(MediaManagerItem): for type in types: if fileType.find(type) == -1: fileType += u'*.%s ' % type - self.plugin.serviceManager.supportedSuffixes(type) + self.service_manager.supported_suffixes(type) self.onNewFileMasks = translate('PresentationPlugin.MediaItem', 'Presentations (%s)') % fileType def requiredIcons(self): @@ -120,7 +120,7 @@ class PresentationMediaItem(MediaManagerItem): Populate the media manager tab """ self.listView.setIconSize(QtCore.QSize(88, 50)) - files = SettingsManager.load_list(self.settingsSection, u'presentations') + files = Settings().value(self.settingsSection + u'/presentations files') self.loadList(files, True) self.populateDisplayTypes() @@ -137,8 +137,7 @@ class PresentationMediaItem(MediaManagerItem): if self.displayTypeComboBox.count() > 1: self.displayTypeComboBox.insertItem(0, self.Automatic) self.displayTypeComboBox.setCurrentIndex(0) - if Settings().value(self.settingsSection + u'/override app', - QtCore.Qt.Unchecked) == QtCore.Qt.Checked: + if Settings().value(self.settingsSection + u'/override app') == QtCore.Qt.Checked: self.presentationWidget.show() else: self.presentationWidget.hide() @@ -154,13 +153,13 @@ class PresentationMediaItem(MediaManagerItem): Receiver.send_message(u'cursor_busy') if not initialLoad: Receiver.send_message(u'cursor_busy') - self.plugin.formParent.displayProgressBar(len(files)) + self.main_window.displayProgressBar(len(files)) # Sort the presentations by its filename considering language specific characters. files.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1]) for file in files: if not initialLoad: - self.plugin.formParent.incrementProgressBar() + self.main_window.incrementProgressBar() if currlist.count(file) > 0: continue filename = os.path.split(unicode(file))[1] @@ -209,7 +208,7 @@ class PresentationMediaItem(MediaManagerItem): self.listView.addItem(item_name) Receiver.send_message(u'cursor_normal') if not initialLoad: - self.plugin.formParent.finishedProgressBar() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') def onDeleteClick(self): @@ -221,19 +220,19 @@ class PresentationMediaItem(MediaManagerItem): row_list = [item.row() for item in items] row_list.sort(reverse=True) Receiver.send_message(u'cursor_busy') - self.plugin.formParent.displayProgressBar(len(row_list)) + self.main_window.displayProgressBar(len(row_list)) for item in items: filepath = unicode(item.data(QtCore.Qt.UserRole)) for cidx in self.controllers: doc = self.controllers[cidx].add_document(filepath) doc.presentation_deleted() doc.close_presentation() - self.plugin.formParent.incrementProgressBar() - self.plugin.formParent.finishedProgressBar() + self.main_window.incrementProgressBar() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') for row in row_list: self.listView.takeItem(row) - SettingsManager.set_list(self.settingsSection, u'presentations', self.getFileList()) + Settings().setValue(self.settingsSection + u'/presentations files', self.getFileList()) def generateSlideData(self, service_item, item=None, xmlVersion=False, remote=False, context=ServiceItemContext.Service): @@ -312,8 +311,7 @@ class PresentationMediaItem(MediaManagerItem): return None def search(self, string, showError): - files = SettingsManager.load_list( - self.settingsSection, u'presentations') + files = Settings().value(self.settingsSection + u'/presentations files') results = [] string = string.lower() for file in files: diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 0c7199825..0051b1d0a 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -387,7 +387,7 @@ class PresentationController(object): """ Return whether the controller is currently enabled """ - if Settings().value(self.settings_section + u'/' + self.name, QtCore.Qt.Checked) == QtCore.Qt.Checked: + if Settings().value(self.settings_section + u'/' + self.name) == QtCore.Qt.Checked: return self.is_available() else: return False diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index 4c2b00174..c72676860 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -29,8 +29,7 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, SettingsTab, translate -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import Receiver, Settings, SettingsTab, translate, UiStrings class PresentationTab(SettingsTab): """ @@ -101,9 +100,8 @@ class PresentationTab(SettingsTab): for key in self.controllers: controller = self.controllers[key] checkbox = self.PresenterCheckboxes[controller.name] - checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name, QtCore.Qt.Checked)) - self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app', - QtCore.Qt.Unchecked)) + checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name)) + self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app')) def save(self): """ @@ -119,7 +117,7 @@ class PresentationTab(SettingsTab): if controller.is_available(): checkbox = self.PresenterCheckboxes[controller.name] setting_key = self.settingsSection + u'/' + controller.name - if Settings().value(setting_key, QtCore.Qt.Checked) != checkbox.checkState(): + if Settings().value(setting_key) != checkbox.checkState(): changed = True Settings().setValue(setting_key, checkbox.checkState()) if checkbox.isChecked(): @@ -127,11 +125,11 @@ class PresentationTab(SettingsTab): else: controller.kill() setting_key = self.settingsSection + u'/override app' - if Settings().value(setting_key, QtCore.Qt.Checked) != self.OverrideAppCheckBox.checkState(): + if Settings().value(setting_key) != self.OverrideAppCheckBox.checkState(): Settings().setValue(setting_key, self.OverrideAppCheckBox.checkState()) changed = True if changed: - self.parent.resetSupportedSuffixes() + self.parent.reset_supported_suffixes() Receiver.send_message(u'mediaitem_presentation_rebuild') Receiver.send_message(u'mediaitem_suffixes') diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 937b78641..883bb4bb8 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -33,6 +33,8 @@ presentations from a variety of document formats. import os import logging +from PyQt4 import QtCore + from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.utils import AppLocation from openlp.plugins.presentations.lib import PresentationController, \ @@ -40,6 +42,15 @@ from openlp.plugins.presentations.lib import PresentationController, \ log = logging.getLogger(__name__) +__default_settings__ = { + u'presentations/override app': QtCore.Qt.Unchecked, + u'presentations/Impress': QtCore.Qt.Checked, + u'presentations/Powerpoint': QtCore.Qt.Checked, + u'presentations/Powerpoint Viewer': QtCore.Qt.Checked, + u'presentations/presentations files': [] + } + + class PresentationPlugin(Plugin): """ This plugin allowed a Presentation to be opened, controlled and displayed @@ -48,13 +59,13 @@ class PresentationPlugin(Plugin): """ log = logging.getLogger(u'PresentationPlugin') - def __init__(self, plugin_helpers): + def __init__(self): """ PluginPresentation constructor. """ log.debug(u'Initialised') self.controllers = {} - Plugin.__init__(self, u'presentations', plugin_helpers) + Plugin.__init__(self, u'presentations', __default_settings__, __default_settings__) self.weight = -8 self.iconPath = u':/plugins/plugin_presentations.png' self.icon = build_icon(self.iconPath) @@ -100,7 +111,7 @@ class PresentationPlugin(Plugin): Create the Media Manager List """ self.mediaItem = PresentationMediaItem( - self.mediaDock.media_dock, self, self.icon, self.controllers) + self.main_window.mediaDockManager.media_dock, self, self.icon, self.controllers) def registerControllers(self, controller): """ diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 7a0adc6d8..af12cc9c4 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -169,8 +169,8 @@ class HttpServer(object): clients. Listen out for socket connections. """ log.debug(u'Start TCP server') - port = Settings().value(self.plugin.settingsSection + u'/port', 4316) - address = Settings().value(self.plugin.settingsSection + u'/ip address', u'0.0.0.0') + port = Settings().value(self.plugin.settingsSection + u'/port') + address = Settings().value(self.plugin.settingsSection + u'/ip address') self.server = QtNetwork.QTcpServer() self.server.listen(QtNetwork.QHostAddress(address), port) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_live_changed'), @@ -252,17 +252,17 @@ class HttpConnection(object): service_items = [] service_manager = self.parent.plugin.serviceManager if self.parent.current_item: - cur_uuid = self.parent.current_item._uuid + current_unique_identifier = self.parent.current_item.unique_identifier else: - cur_uuid = None + current_unique_identifier = None for item in service_manager.serviceItems: service_item = item[u'service_item'] service_items.append({ - u'id': unicode(service_item._uuid), + u'id': unicode(service_item.unique_identifier), u'title': unicode(service_item.get_display_title()), u'plugin': unicode(service_item.name), u'notes': unicode(service_item.notes), - u'selected': (service_item._uuid == cur_uuid) + u'selected': (service_item.unique_identifier == current_unique_identifier) }) return service_items @@ -386,10 +386,10 @@ class HttpConnection(object): Poll OpenLP to determine the current slide number and item name. """ result = { - u'service': self.parent.plugin.serviceManager.serviceId, + u'service': self.parent.plugin.serviceManager.service_id, u'slide': self.parent.current_slide or 0, - u'item': self.parent.current_item._uuid if self.parent.current_item else u'', - u'twelve':Settings().value(u'remotes/twelve hour', True), + u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'', + u'twelve':Settings().value(u'remotes/twelve hour'), u'blank': self.parent.plugin.liveController.blankScreen.isChecked(), u'theme': self.parent.plugin.liveController.themeScreen.isChecked(), u'display': self.parent.plugin.liveController.desktopScreen.isChecked() @@ -459,7 +459,7 @@ class HttpConnection(object): data.append(item) json_data = {u'results': {u'slides': data}} if current_item: - json_data[u'results'][u'item'] = self.parent.current_item._uuid + json_data[u'results'][u'item'] = self.parent.current_item.unique_identifier else: if self.url_params and self.url_params.get(u'data'): try: diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index 9baaae8c2..1d28355c4 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -31,8 +31,10 @@ from PyQt4 import QtCore, QtGui, QtNetwork from openlp.core.lib import Settings, SettingsTab, translate, Receiver + ZERO_URL = u'0.0.0.0' + class RemoteTab(SettingsTab): """ RemoteTab is the Remotes settings tab in the settings dialog. @@ -135,16 +137,16 @@ class RemoteTab(SettingsTab): self.stageUrl.setText(u'%s' % (url, url)) def load(self): - self.portSpinBox.setValue(Settings().value(self.settingsSection + u'/port', 4316)) - self.addressEdit.setText(Settings().value(self.settingsSection + u'/ip address', ZERO_URL)) - self.twelveHour = Settings().value(self.settingsSection + u'/twelve hour', True) + self.portSpinBox.setValue(Settings().value(self.settingsSection + u'/port')) + self.addressEdit.setText(Settings().value(self.settingsSection + u'/ip address')) + self.twelveHour = Settings().value(self.settingsSection + u'/twelve hour') self.twelveHourCheckBox.setChecked(self.twelveHour) self.setUrls() def save(self): changed = False - if Settings().value(self.settingsSection + u'/ip address', ZERO_URL != self.addressEdit.text() or - Settings().value(self.settingsSection + u'/port', 4316) != self.portSpinBox.value()): + if Settings().value(self.settingsSection + u'/ip address') != self.addressEdit.text() or \ + Settings().value(self.settingsSection + u'/port') != self.portSpinBox.value(): changed = True Settings().setValue(self.settingsSection + u'/port', self.portSpinBox.value()) Settings().setValue(self.settingsSection + u'/ip address', self.addressEdit.text()) diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py index b3f9be5f9..160b7d542 100644 --- a/openlp/plugins/remotes/remoteplugin.py +++ b/openlp/plugins/remotes/remoteplugin.py @@ -34,14 +34,21 @@ from openlp.plugins.remotes.lib import RemoteTab, HttpServer log = logging.getLogger(__name__) +__default_settings__ = { + u'remotes/twelve hour': True, + u'remotes/port': 4316, + u'remotes/ip address': u'0.0.0.0' + } + + class RemotesPlugin(Plugin): log.info(u'Remote Plugin loaded') - def __init__(self, plugin_helpers): + def __init__(self): """ remotes constructor """ - Plugin.__init__(self, u'remotes', plugin_helpers, settings_tab_class=RemoteTab) + Plugin.__init__(self, u'remotes', __default_settings__, settings_tab_class=RemoteTab) self.iconPath = u':/plugins/plugin_remote.png' self.icon = build_icon(self.iconPath) self.weight = -1 diff --git a/openlp/plugins/songs/forms/authorsdialog.py b/openlp/plugins/songs/forms/authorsdialog.py index 1e33886a9..c8f1260c9 100644 --- a/openlp/plugins/songs/forms/authorsdialog.py +++ b/openlp/plugins/songs/forms/authorsdialog.py @@ -37,7 +37,7 @@ class Ui_AuthorsDialog(object): authorsDialog.setObjectName(u'AuthorsDialog') authorsDialog.resize(300, 10) self.dialogLayout = QtGui.QVBoxLayout(authorsDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.authorLayout = QtGui.QFormLayout() self.authorLayout.setObjectName(u'authorLayout') self.firstNameLabel = QtGui.QLabel(authorsDialog) @@ -59,8 +59,8 @@ class Ui_AuthorsDialog(object): self.displayLabel.setBuddy(self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit) self.dialogLayout.addLayout(self.authorLayout) - self.buttonBox = create_button_box(authorsDialog, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(authorsDialog, u'button_box', [u'cancel', u'save']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(authorsDialog) authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) diff --git a/openlp/plugins/songs/forms/editsongdialog.py b/openlp/plugins/songs/forms/editsongdialog.py index 4027d2a66..3f6e1e61a 100644 --- a/openlp/plugins/songs/forms/editsongdialog.py +++ b/openlp/plugins/songs/forms/editsongdialog.py @@ -29,8 +29,8 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon, translate -from openlp.core.lib.ui import UiStrings, create_button_box, create_button +from openlp.core.lib import build_icon, translate, UiStrings +from openlp.core.lib.ui import create_button_box, create_button from openlp.plugins.songs.lib.ui import SongStrings class Ui_EditSongDialog(object): @@ -42,7 +42,7 @@ class Ui_EditSongDialog(object): self.dialogLayout = QtGui.QVBoxLayout(editSongDialog) self.dialogLayout.setSpacing(8) self.dialogLayout.setContentsMargins(8, 8, 8, 8) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.songTabWidget = QtGui.QTabWidget(editSongDialog) self.songTabWidget.setObjectName(u'songTabWidget') # lyrics tab @@ -272,8 +272,8 @@ class Ui_EditSongDialog(object): self.warningLabel.setObjectName(u'warningLabel') self.warningLabel.setVisible(False) self.bottomLayout.addWidget(self.warningLabel) - self.buttonBox = create_button_box(editSongDialog, u'buttonBox', [u'cancel', u'save']) - self.bottomLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(editSongDialog, u'button_box', [u'cancel', u'save']) + self.bottomLayout.addWidget(self.button_box) self.dialogLayout.addLayout(self.bottomLayout) self.retranslateUi(editSongDialog) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index e22937cd1..0c0e5c196 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -38,7 +38,8 @@ import shutil from PyQt4 import QtCore, QtGui -from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, create_separated_list, check_directory_exists +from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, create_separated_list, \ + check_directory_exists, Registry, UiStrings from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, critical_error_message_box, \ find_and_set_in_combo_box from openlp.core.utils import AppLocation @@ -87,8 +88,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.onVerseListViewClicked) QtCore.QObject.connect(self.verseOrderEdit, QtCore.SIGNAL(u'textChanged(QString)'), self.onVerseOrderTextChanged) - QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'), - self.mediaitem.plugin.renderer.theme_manager.onAddTheme) + QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'), self.theme_manager.onAddTheme) QtCore.QObject.connect(self.maintenanceButton, QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked) QtCore.QObject.connect(self.audioAddFromFileButton, QtCore.SIGNAL(u'clicked()'), self.onAudioAddFromFileButtonClicked) @@ -101,8 +101,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.previewButton = QtGui.QPushButton() self.previewButton.setObjectName(u'previewButton') self.previewButton.setText(UiStrings().SaveAndPreview) - self.buttonBox.addButton(self.previewButton, QtGui.QDialogButtonBox.ActionRole) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview) + self.button_box.addButton(self.previewButton, QtGui.QDialogButtonBox.ActionRole) + QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview) # Create other objects and forms self.manager = manager self.verseForm = EditVerseForm(self) @@ -775,7 +775,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): Exit Dialog and do not save """ log.debug (u'SongEditForm.reject') - Receiver.send_message(u'songs_edit_clear') self.clearCaches() QtGui.QDialog.reject(self) @@ -908,3 +907,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): except: log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml()) + def _get_theme_manager(self): + """ + Adds the theme manager to the class dynamically + """ + if not hasattr(self, u'_theme_manager'): + self._theme_manager = Registry().get(u'theme_manager') + return self._theme_manager + + theme_manager = property(_get_theme_manager) \ No newline at end of file diff --git a/openlp/plugins/songs/forms/editversedialog.py b/openlp/plugins/songs/forms/editversedialog.py index 402e1f163..603af2180 100644 --- a/openlp/plugins/songs/forms/editversedialog.py +++ b/openlp/plugins/songs/forms/editversedialog.py @@ -39,7 +39,7 @@ class Ui_EditVerseDialog(object): editVerseDialog.resize(400, 400) editVerseDialog.setModal(True) self.dialogLayout = QtGui.QVBoxLayout(editVerseDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.verseTextEdit = SpellTextEdit(editVerseDialog) self.verseTextEdit.setObjectName(u'verseTextEdit') self.dialogLayout.addWidget(self.verseTextEdit) @@ -67,8 +67,8 @@ class Ui_EditVerseDialog(object): self.verseTypeLayout.addWidget(self.insertButton) self.verseTypeLayout.addStretch() self.dialogLayout.addLayout(self.verseTypeLayout) - self.buttonBox = create_button_box(editVerseDialog, u'buttonBox', [u'cancel', u'ok']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(editVerseDialog, u'button_box', [u'cancel', u'ok']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(editVerseDialog) def retranslateUi(self, editVerseDialog): diff --git a/openlp/plugins/songs/forms/mediafilesdialog.py b/openlp/plugins/songs/forms/mediafilesdialog.py index bb628aec4..dd2c4b01a 100644 --- a/openlp/plugins/songs/forms/mediafilesdialog.py +++ b/openlp/plugins/songs/forms/mediafilesdialog.py @@ -52,8 +52,8 @@ class Ui_MediaFilesDialog(object): self.fileListWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.fileListWidget.setObjectName(u'fileListWidget') self.filesVerticalLayout.addWidget(self.fileListWidget) - self.buttonBox = create_button_box(mediaFilesDialog, u'buttonBox', [u'cancel', u'ok']) - self.filesVerticalLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(mediaFilesDialog, u'button_box', [u'cancel', u'ok']) + self.filesVerticalLayout.addWidget(self.button_box) self.retranslateUi(mediaFilesDialog) def retranslateUi(self, mediaFilesDialog): diff --git a/openlp/plugins/songs/forms/songbookdialog.py b/openlp/plugins/songs/forms/songbookdialog.py index fb378fd6e..7c6bf40aa 100644 --- a/openlp/plugins/songs/forms/songbookdialog.py +++ b/openlp/plugins/songs/forms/songbookdialog.py @@ -37,7 +37,7 @@ class Ui_SongBookDialog(object): songBookDialog.setObjectName(u'songBookDialog') songBookDialog.resize(300, 10) self.dialogLayout = QtGui.QVBoxLayout(songBookDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.bookLayout = QtGui.QFormLayout() self.bookLayout.setObjectName(u'bookLayout') self.nameLabel = QtGui.QLabel(songBookDialog) @@ -53,8 +53,8 @@ class Ui_SongBookDialog(object): self.publisherLabel.setBuddy(self.publisherEdit) self.bookLayout.addRow(self.publisherLabel, self.publisherEdit) self.dialogLayout.addLayout(self.bookLayout) - self.buttonBox = create_button_box(songBookDialog, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(songBookDialog, u'button_box', [u'cancel', u'save']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(songBookDialog) songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height()) diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py index 4ea433b66..29d4b8609 100644 --- a/openlp/plugins/songs/forms/songexportform.py +++ b/openlp/plugins/songs/forms/songexportform.py @@ -34,8 +34,8 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon, Receiver, translate, create_separated_list -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import build_icon, Receiver, translate, create_separated_list, UiStrings +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard, WizardStrings from openlp.plugins.songs.lib import natcmp from openlp.plugins.songs.lib.db import Song @@ -331,4 +331,5 @@ class SongExportForm(OpenLPWizard): Called when the *directoryButton* was clicked. Opens a dialog and writes the path to *directoryLineEdit*. """ - self.getFolder(translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'), self.directoryLineEdit) + self.getFolder(translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'), + self.directoryLineEdit, u'last directory export') diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index d9045e163..efadd6b61 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -35,8 +35,8 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, Settings, SettingsManager, translate -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import Receiver, Settings, SettingsManager, translate, UiStrings +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 @@ -59,7 +59,7 @@ class SongImportForm(OpenLPWizard): ``plugin`` The songs plugin. """ - self.clipboard = plugin.formParent.clipboard + self.clipboard = self.main_window.clipboard OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard', u':/wizards/wizard_importsong.bmp') def setupUi(self, image): @@ -250,10 +250,11 @@ class SongImportForm(OpenLPWizard): filters += u';;' filters += u'%s (*)' % UiStrings().AllFiles filenames = QtGui.QFileDialog.getOpenFileNames(self, title, - SettingsManager.get_last_dir(self.plugin.settingsSection, 1), filters) + Settings().value(self.plugin.settingsSection + u'/last directory import'), filters) if filenames: listbox.addItems(filenames) - SettingsManager.set_last_dir(self.plugin.settingsSection, os.path.split(unicode(filenames[0]))[0], 1) + Settings().setValue(self.plugin.settingsSection + u'/last directory import', + os.path.split(unicode(filenames[0]))[0]) def getListOfFiles(self, listbox): """ @@ -275,9 +276,9 @@ class SongImportForm(OpenLPWizard): u'name', u'filter') filepathEdit = self.formatWidgets[format][u'filepathEdit'] if select_mode == SongFormatSelect.SingleFile: - self.getFileName(WizardStrings.OpenTypeFile % format_name, filepathEdit, filter) + self.getFileName(WizardStrings.OpenTypeFile % format_name, filepathEdit, u'last directory import', filter) elif select_mode == SongFormatSelect.SingleFolder: - self.getFolder(WizardStrings.OpenTypeFolder % format_name, filepathEdit) + self.getFolder(WizardStrings.OpenTypeFolder % format_name, filepathEdit, u'last directory import') def onAddButtonClicked(self): format = self.currentFormat @@ -306,7 +307,7 @@ class SongImportForm(OpenLPWizard): self.restart() self.finishButton.setVisible(False) self.cancelButton.setVisible(True) - last_import_type = Settings().value(u'songs/last import type', SongFormat.OpenLyrics) + last_import_type = Settings().value(u'songs/last import type') if last_import_type < 0 or last_import_type >= self.formatComboBox.count(): last_import_type = 0 self.formatComboBox.setCurrentIndex(last_import_type) @@ -360,7 +361,7 @@ class SongImportForm(OpenLPWizard): Save the error report to a file. """ filename = QtGui.QFileDialog.getSaveFileName(self, - SettingsManager.get_last_dir(self.plugin.settingsSection, 1)) + Settings().value(self.plugin.settingsSection + u'last directory import')) if not filename: return report_file = codecs.open(filename, u'w', u'utf-8') diff --git a/openlp/plugins/songs/forms/songmaintenancedialog.py b/openlp/plugins/songs/forms/songmaintenancedialog.py index 455c1a69c..389579284 100644 --- a/openlp/plugins/songs/forms/songmaintenancedialog.py +++ b/openlp/plugins/songs/forms/songmaintenancedialog.py @@ -29,8 +29,8 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon -from openlp.core.lib.ui import UiStrings, create_button_box +from openlp.core.lib import build_icon, UiStrings +from openlp.core.lib.ui import create_button_box from openlp.plugins.songs.lib.ui import SongStrings class Ui_SongMaintenanceDialog(object): @@ -39,7 +39,7 @@ class Ui_SongMaintenanceDialog(object): songMaintenanceDialog.setWindowModality(QtCore.Qt.ApplicationModal) songMaintenanceDialog.resize(10, 350) self.dialogLayout = QtGui.QGridLayout(songMaintenanceDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.typeListWidget = QtGui.QListWidget(songMaintenanceDialog) self.typeListWidget.setIconSize(QtCore.QSize(32, 32)) self.typeListWidget.setUniformItemSizes(True) @@ -130,8 +130,8 @@ class Ui_SongMaintenanceDialog(object): self.stackedLayout.addWidget(self.booksPage) # self.dialogLayout.addLayout(self.stackedLayout, 0, 1) - self.buttonBox = create_button_box(songMaintenanceDialog, u'buttonBox', [u'close']) - self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) + self.button_box = create_button_box(songMaintenanceDialog, u'button_box', [u'close']) + self.dialogLayout.addWidget(self.button_box, 1, 0, 1, 2) self.retranslateUi(songMaintenanceDialog) self.stackedLayout.setCurrentIndex(0) QtCore.QObject.connect(self.typeListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py index 5d62b5888..474e68040 100644 --- a/openlp/plugins/songs/forms/songmaintenanceform.py +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -31,8 +31,8 @@ import logging from PyQt4 import QtGui, QtCore from sqlalchemy.sql import and_ -from openlp.core.lib import Receiver, translate -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib import Receiver, translate, UiStrings +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm from openlp.plugins.songs.lib.db import Author, Book, Topic, Song from songmaintenancedialog import Ui_SongMaintenanceDialog diff --git a/openlp/plugins/songs/forms/topicsdialog.py b/openlp/plugins/songs/forms/topicsdialog.py index c26a92176..9b1a8c11c 100644 --- a/openlp/plugins/songs/forms/topicsdialog.py +++ b/openlp/plugins/songs/forms/topicsdialog.py @@ -37,7 +37,7 @@ class Ui_TopicsDialog(object): topicsDialog.setObjectName(u'topicsDialog') topicsDialog.resize(300, 10) self.dialogLayout = QtGui.QVBoxLayout(topicsDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + self.dialogLayout.setObjectName(u'dialog_layout') self.nameLayout = QtGui.QFormLayout() self.nameLayout.setObjectName(u'nameLayout') self.nameLabel = QtGui.QLabel(topicsDialog) @@ -47,8 +47,8 @@ class Ui_TopicsDialog(object): self.nameLabel.setBuddy(self.nameEdit) self.nameLayout.addRow(self.nameLabel, self.nameEdit) self.dialogLayout.addLayout(self.nameLayout) - self.buttonBox = create_button_box(topicsDialog, u'buttonBox', [u'cancel', u'save']) - self.dialogLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(topicsDialog, u'button_box', [u'cancel', u'save']) + self.dialogLayout.addWidget(self.button_box) self.retranslateUi(topicsDialog) topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height()) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index bd20f5ffd..5c3b6998a 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -32,8 +32,7 @@ The :mod:`importer` modules provides the general song import functionality. import os import logging -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import translate, UiStrings from openlp.core.ui.wizard import WizardStrings from opensongimport import OpenSongImport from easyslidesimport import EasySlidesImport diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 8351c2dd5..de1ad22ff 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -35,15 +35,12 @@ import shutil from PyQt4 import QtCore, QtGui from sqlalchemy.sql import or_ -from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ - translate, check_item_selected, PluginStatus, create_separated_list, \ - check_directory_exists, ServiceItemContext, Settings -from openlp.core.lib.ui import UiStrings, create_widget_action +from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, translate, check_item_selected, \ + PluginStatus, create_separated_list, check_directory_exists, ServiceItemContext, Settings, UiStrings +from openlp.core.lib.ui import create_widget_action from openlp.core.utils import AppLocation -from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ - SongImportForm, SongExportForm -from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ - clean_string, natcmp +from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, SongImportForm, SongExportForm +from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, clean_string, natcmp from openlp.plugins.songs.lib.db import Author, Song, Book, MediaFile from openlp.plugins.songs.lib.ui import SongStrings @@ -71,8 +68,7 @@ class SongMediaItem(MediaManagerItem): def __init__(self, parent, plugin, icon): self.IconPath = u'songs/song' MediaManagerItem.__init__(self, parent, plugin, icon) - self.editSongForm = EditSongForm(self, self.plugin.formParent, - self.plugin.manager) + self.editSongForm = EditSongForm(self, self.main_window, self.plugin.manager) self.openLyrics = OpenLyrics(self.plugin.manager) self.singleServiceItem = False self.songMaintenanceForm = SongMaintenanceForm(self.plugin.manager, self) @@ -106,8 +102,6 @@ class SongMediaItem(MediaManagerItem): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_load_list'), self.onSongListLoad) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_preview'), self.onPreviewClick) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_edit'), self.onRemoteEdit) - QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_edit_clear'), self.onRemoteEditClear) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'searchTypeChanged(int)'), self.onSearchTextButtonClicked) @@ -122,9 +116,9 @@ class SongMediaItem(MediaManagerItem): self.searchTextEdit.setFocus() def configUpdated(self): - self.searchAsYouType = Settings().value(self.settingsSection + u'/search as type', False) - self.updateServiceOnEdit = Settings().value(self.settingsSection + u'/update service on edit', False) - self.addSongFromService = Settings().value(self.settingsSection + u'/add song from service', True) + self.searchAsYouType = Settings().value(self.settingsSection + u'/search as type') + self.updateServiceOnEdit = Settings().value(self.settingsSection + u'/update service on edit') + self.addSongFromService = Settings().value(self.settingsSection + u'/add song from service',) def retranslateUi(self): self.searchTextLabel.setText(u'%s:' % UiStrings().Search) @@ -151,8 +145,7 @@ class SongMediaItem(MediaManagerItem): (SongSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes) ]) - self.searchTextEdit.setCurrentSearchType(Settings().value( - u'%s/last search type' % self.settingsSection, SongSearch.Entire)) + self.searchTextEdit.setCurrentSearchType(Settings().value(u'%s/last search type' % self.settingsSection)) self.configUpdated() def onSearchTextButtonClicked(self): @@ -214,15 +207,10 @@ class SongMediaItem(MediaManagerItem): # Called to redisplay the song list screen edit from a search # or from the exit of the Song edit dialog. If remote editing is active # Trigger it and clean up so it will not update again. - if self.remoteTriggered == u'L': - self.onAddClick() - if self.remoteTriggered == u'P': - self.onPreviewClick() # Push edits to the service manager to update items if self.editItem and self.updateServiceOnEdit and not self.remoteTriggered: item = self.buildServiceItem(self.editItem) - self.plugin.serviceManager.replaceServiceItem(item) - self.onRemoteEditClear() + self.service_manager.replace_service_item(item) self.onSearchTextButtonClicked() log.debug(u'onSongListLoad - finished') @@ -323,28 +311,28 @@ class SongMediaItem(MediaManagerItem): def onSongMaintenanceClick(self): self.songMaintenanceForm.exec_() - def onRemoteEditClear(self): - log.debug(u'onRemoteEditClear') - self.remoteTriggered = None - self.remoteSong = -1 - - def onRemoteEdit(self, message): + def onRemoteEdit(self, song_id, preview=False): """ Called by ServiceManager or SlideController by event passing the Song Id in the payload along with an indicator to say which type of display is required. """ - log.debug(u'onRemoteEdit %s' % message) - remote_type, song_id = message.split(u':') + log.debug(u'onRemoteEdit for song %s' % song_id) song_id = int(song_id) valid = self.plugin.manager.get_object(Song, song_id) if valid: - self.remoteSong = song_id - self.remoteTriggered = remote_type - self.editSongForm.loadSong(song_id, remote_type == u'P') - self.editSongForm.exec_() - self.autoSelectId = -1 - self.onSongListLoad() + self.editSongForm.loadSong(song_id, preview) + if self.editSongForm.exec_() == QtGui.QDialog.Accepted: + self.autoSelectId = -1 + self.onSongListLoad() + self.remoteSong = song_id + self.remoteTriggered = True + item = self.buildServiceItem(remote=True) + self.remoteSong = -1 + self.remoteTriggered = None + if item: + return item + return None def onEditClick(self): """ @@ -374,7 +362,7 @@ class SongMediaItem(MediaManagerItem): QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return Receiver.send_message(u'cursor_busy') - self.plugin.formParent.displayProgressBar(len(items)) + self.main_window.displayProgressBar(len(items)) for item in items: item_id = item.data(QtCore.Qt.UserRole) media_files = self.plugin.manager.get_all_objects(MediaFile, MediaFile.song_id == item_id) @@ -390,8 +378,8 @@ class SongMediaItem(MediaManagerItem): except OSError: log.exception(u'Could not remove directory: %s', save_path) self.plugin.manager.delete_object(Song, item_id) - self.plugin.formParent.incrementProgressBar() - self.plugin.formParent.finishedProgressBar() + self.main_window.incrementProgressBar() + self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') self.onSearchTextButtonClicked() @@ -412,7 +400,7 @@ class SongMediaItem(MediaManagerItem): self.onSongListLoad() def generateSlideData(self, service_item, item=None, xmlVersion=False, - remote=False, context=ServiceItemContext.Service): + remote=False, context=ServiceItemContext.Service): log.debug(u'generateSlideData: %s, %s, %s' % (service_item, item, self.remoteSong)) item_id = self._getIdOfItemToGenerate(item, self.remoteSong) service_item.add_capability(ItemCapabilities.CanEdit) @@ -428,8 +416,7 @@ class SongMediaItem(MediaManagerItem): verse_list = SongXML().get_verses(song.lyrics) # no verse list or only 1 space (in error) verse_tags_translated = False - if VerseType.from_translated_string(unicode( - verse_list[0][0][u'type'])) is not None: + if VerseType.from_translated_string(unicode(verse_list[0][0][u'type'])) is not None: verse_tags_translated = True if not song.verse_order.strip(): for verse in verse_list: @@ -470,9 +457,9 @@ class SongMediaItem(MediaManagerItem): service_item.raw_footer.append(song.title) service_item.raw_footer.append(create_separated_list(author_list)) service_item.raw_footer.append(song.copyright) - if Settings().value(u'general/ccli number', u''): + if Settings().value(u'general/ccli number'): service_item.raw_footer.append(translate('SongsPlugin.MediaItem', 'CCLI License: ') + - Settings().value(u'general/ccli number', u'')) + Settings().value(u'general/ccli number')) service_item.audit = [ song.title, author_list, song.copyright, unicode(song.ccli_number) ] @@ -539,7 +526,7 @@ class SongMediaItem(MediaManagerItem): temporary = True # Update service with correct song id. if editId: - Receiver.send_message(u'service_item_update%s:%s:%s' % (editId, item._uuid, temporary)) + Receiver.send_message(u'service_item_update%s:%s:%s' % (editId, item.unique_identifier, temporary)) def search(self, string, showError): """ diff --git a/openlp/plugins/songs/lib/songstab.py b/openlp/plugins/songs/lib/songstab.py index a067cf04a..6300db4f6 100644 --- a/openlp/plugins/songs/lib/songstab.py +++ b/openlp/plugins/songs/lib/songstab.py @@ -80,36 +80,24 @@ class SongsTab(SettingsTab): 'Import missing songs from service files')) def onSearchAsTypeCheckBoxChanged(self, check_state): - self.song_search = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.song_search = True + self.song_search = (check_state == QtCore.Qt.Checked) def onToolBarActiveCheckBoxChanged(self, check_state): - self.tool_bar = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.tool_bar = True + self.tool_bar = (check_state == QtCore.Qt.Checked) def onUpdateOnEditCheckBoxChanged(self, check_state): - self.update_edit = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.update_edit = True + self.update_edit = (check_state == QtCore.Qt.Checked) def onAddFromServiceCheckBoxChanged(self, check_state): - self.update_load = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.update_load = True + self.update_load = (check_state == QtCore.Qt.Checked) def load(self): settings = Settings() settings.beginGroup(self.settingsSection) - self.song_search = settings.value(u'search as type', False) - self.tool_bar = settings.value(u'display songbar', True) - self.update_edit = settings.value(u'update service on edit', False) - self.update_load = settings.value(u'add song from service', True) + self.song_search = settings.value(u'search as type') + self.tool_bar = settings.value(u'display songbar') + self.update_edit = settings.value(u'update service on edit') + self.update_load = settings.value(u'add song from service') self.searchAsTypeCheckBox.setChecked(self.song_search) self.toolBarActiveCheckBox.setChecked(self.tool_bar) self.updateOnEditCheckBox.setChecked(self.update_edit) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 4f9ab5889..c4c0aa3e0 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -38,19 +38,32 @@ import sqlite3 from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, StringContent, build_icon, translate, Receiver +from openlp.core.lib import Plugin, StringContent, build_icon, translate, Receiver, UiStrings from openlp.core.lib.db import Manager -from openlp.core.lib.ui import UiStrings, create_action +from openlp.core.lib.ui import create_action from openlp.core.utils import get_filesystem_encoding from openlp.core.utils.actions import ActionList from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, SongsTab from openlp.plugins.songs.lib.db import init_schema, Song +from openlp.plugins.songs.lib.mediaitem import SongSearch from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.olpimport import OpenLPSongImport from openlp.plugins.songs.forms.duplicatesongremovalform import \ DuplicateSongRemovalForm log = logging.getLogger(__name__) +__default_settings__ = { + u'songs/db type': u'sqlite', + u'songs/last search type': SongSearch.Entire, + u'songs/last import type': SongFormat.OpenLyrics, + u'songs/update service on edit': False, + u'songs/search as type': False, + u'songs/add song from service': True, + u'songs/display songbar': True, + u'songs/last directory import': u'', + u'songs/last directory export': u'' + } + class SongsPlugin(Plugin): """ @@ -62,11 +75,11 @@ class SongsPlugin(Plugin): """ log.info(u'Song Plugin loaded') - def __init__(self, plugin_helpers): + def __init__(self): """ Create and set up the Songs plugin. """ - Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab) + Plugin.__init__(self, u'songs', __default_settings__, SongMediaItem, SongsTab) self.manager = Manager(u'songs', init_schema, upgrade_mod=upgrade) self.weight = -10 self.iconPath = u':/plugins/plugin_songs.png' @@ -154,7 +167,7 @@ class SongsPlugin(Plugin): if maxSongs == 0: return progressDialog = QtGui.QProgressDialog(translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel, - 0, maxSongs, self.formParent) + 0, maxSongs, self.main_window) progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs')) progressDialog.setWindowModality(QtCore.Qt.WindowModal) songs = self.manager.get_all_objects(Song) @@ -203,8 +216,7 @@ class SongsPlugin(Plugin): ``newTheme`` The new name the plugin should now use. """ - songsUsingTheme = self.manager.get_all_objects(Song, - Song.theme_name == oldTheme) + songsUsingTheme = self.manager.get_all_objects(Song, Song.theme_name == oldTheme) for song in songsUsingTheme: song.theme_name = newTheme self.manager.save_object(song) @@ -264,7 +276,7 @@ class SongsPlugin(Plugin): if not song_dbs: return Receiver.send_message(u'openlp_process_events') - progress = QtGui.QProgressDialog(self.formParent) + progress = QtGui.QProgressDialog(self.main_window) progress.setWindowModality(QtCore.Qt.WindowModal) progress.setWindowTitle(translate('OpenLP.Ui', 'Importing Songs')) progress.setLabelText(translate('OpenLP.Ui', 'Starting import...')) diff --git a/openlp/plugins/songusage/forms/songusagedeletedialog.py b/openlp/plugins/songusage/forms/songusagedeletedialog.py index 5ffefa383..349c3258a 100644 --- a/openlp/plugins/songusage/forms/songusagedeletedialog.py +++ b/openlp/plugins/songusage/forms/songusagedeletedialog.py @@ -49,8 +49,8 @@ class Ui_SongUsageDeleteDialog(object): self.deleteCalendar.setVerticalHeaderFormat(QtGui.QCalendarWidget.NoVerticalHeader) self.deleteCalendar.setObjectName(u'deleteCalendar') self.verticalLayout.addWidget(self.deleteCalendar) - self.buttonBox = create_button_box(songUsageDeleteDialog, u'buttonBox', [u'cancel', u'ok']) - self.verticalLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(songUsageDeleteDialog, u'button_box', [u'cancel', u'ok']) + self.verticalLayout.addWidget(self.button_box) self.retranslateUi(songUsageDeleteDialog) def retranslateUi(self, songUsageDeleteDialog): diff --git a/openlp/plugins/songusage/forms/songusagedeleteform.py b/openlp/plugins/songusage/forms/songusagedeleteform.py index e9dd19af3..8174060bd 100644 --- a/openlp/plugins/songusage/forms/songusagedeleteform.py +++ b/openlp/plugins/songusage/forms/songusagedeleteform.py @@ -44,11 +44,11 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): self.manager = manager QtGui.QDialog.__init__(self, parent) self.setupUi(self) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), + QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onButtonBoxClicked) def onButtonBoxClicked(self, button): - if self.buttonBox.standardButton(button) == QtGui.QDialogButtonBox.Ok: + if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Ok: ret = QtGui.QMessageBox.question(self, translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Selected Song Usage Events?'), translate('SongUsagePlugin.SongUsageDeleteForm', diff --git a/openlp/plugins/songusage/forms/songusagedetaildialog.py b/openlp/plugins/songusage/forms/songusagedetaildialog.py index 0d7d329dc..740771a2b 100644 --- a/openlp/plugins/songusage/forms/songusagedetaildialog.py +++ b/openlp/plugins/songusage/forms/songusagedetaildialog.py @@ -74,8 +74,8 @@ class Ui_SongUsageDetailDialog(object): self.saveFilePushButton.setObjectName(u'saveFilePushButton') self.fileHorizontalLayout.addWidget(self.saveFilePushButton) self.verticalLayout.addWidget(self.fileGroupBox) - self.buttonBox = create_button_box(songUsageDetailDialog, u'buttonBox', [u'cancel', u'ok']) - self.verticalLayout.addWidget(self.buttonBox) + self.button_box = create_button_box(songUsageDetailDialog, u'button_box', [u'cancel', u'ok']) + self.verticalLayout.addWidget(self.button_box) self.retranslateUi(songUsageDetailDialog) QtCore.QObject.connect(self.saveFilePushButton, QtCore.SIGNAL(u'clicked()'), songUsageDetailDialog.defineOutputLocation) diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index dca47f1dd..c455e079c 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -30,11 +30,10 @@ import logging import os -from PyQt4 import QtCore, QtGui +from PyQt4 import QtGui from sqlalchemy.sql import and_ -from openlp.core.lib import Receiver, Settings, SettingsManager, translate, \ - check_directory_exists +from openlp.core.lib import Receiver, Settings, translate, check_directory_exists from openlp.plugins.songusage.lib.db import SongUsageItem from songusagedetaildialog import Ui_SongUsageDetailDialog @@ -58,14 +57,11 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): """ We need to set up the screen """ - year = QtCore.QDate().currentDate().year() - if QtCore.QDate().currentDate().month() < 9: - year -= 1 - toDate = Settings().value(self.plugin.settingsSection + u'/to date', QtCore.QDate(year, 8, 31)) - fromDate = Settings().value(self.plugin.settingsSection + u'/from date', QtCore.QDate(year - 1, 9, 1)) + toDate = Settings().value(self.plugin.settingsSection + u'/to date') + fromDate = Settings().value(self.plugin.settingsSection + u'/from date') self.fromDate.setSelectedDate(fromDate) self.toDate.setSelectedDate(toDate) - self.fileLineEdit.setText(SettingsManager.get_last_dir(self.plugin.settingsSection, 1)) + self.fileLineEdit.setText(Settings().value(self.plugin.settingsSection + u'/last directory export')) def defineOutputLocation(self): """ @@ -73,10 +69,9 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): """ path = QtGui.QFileDialog.getExistingDirectory(self, translate('SongUsagePlugin.SongUsageDetailForm', 'Output File Location'), - SettingsManager.get_last_dir(self.plugin.settingsSection, 1)) - path = unicode(path) + Settings().value(self.plugin.settingsSection + u'/last directory export')) if path: - SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1) + Settings().setValue(self.plugin.settingsSection + u'/last directory export', path) self.fileLineEdit.setText(path) def accept(self): diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 980ef3190..398997715 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -42,11 +42,26 @@ from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem log = logging.getLogger(__name__) + +YEAR = QtCore.QDate().currentDate().year() +if QtCore.QDate().currentDate().month() < 9: + YEAR -= 1 + + +__default_settings__ = { + u'songusage/db type': u'sqlite', + u'songusage/active': False, + u'songusage/to date': QtCore.QDate(YEAR, 8, 31), + u'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1), + u'songusage/last directory export': u'' + } + + class SongUsagePlugin(Plugin): log.info(u'SongUsage Plugin loaded') - def __init__(self, plugin_helpers): - Plugin.__init__(self, u'songusage', plugin_helpers) + def __init__(self): + Plugin.__init__(self, u'songusage', __default_settings__) self.manager = Manager(u'songusage', init_schema, upgrade_mod=upgrade) self.weight = -4 self.icon = build_icon(u':/plugins/plugin_songusage.png') @@ -92,12 +107,12 @@ class SongUsagePlugin(Plugin): self.songUsageMenu.addSeparator() self.songUsageMenu.addAction(self.songUsageReport) self.songUsageMenu.addAction(self.songUsageDelete) - self.songUsageActiveButton = QtGui.QToolButton(self.formParent.statusBar) + self.songUsageActiveButton = QtGui.QToolButton(self.main_window.statusBar) self.songUsageActiveButton.setCheckable(True) self.songUsageActiveButton.setAutoRaise(True) self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin', 'Toggle the tracking of song usage.')) self.songUsageActiveButton.setObjectName(u'songUsageActiveButton') - self.formParent.statusBar.insertPermanentWidget(1, self.songUsageActiveButton) + self.main_window.statusBar.insertPermanentWidget(1, self.songUsageActiveButton) self.songUsageActiveButton.hide() # Signals and slots QtCore.QObject.connect(self.songUsageStatus, QtCore.SIGNAL(u'visibilityChanged(bool)'), @@ -112,15 +127,15 @@ class SongUsagePlugin(Plugin): self.displaySongUsage) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'print_service_started'), self.printSongUsage) - self.songUsageActive = Settings().value(self.settingsSection + u'/active', False) + self.songUsageActive = Settings().value(self.settingsSection + u'/active') # Set the button and checkbox state self.setButtonState() action_list = ActionList.get_instance() action_list.add_action(self.songUsageStatus, translate('SongUsagePlugin', 'Song Usage')) action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) action_list.add_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.formParent) - self.songUsageDetailForm = SongUsageDetailForm(self, self.formParent) + self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.main_window) + self.songUsageDetailForm = SongUsageDetailForm(self, self.main_window) self.songUsageMenu.menuAction().setVisible(True) self.songUsageActiveButton.show() diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py index 0484931cd..176197e24 100644 --- a/tests/functional/openlp_core_lib/test_lib.py +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -349,7 +349,7 @@ class TestLib(TestCase): thumb_mocked_stat = MagicMock() thumb_mocked_stat.st_mtime = datetime.now() - timedelta(seconds=10) mocked_os.path.exists.return_value = True - mocked_os.stat.side_effect = [file_mocked_stat, thumb_mocked_stat] + mocked_os.stat.side_effect = lambda fname: file_mocked_stat if fname == file_path else thumb_mocked_stat # WHEN: we run the validate_thumb() function result = validate_thumb(file_path, thumb_path) diff --git a/tests/functional/openlp_core_lib/test_registry.py b/tests/functional/openlp_core_lib/test_registry.py new file mode 100644 index 000000000..f27eef3d8 --- /dev/null +++ b/tests/functional/openlp_core_lib/test_registry.py @@ -0,0 +1,48 @@ +""" + Package to test the openlp.core.lib package. +""" +import os + +from unittest import TestCase +from mock import MagicMock +from openlp.core.lib import Registry + +TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) + +class TestRegistry(TestCase): + + def registry_basic_test(self): + """ + Test the registry creation and its usage + """ + # GIVEN: A new registry + registry = Registry.create() + + # WHEN: I add a component it should save it + mock_1 = MagicMock() + Registry().register(u'test1', mock_1) + + # THEN: we should be able retrieve the saved component + assert Registry().get(u'test1') == mock_1, u'The saved service can be retrieved and matches' + + # WHEN: I add a component for the second time I am mad. + # THEN and I will get an exception + with self.assertRaises(KeyError) as context: + Registry().register(u'test1', mock_1) + self.assertEqual(context.exception[0], u'Duplicate service exception test1', + u'KeyError exception should have been thrown for duplicate service') + + # WHEN I try to get back a non existent component + # THEN I will get an exception + with self.assertRaises(KeyError) as context: + temp = Registry().get(u'test2') + self.assertEqual(context.exception[0], u'Service test2 not found in list', + u'KeyError exception should have been thrown for missing service') + + # WHEN I try to replace a component I should be allowed (testing only) + Registry().remove(u'test1') + # THEN I will get an exception + with self.assertRaises(KeyError) as context: + temp = Registry().get(u'test1') + self.assertEqual(context.exception[0], u'Service test1 not found in list', + u'KeyError exception should have been thrown for deleted service') diff --git a/tests/functional/openlp_core_lib/test_serviceitem.py b/tests/functional/openlp_core_lib/test_serviceitem.py index c2b9aacb1..a50752cce 100644 --- a/tests/functional/openlp_core_lib/test_serviceitem.py +++ b/tests/functional/openlp_core_lib/test_serviceitem.py @@ -2,10 +2,13 @@ Package to test the openlp.core.lib package. """ import os +import cPickle from unittest import TestCase + from mock import MagicMock -from openlp.core.lib import ServiceItem +from openlp.core.lib import ServiceItem, Registry + VERSE = u'The Lord said to {r}Noah{/r}: \n'\ 'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\ @@ -18,11 +21,22 @@ FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456'] TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) + class TestServiceItem(TestCase): + def setUp(self): + """ + Set up the Registry + """ + registry = Registry.create() + mocked_renderer = MagicMock() + mocked_renderer.format_slide.return_value = [VERSE] + Registry().register(u'renderer', mocked_renderer) + Registry().register(u'image_manager', MagicMock()) + def serviceitem_basic_test(self): """ - Test the Service Item basic test + Test the Service Item - basic test """ # GIVEN: A new service item @@ -35,7 +49,7 @@ class TestServiceItem(TestCase): def serviceitem_add_text_test(self): """ - Test the Service Item add text test + Test the Service Item - add text test """ # GIVEN: A new service item service_item = ServiceItem(None) @@ -48,11 +62,6 @@ class TestServiceItem(TestCase): assert service_item.is_valid is True, u'The new service item should be valid' assert service_item.missing_frames() is False, u'check frames loaded ' - # GIVEN: A service item with text - mocked_renderer = MagicMock() - mocked_renderer.format_slide.return_value = [VERSE] - service_item.renderer = mocked_renderer - # WHEN: Render called assert len(service_item._display_frames) == 0, u'A blank Service Item with no display frames' service_item.render(True) @@ -63,13 +72,11 @@ class TestServiceItem(TestCase): def serviceitem_add_image_test(self): """ - Test the Service Item add image test + Test the Service Item - add image test """ # GIVEN: A new service item and a mocked renderer service_item = ServiceItem(None) service_item.name = u'test' - mocked_renderer = MagicMock() - service_item.renderer = mocked_renderer # WHEN: adding image to a service item test_image = os.path.join(TESTPATH, u'church.jpg') @@ -120,13 +127,11 @@ class TestServiceItem(TestCase): def serviceitem_add_command_test(self): """ - Test the Service Item add command test + Test the Service Item - add command test """ # GIVEN: A new service item and a mocked renderer service_item = ServiceItem(None) service_item.name = u'test' - mocked_renderer = MagicMock() - service_item.renderer = mocked_renderer # WHEN: adding image to a service item test_file = os.path.join(TESTPATH, u'church.jpg') @@ -154,10 +159,55 @@ class TestServiceItem(TestCase): service_item.validate_item([u'jpg']) # THEN the service item should be valid - assert service_item.is_valid is True, u'The service item is valid' + assert service_item.is_valid is True, u'The service item should be valid' # WHEN validating a service item with a different suffix service_item.validate_item([u'png']) # THEN the service item should not be valid assert service_item.is_valid is False, u'The service item is not valid' + + def serviceitem_load_custom_from_service_test(self): + """ + Test the Service Item - adding a custom slide from a saved service + """ + # GIVEN: A new service item and a mocked add icon function + service_item = ServiceItem(None) + mocked_add_icon = MagicMock() + service_item.add_icon = mocked_add_icon + + # WHEN: adding a custom from a saved Service + line = self.convert_file_service_item(u'serviceitem_custom1.osd') + service_item.set_from_service(line) + + # THEN: We should get back a valid service item + assert service_item.is_valid is True, u'The new service item should be valid' + assert len(service_item._display_frames) == 0, u'The service item has no display frames' + assert len(service_item.capabilities) == 5, u'There are 5 default custom item capabilities' + service_item.render(True) + assert (service_item.get_display_title()) == u'Test Custom', u'The custom title should be correct' + + def serviceitem_load_image_from_service_test(self): + """ + Test the Service Item - adding an image from a saved service + """ + # GIVEN: A new service item and a mocked add icon function + service_item = ServiceItem(None) + mocked_add_icon = MagicMock() + service_item.add_icon = mocked_add_icon + + # WHEN: adding a custom from a saved Service + + # THEN: We should get back a valid service item + assert service_item.is_valid is True, u'The new service item should be valid' + + + def convert_file_service_item(self, name): + service_file = os.path.join(TESTPATH, name) + try: + open_file = open(service_file, u'r') + items = cPickle.load(open_file) + first_line = items[0] + except: + first_line = u'' + return first_line \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/test_servicenotedialog.py b/tests/functional/openlp_core_ui/test_servicenotedialog.py new file mode 100644 index 000000000..e444ff687 --- /dev/null +++ b/tests/functional/openlp_core_ui/test_servicenotedialog.py @@ -0,0 +1,67 @@ +""" + Package to test the openlp.core.ui package. +""" +from unittest import TestCase + +from mock import patch +from openlp.core.lib import Registry +from openlp.core.ui import servicenoteform +from PyQt4 import QtCore, QtGui, QtTest + +class TestStartNoteDialog(TestCase): + + def setUp(self): + """ + Create the UI + """ + registry = Registry.create() + self.app = QtGui.QApplication([]) + self.main_window = QtGui.QMainWindow() + Registry().register(u'main_window', self.main_window) + self.form = servicenoteform.ServiceNoteForm() + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + del self.form + del self.main_window + del self.app + + def basic_display_test(self): + """ + Test Service Note form functionality + """ + # GIVEN: A dialog with an empty text box + self.form.text_edit.setPlainText(u'') + + # WHEN displaying the UI and pressing enter + with patch(u'PyQt4.QtGui.QDialog') as mocked_exec: + self.form.exec_() + okWidget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the following input text is returned + self.assertEqual(self.form.text_edit.toPlainText(), u'', u'The returned text should be empty') + + # WHEN displaying the UI, having set the text and pressing enter + text = u'OpenLP is the best worship software' + self.form.text_edit.setPlainText(text) + with patch(u'PyQt4.QtGui.QDialog') as mocked_exec: + self.form.exec_() + okWidget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the following text is returned + self.assertEqual(self.form.text_edit.toPlainText(), text, u'The text originally entered should still be there') + + # WHEN displaying the UI, having set the text and pressing enter + self.form.text_edit.setPlainText(u'') + with patch(u'PyQt4.QtGui.QDialog') as mocked_exec: + self.form.exec_() + self.form.text_edit.setPlainText(text) + okWidget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the following text is returned + self.assertEqual(self.form.text_edit.toPlainText(), text, u'The new text should be returned') \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/test_starttimedialog.py b/tests/functional/openlp_core_ui/test_starttimedialog.py index 0aed81592..918c6637c 100644 --- a/tests/functional/openlp_core_ui/test_starttimedialog.py +++ b/tests/functional/openlp_core_ui/test_starttimedialog.py @@ -1,11 +1,11 @@ """ -Package to test the openlp.core.ui package. + Package to test the openlp.core.ui package. """ import sys from unittest import TestCase -from mock import MagicMock - +from mock import MagicMock, patch +from openlp.core.lib import Registry from openlp.core.ui import starttimeform from PyQt4 import QtCore, QtGui, QtTest @@ -15,43 +15,81 @@ class TestStartTimeDialog(TestCase): """ Create the UI """ + registry = Registry.create() self.app = QtGui.QApplication([]) - self.window = QtGui.QMainWindow() - self.form = starttimeform.StartTimeForm(self.window) + self.main_window = QtGui.QMainWindow() + Registry().register(u'main_window', self.main_window) + self.form = starttimeform.StartTimeForm() def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ del self.form - del self.window + del self.main_window del self.app def ui_defaults_test(self): """ - Test StartTimeDialog defaults + Test StartTimeDialog are defaults correct """ - self.assertEqual(self.form.hourSpinBox.minimum(), 0) - self.assertEqual(self.form.hourSpinBox.maximum(), 4) - self.assertEqual(self.form.minuteSpinBox.minimum(), 0) - self.assertEqual(self.form.minuteSpinBox.maximum(), 59) - self.assertEqual(self.form.secondSpinBox.minimum(), 0) - self.assertEqual(self.form.secondSpinBox.maximum(), 59) - self.assertEqual(self.form.hourFinishSpinBox.minimum(), 0) - self.assertEqual(self.form.hourFinishSpinBox.maximum(), 4) - self.assertEqual(self.form.minuteFinishSpinBox.minimum(), 0) - self.assertEqual(self.form.minuteFinishSpinBox.maximum(), 59) - self.assertEqual(self.form.secondFinishSpinBox.minimum(), 0) - self.assertEqual(self.form.secondFinishSpinBox.maximum(), 59) + self.assertEqual(self.form.hourSpinBox.minimum(), 0, u'The minimum hour should stay the same as the dialog') + self.assertEqual(self.form.hourSpinBox.maximum(), 4, u'The maximum hour should stay the same as the dialog') + self.assertEqual(self.form.minuteSpinBox.minimum(), 0, + u'The minimum minute should stay the same as the dialog') + self.assertEqual(self.form.minuteSpinBox.maximum(), 59, + u'The maximum minute should stay the same as the dialog') + self.assertEqual(self.form.secondSpinBox.minimum(), 0, + u'The minimum second should stay the same as the dialog') + self.assertEqual(self.form.secondSpinBox.maximum(), 59, + u'The maximum second should stay the same as the dialog') + self.assertEqual(self.form.hourFinishSpinBox.minimum(), 0, + u'The minimum finish hour should stay the same as the dialog') + self.assertEqual(self.form.hourFinishSpinBox.maximum(), 4, + u'The maximum finish hour should stay the same as the dialog') + self.assertEqual(self.form.minuteFinishSpinBox.minimum(), 0, + u'The minimum finish minute should stay the same as the dialog') + self.assertEqual(self.form.minuteFinishSpinBox.maximum(), 59, + u'The maximum finish minute should stay the same as the dialog') + self.assertEqual(self.form.secondFinishSpinBox.minimum(), 0, + u'The minimum finish second should stay the same as the dialog') + self.assertEqual(self.form.secondFinishSpinBox.maximum(), 59, + u'The maximum finish second should stay the same as the dialog') def time_display_test(self): """ - Test StartTimeDialog display initialisation + Test StartTimeDialog display functionality """ - #GIVEN: A service item with with time + # GIVEN: A service item with with time mocked_serviceitem = MagicMock() mocked_serviceitem.start_time = 61 mocked_serviceitem.end_time = 3701 + mocked_serviceitem.media_length = 3701 - self.form.item = mocked_serviceitem - #self.form.exec_() + # WHEN displaying the UI and pressing enter + self.form.item = {u'service_item': mocked_serviceitem} + with patch(u'PyQt4.QtGui.QDialog') as mocked_exec: + self.form.exec_() + okWidget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the following input values are returned + self.assertEqual(self.form.hourSpinBox.value(), 0) + self.assertEqual(self.form.minuteSpinBox.value(), 1) + self.assertEqual(self.form.secondSpinBox.value(), 1) + self.assertEqual(self.form.item[u'service_item'].start_time, 61, u'The start time should stay the same') + + # WHEN displaying the UI, changing the time to 2min 3secs and pressing enter + self.form.item = {u'service_item': mocked_serviceitem} + with patch(u'PyQt4.QtGui.QDialog') as mocked_exec: + self.form.exec_() + self.form.minuteSpinBox.setValue(2) + self.form.secondSpinBox.setValue(3) + okWidget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the following values are returned + self.assertEqual(self.form.hourSpinBox.value(), 0) + self.assertEqual(self.form.minuteSpinBox.value(), 2) + self.assertEqual(self.form.secondSpinBox.value(), 3) + self.assertEqual(self.form.item[u'service_item'].start_time, 123, u'The start time should have changed') \ No newline at end of file diff --git a/tests/functional/openlp_core_utils/test_applocation.py b/tests/functional/openlp_core_utils/test_applocation.py index 38cc57d70..f874de4db 100644 --- a/tests/functional/openlp_core_utils/test_applocation.py +++ b/tests/functional/openlp_core_utils/test_applocation.py @@ -48,7 +48,7 @@ class TestAppLocation(TestCase): data_path = AppLocation.get_data_path() # THEN: the mocked Settings methods were called and the value returned was our set up value mocked_settings.contains.assert_called_with(u'advanced/data path') - mocked_settings.value.assert_called_with(u'advanced/data path', u'') + mocked_settings.value.assert_called_with(u'advanced/data path') assert data_path == u'custom/dir', u'Result should be "custom/dir"' def get_section_data_path_test(self): @@ -76,7 +76,7 @@ class TestAppLocation(TestCase): directory = AppLocation.get_directory(AppLocation.AppDir) # THEN: assert directory == u'app/dir', u'Directory should be "app/dir"' - + def get_directory_for_plugins_dir_test(self): """ Test the AppLocation.get_directory() method for AppLocation.PluginsDir @@ -94,4 +94,4 @@ class TestAppLocation(TestCase): directory = AppLocation.get_directory(AppLocation.PluginsDir) # THEN: assert directory == u'plugins/dir', u'Directory should be "plugins/dir"' - + diff --git a/tests/resources/serviceitem_custom1.osd b/tests/resources/serviceitem_custom1.osd new file mode 100644 index 000000000..7f75b39f4 --- /dev/null +++ b/tests/resources/serviceitem_custom1.osd @@ -0,0 +1,96 @@ +(lp1 +(dp2 +Vserviceitem +p3 +(dp4 +Vheader +p5 +(dp6 +Vfooter +p7 +(lp8 +VTest Custom Credits +p9 +asVaudit +p10 +V +sVsearch +p11 +V +sVwill_auto_start +p12 +I00 +sVname +p13 +Vcustom +p14 +sVplugin +p15 +g14 +sVdata +p16 +V +sVnotes +p17 +V +sVtitle +p18 +VTest Custom +p19 +sVfrom_plugin +p20 +I00 +sVcapabilities +p21 +(lp22 +I2 +aI1 +aI5 +aI13 +aI8 +asVmedia_length +p23 +I0 +sVtheme_overwritten +p24 +I00 +sVtheme +p25 +NsVxml_version +p26 +NsVend_time +p27 +I0 +sVbackground_audio +p28 +(lp29 +sVtype +p30 +I1 +sVstart_time +p31 +I0 +sVicon +p32 +V:/plugins/plugin_custom.png +p33 +ssg16 +(lp34 +(dp35 +VverseTag +p36 +NsVraw_slide +p37 +VSlide 1 +p38 +sVtitle +p39 +g38 +sa(dp40 +g36 +Nsg37 +VSlide 2 +p41 +sg39 +g41 +sassa. \ No newline at end of file diff --git a/tests/resources/serviceitem_image1.osd b/tests/resources/serviceitem_image1.osd new file mode 100644 index 000000000..7dfeda2d8 --- /dev/null +++ b/tests/resources/serviceitem_image1.osd @@ -0,0 +1,79 @@ +(lp1 +(dp2 +Vserviceitem +p3 +(dp4 +Vheader +p5 +(dp6 +Vfooter +p7 +(lp8 +sVaudit +p9 +V +sVsearch +p10 +V +sVwill_auto_start +p11 +I00 +sVname +p12 +Vimages +p13 +sVplugin +p14 +g13 +sVdata +p15 +V +sVnotes +p16 +V +sVtitle +p17 +VImages +p18 +sVfrom_plugin +p19 +I00 +sVcapabilities +p20 +(lp21 +I3 +aI1 +aI5 +aI6 +asVmedia_length +p22 +I0 +sVtheme_overwritten +p23 +I00 +sVtheme +p24 +I-1 +sVxml_version +p25 +NsVend_time +p26 +I0 +sVbackground_audio +p27 +(lp28 +sVtype +p29 +I2 +sVstart_time +p30 +I0 +sVicon +p31 +V:/plugins/plugin_images.png +p32 +ssg15 +(lp33 +VIMG_7453.JPG +p34 +assa. \ No newline at end of file