diff --git a/.bzrignore b/.bzrignore index 00884055d..2314d48c5 100644 --- a/.bzrignore +++ b/.bzrignore @@ -14,3 +14,4 @@ dist OpenLP.egg-info build resources/innosetup/Output +_eric4project diff --git a/documentation/source/core/lib.rst b/documentation/source/core/lib.rst index 37360a43a..12c7b702c 100644 --- a/documentation/source/core/lib.rst +++ b/documentation/source/core/lib.rst @@ -30,12 +30,6 @@ .. autoclass:: openlp.core.lib.plugin.Plugin :members: -:mod:`PluginConfig` -------------------- - -.. autoclass:: openlp.core.lib.pluginconfig.PluginConfig - :members: - :mod:`PluginManager` -------------------- diff --git a/openlp.pyw b/openlp.pyw index 528923862..0c1227b6a 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -34,10 +34,10 @@ from PyQt4 import QtCore, QtGui log = logging.getLogger() -from openlp.core.lib import Receiver, str_to_bool +from openlp.core.lib import Receiver from openlp.core.resources import qInitResources from openlp.core.ui import MainWindow, SplashScreen, ScreenList -from openlp.core.utils import AppLocation, ConfigHelper +from openlp.core.utils import AppLocation application_stylesheet = u""" QMainWindow::separator @@ -110,20 +110,17 @@ class OpenLP(QtGui.QApplication): finally: if fversion: fversion.close() - #set the default string encoding - try: - sys.setappdefaultencoding(u'utf-8') - except: - pass #provide a listener for widgets to reqest a screen update. QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'process_events'), self.processEvents) + QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) + self.setOrganizationName(u'OpenLP') + self.setOrganizationDomain(u'openlp.org') self.setApplicationName(u'OpenLP') self.setApplicationVersion(app_version[u'version']) if os.name == u'nt': self.setStyleSheet(application_stylesheet) - show_splash = str_to_bool(ConfigHelper.get_registry().get_value( - u'general', u'show splash', True)) + show_splash = QtCore.QSettings().value( + u'general/show splash', QtCore.QVariant(True)).toBool() if show_splash: self.splash = SplashScreen(self.applicationVersion()) self.splash.show() @@ -133,8 +130,8 @@ class OpenLP(QtGui.QApplication): # Decide how many screens we have and their size for screen in xrange(0, self.desktop().numScreens()): screens.add_screen({u'number': screen, - u'size': self.desktop().availableGeometry(screen), - u'primary': (self.desktop().primaryScreen() == screen)}) + u'size': self.desktop().availableGeometry(screen), + u'primary': (self.desktop().primaryScreen() == screen)}) log.info(u'Screen %d found with resolution %s', screen, self.desktop().availableGeometry(screen)) # start the main app window diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 38bcd127c..c8570a643 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -164,7 +164,6 @@ class ThemeLevel(object): from eventreceiver import Receiver from settingsmanager import SettingsManager -from pluginconfig import PluginConfig from plugin import PluginStatus, Plugin from pluginmanager import PluginManager from settingstab import SettingsTab diff --git a/openlp/core/lib/baselistwithdnd.py b/openlp/core/lib/baselistwithdnd.py index bc043082c..d34eada98 100644 --- a/openlp/core/lib/baselistwithdnd.py +++ b/openlp/core/lib/baselistwithdnd.py @@ -48,5 +48,4 @@ class BaseListWithDnD(QtGui.QListWidget): mimeData = QtCore.QMimeData() drag.setMimeData(mimeData) mimeData.setText(self.PluginName) - dropAction = drag.start(QtCore.Qt.CopyAction) - + drag.start(QtCore.Qt.CopyAction) diff --git a/openlp/core/lib/dockwidget.py b/openlp/core/lib/dockwidget.py index fcee02af8..083c99184 100644 --- a/openlp/core/lib/dockwidget.py +++ b/openlp/core/lib/dockwidget.py @@ -43,8 +43,3 @@ class OpenLPDockWidget(QtGui.QDockWidget): self.setObjectName(name) self.setFloating(False) log.debug(u'Init done') - - def closeEvent(self, event): - self.parent.settingsmanager.setUIItemVisibility( - self.objectName(), False) - event.accept() diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 2e1cf9d39..d21e3f167 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -35,36 +35,118 @@ class EventReceiver(QtCore.QObject): system. This is a private class and should not be used directly but rather via the Receiver class. - ``stop_import`` - Stops the Bible Import - - ``pre_load_bibles`` - Triggers the plugin to relaod the bible lists - - ``process_events`` + ``openlp_process_events`` Requests the Application to flush the events queue - ``{plugin}_add_service_item`` - ask the plugin to push the selected items to the service item + ``openlp_version_check`` + Version has changed so pop up window. - ``update_themes`` + ``config_updated`` + Informs components the config has changed + + ``config_screen_changed`` + The display monitor has been changed + + ``slidecontroller_{live|preview}_first`` + Moves to the first slide + + ``slidecontroller_{live|preview}_next`` + Moves to the next slide + + ``slidecontroller_{live|preview}_next_noloop`` + Moves to the next slide without auto advance + + ``slidecontroller_{live|preview}_previous`` + Moves to the previous slide + + ``slidecontroller_{live|preview}_previous_noloop`` + Moves to the previous slide, without auto advance + + ``slidecontroller_{live|preview}_last`` + Moves to the last slide + + ``slidecontroller_{live|preview}_set`` + Moves to a specific slide, by index + + ``slidecontroller_{live|preview}_started`` + Broadcasts that an item has been made live/previewed + + ``slidecontroller_{live|preview}_change`` + Informs the slidecontroller that a slide change has occurred and to + update itself + + ``slidecontroller_{live|preview}_changed`` + Broadcasts that the slidecontroller has changed the current slide + + ``slidecontroller_{live|preview}_text_request`` + Request the text for the current item in the controller + Returns a slidecontroller_{live|preview}_text_response with an + array of dictionaries with the tag and verse text + + ``slidecontroller_{live|preview}_blank`` + Request that the output screen is blanked + + ``slidecontroller_{live|preview}_unblank`` + Request that the output screen is unblanked + + ``slidecontroller_live_spin_delay`` + Pushes out the loop delay + + ``slidecontroller_live_stop_loop`` + Stop the loop on the main display + + ``servicemanager_previous_item`` + Display the previous item in the service + + ``servicemanager_next_item`` + Display the next item in the service + + ``servicemanager_set_item`` + Go live on a specific item, by index + + ``servicemanager_list_request`` + Request the service list. Responds with servicemanager_list_response + containing a array of dictionaries + + ``maindisplay_blank`` + Blank the maindisplay window + + ``maindisplay_hide`` + Hide the maindisplay window + + ``maindisplay_show`` + Return the maindisplay window + + ``maindisplay_active`` + The maindisplay has been made active + + ``maindisplay_status_text`` + Changes the bottom status bar text on the maindisplay window + + ``maindisplay_blank_check`` + Check to see if the blank display message is required + + ``videodisplay_start`` + Open a media item and prepare for playing + + ``videodisplay_play`` + Start playing a media item + + ``videodisplay_pause`` + Pause a media item + + ``videodisplay_stop`` + Stop playing a media item + + ``videodisplay_background`` + Replace the background video + + ``theme_update_list`` send out message with new themes - ``update_global_theme`` + ``theme_update_global`` Tell the components we have a new global theme - ``load_song_list`` - Tells the the song plugin to reload the song list - - ``load_custom_list`` - Tells the the custom plugin to reload the custom list - - ``update_spin_delay`` - Pushes out the Image loop delay - - ``request_spin_delay`` - Requests a spin delay - ``{plugin}_start`` Requests a plugin to start a external program Path and file provided in message @@ -81,42 +163,51 @@ class EventReceiver(QtCore.QObject): ``{plugin}_last`` Requests a plugin to handle a last event + ``{plugin}_slide`` + Requests a plugin to handle a go to specific slide event + ``{plugin}_stop`` Requests a plugin to handle a stop event + ``{plugin}_blank`` + Requests a plugin to handle a blank screen event + + ``{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 - ``songusage_live`` - Sends live song audit requests to the audit component + ``{plugin}_edit_clear`` + Editing has been completed - ``audit_changed`` - Audit information may have changed + ``{plugin}_load_list`` + Tells the the plugin to reload the media manager list - ``config_updated`` - Informs components the config has changed + ``{plugin}_preview`` + Tells the plugin it's item can be previewed - ``preview_song`` - Tells the song plugin the edit has finished and the song can be previewed - Only available if the edit was triggered by the Preview button. + ``{plugin}_add_service_item`` + Ask the plugin to push the selected items to the service item - ``slidecontroller_change`` - Informs the slidecontroller that a slide change has occurred + ``alerts_text`` + Displays an alert message + + ``bibles_nobook`` + Attempt to find book resulted in no match - ``remote_edit_clear`` - Informs all components that remote edit has been aborted. + ``bibles_showprogress`` + Show progress of bible verse import - ``presentation types`` - Informs all components of the presentation types supported. + ``bibles_hideprogress`` + Hide progress of bible verse import - ``blank_check`` - Check to see if th eblank display message is required + ``bibles_stop_import`` + Stops the Bible Import - ``version_check`` - Version has changed so pop up window. - - ``mainDisplay_active`` - Version has changed so pop up window. + ``remotes_poll_request`` + Waits for openlp to do something "interesting" and sends a + remotes_poll_response signal when it does """ def __init__(self): @@ -173,4 +264,3 @@ class Receiver(): Get the global ``eventreceiver`` instance. """ return Receiver.eventreceiver - diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 7ac2a6f0a..36cc738b8 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -29,7 +29,8 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib.toolbar import * -from openlp.core.lib import contextMenuAction, contextMenuSeparator +from openlp.core.lib import contextMenuAction, contextMenuSeparator, \ + SettingsManager from serviceitem import ServiceItem log = logging.getLogger(__name__) @@ -69,11 +70,6 @@ class MediaManagerItem(QtGui.QWidget): The user visible name for a plugin which should use a suitable translation function. - ``self.ConfigSection`` - The section in the configuration where the items in the media - manager are stored. This could potentially be - ``self.PluginNameShort.lower()``. - ``self.OnNewPrompt`` Defaults to *'Select Image(s)'*. @@ -102,6 +98,7 @@ class MediaManagerItem(QtGui.QWidget): """ QtGui.QWidget.__init__(self) self.parent = parent + self.settingsSection = title.lower() if type(icon) is QtGui.QIcon: self.icon = icon elif type(icon) is types.StringType: @@ -334,18 +331,20 @@ class MediaManagerItem(QtGui.QWidget): def onFileClick(self): files = QtGui.QFileDialog.getOpenFileNames( self, self.OnNewPrompt, - self.parent.config.get_last_dir(), self.OnNewFileMasks) + SettingsManager.get_last_dir(self.settingsSection), + self.OnNewFileMasks) log.info(u'New files(s) %s', unicode(files)) if files: self.loadList(files) - dir, filename = os.path.split(unicode(files[0])) - self.parent.config.set_last_dir(dir) - self.parent.config.set_list(self.ConfigSection, self.getFileList()) + dir = os.path.split(unicode(files[0]))[0] + SettingsManager.set_last_dir(self.settingsSection, dir) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def getFileList(self): count = 0 filelist = [] - while count < self.ListView.count(): + while count < self.ListView.count(): bitem = self.ListView.item(count) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) filelist.append(filename) @@ -357,11 +356,14 @@ class MediaManagerItem(QtGui.QWidget): Validates to see if the file still exists or thumbnail is up to date """ - filedate = os.stat(file).st_mtime - thumbdate = os.stat(thumb).st_mtime - #if file updated rebuild icon - if filedate > thumbdate: - self.IconFromFile(file, thumb) + if os.path.exists(file): + filedate = os.stat(file).st_mtime + thumbdate = os.stat(thumb).st_mtime + #if file updated rebuild icon + if filedate > thumbdate: + self.IconFromFile(file, thumb) + return True + return False def IconFromFile(self, file, thumb): icon = build_icon(unicode(file)) @@ -422,12 +424,13 @@ class MediaManagerItem(QtGui.QWidget): else: #Is it posssible to process multiple list items to generate multiple #service items? - if self.singleServiceItem: + if self.singleServiceItem or self.remoteTriggered: log.debug(self.PluginNameShort + u' Add requested') service_item = self.buildServiceItem() if service_item: service_item.from_plugin = False - self.parent.service_manager.addServiceItem(service_item) + self.parent.service_manager.addServiceItem(service_item, + replace=self.remoteTriggered) else: items = self.ListView.selectedIndexes() for item in items: @@ -447,16 +450,18 @@ class MediaManagerItem(QtGui.QWidget): if not service_item: QtGui.QMessageBox.information(self, self.trUtf8('No Service Item Selected'), - self.trUtf8('You must select a existing service item to add to.')) + self.trUtf8( + 'You must select an existing service item to add to.')) elif self.title.lower() == service_item.name.lower(): self.generateSlideData(service_item) - self.parent.service_manager.addServiceItem(service_item) + self.parent.service_manager.addServiceItem(service_item, + replace=True) else: #Turn off the remote edit update message indicator - self.parent.service_manager.remoteEditTriggered = False QtGui.QMessageBox.information(self, self.trUtf8('Invalid Service Item'), - self.trUtf8(unicode('You must select a %s service item.' % self.title))) + self.trUtf8(unicode( + 'You must select a %s service item.' % self.title))) def buildServiceItem(self, item=None): """ @@ -471,4 +476,4 @@ class MediaManagerItem(QtGui.QWidget): if self.generateSlideData(service_item, item): return service_item else: - return None \ No newline at end of file + return None diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index 57dd984c3..ebb38615d 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -24,9 +24,10 @@ ############################################################################### import logging + from PyQt4 import QtCore -from openlp.core.lib import PluginConfig, Receiver +from openlp.core.lib import Receiver log = logging.getLogger(__name__) @@ -50,13 +51,12 @@ class Plugin(QtCore.QObject): ``version`` The version number of this iteration of the plugin. + ``settingsSection`` + The namespace to store settings for the plugin. + ``icon`` An instance of QIcon, which holds an icon for this plugin. - ``config`` - An instance of PluginConfig, which allows plugins to read and write to - openlp.org's configuration. This is pre-instantiated. - ``log`` A log object used to log debugging messages. This is pre-instantiated. @@ -78,7 +78,8 @@ class Plugin(QtCore.QObject): Add an item to the Export menu. ``get_settings_tab()`` - Returns an instance of SettingsTabItem to be used in the Settings dialog. + Returns an instance of SettingsTabItem to be used in the Settings + dialog. ``add_to_menu(menubar)`` A method to add a menu item to anywhere in the menu, given the menu bar. @@ -115,8 +116,8 @@ class Plugin(QtCore.QObject): self.name = name if version: self.version = version + self.settingsSection = self.name.lower() self.icon = None - self.config = PluginConfig(self.name) self.weight = 0 self.status = PluginStatus.Inactive # Set up logging @@ -125,7 +126,7 @@ class Plugin(QtCore.QObject): self.live_controller = plugin_helpers[u'live'] self.render_manager = plugin_helpers[u'render'] self.service_manager = plugin_helpers[u'service'] - self.settings = plugin_helpers[u'settings'] + self.settings_form = plugin_helpers[u'settings form'] self.mediadock = plugin_helpers[u'toolbox'] self.maindisplay = plugin_helpers[u'maindisplay'] QtCore.QObject.connect(Receiver.get_receiver(), @@ -145,15 +146,17 @@ class Plugin(QtCore.QObject): """ Sets the status of the plugin """ - self.status = int(self.config.get_config(u'status', - PluginStatus.Inactive)) + self.status = QtCore.QSettings().value( + self.settingsSection + u'/status', + QtCore.QVariant(PluginStatus.Inactive)).toInt()[0] def toggle_status(self, new_status): """ Changes the status of the plugin and remembers it """ self.status = new_status - self.config.set_config(u'status', self.status) + QtCore.QSettings().setValue( + self.settingsSection + u'/status', QtCore.QVariant(self.status)) def is_active(self): """ @@ -212,12 +215,16 @@ class Plugin(QtCore.QObject): """ pass - def process_add_service_event(self): + def process_add_service_event(self, replace=False): """ Generic Drag and drop handler triggered from service_manager. """ - log.debug(u'process_add_service_event event called for plugin %s' % self.name) - self.media_item.onAddClick() + log.debug(u'process_add_service_event event called for plugin %s' % + self.name) + if replace: + self.media_item.onAddEditClick() + else: + self.media_item.onAddClick() def about(self): """ @@ -244,7 +251,7 @@ class Plugin(QtCore.QObject): Called by the plugin to remove toolbar """ self.mediadock.remove_dock(self.name) - self.settings.removeTab(self.name) + self.settings_form.removeTab(self.name) def insert_toolbox_item(self): """ @@ -253,7 +260,7 @@ class Plugin(QtCore.QObject): if self.media_item: self.mediadock.insert_dock(self.media_item, self.icon, self.weight) if self.settings_tab: - self.settings.insertTab(self.settings_tab, self.weight) + self.settings_form.insertTab(self.settings_tab, self.weight) def can_delete_theme(self, theme): """ diff --git a/openlp/core/lib/pluginconfig.py b/openlp/core/lib/pluginconfig.py deleted file mode 100644 index e27b86669..000000000 --- a/openlp/core/lib/pluginconfig.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2010 Raoul Snyman # -# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # -# Thompson, Jon Tibble, Carsten Tinggaard # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### - -import os - -from openlp.core.utils import ConfigHelper - -class PluginConfig(object): - """ - This is a generic config helper for plugins. - """ - def __init__(self, plugin_name): - """ - Initialise the plugin config object, setting the section name to the - plugin name. - - ``plugin_name`` - The name of the plugin to use as a section name. - """ - self.section = plugin_name.lower() - - def get_config(self, key, default=None): - """ - Get a configuration value from the configuration registry. - - ``key`` - The name of configuration to load. - - ``default`` - Defaults to *None*. The default value to return if there is no - other value. - """ - return ConfigHelper.get_config(self.section, key, default) - - def delete_config(self, key): - """ - Delete a configuration value from the configuration registry. - - ``key`` - The name of the configuration to remove. - """ - return ConfigHelper.delete_config(self.section, key) - - def set_config(self, key, value): - """ - Set a configuration value in the configuration registry. - - ``key`` - The name of the configuration to save. - - ``value`` - The value of the configuration to save. - """ - return ConfigHelper.set_config(self.section, key, value) - - def get_data_path(self): - """ - Dynamically build the data file path for a plugin. - """ - #app_data = ConfigHelper.get_data_path() - app_data = ConfigHelper.get_data_path() - safe_name = self.section.replace(u' ',u'-') - plugin_data = self.get_config(u'data path', safe_name) - path = os.path.join(app_data, plugin_data) - if not os.path.exists(path): - os.makedirs(path) - return path - - def set_data_path(self, path): - """ - Set the data file path. - - ``path`` - The path to save. - """ - return self.set_config(u'data path', os.path.basename(path)) - - def get_files(self, suffix=None): - """ - Get a list of files from the data files path. - - ``suffix`` - Defaults to *None*. The extension to search for. - """ - try: - files = os.listdir(self.get_data_path()) - except: - return [] - if suffix: - return_files = [] - for file in files: - if file.find(u'.') != -1: - filename = file.split(u'.') - #bname = nme[0] - filesuffix = filename[1].lower() - filesuffix = filesuffix.lower() - # only load files with the correct suffix - if suffix.find(filesuffix) > -1 : - return_files.append(file) - return return_files - else: - # no filtering required - return files - - def load_list(self, name): - """ - Load a list from the config file. - - ``name`` - The name of the list. - """ - list_count = self.get_config(u'%s count' % name) - if list_count: - list_count = int(list_count) - else: - list_count = 0 - list = [] - if list_count > 0: - for counter in range(0, list_count): - item = self.get_config(u'%s %d' % (name, counter)) - if item: - list.append(item) - return list - - def set_list(self, name, list): - """ - Save a list to the config file. - - ``name`` - The name of the list to save. - - ``list`` - The list of values to save. - """ - old_count = int(self.get_config(u'%s count' % name, int(0))) - new_count = len(list) - self.set_config(u'%s count' % name, new_count) - for counter in range (0, new_count): - self.set_config(u'%s %d' % (name, counter), list[counter-1]) - if old_count > new_count: - # Tidy up any old list itrms if list is smaller now - for counter in range(new_count, old_count): - self.delete_config(u'%s %d' % (name, counter)) - - def get_last_dir(self, num=None): - """ - Read the last directory used for plugin. - - ``num`` - Defaults to *None*. A further qualifier. - """ - if num: - name = u'last directory %d' % num - else: - name = u'last directory' - last_dir = self.get_config(name) - if not last_dir: - last_dir = u'' - return last_dir - - def set_last_dir(self, directory, num=None): - """ - Save the last directory used for plugin. - - ``num`` - Defaults to *None*. A further qualifier. - """ - if num: - name = u'last directory %d' % num - else: - name = u'last directory' - self.set_config(name, directory) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index f574ed6a8..cfb0e2bc2 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -48,8 +48,8 @@ class Renderer(object): self.theme_name = None self._theme = None self._bg_image_filename = None - self._frame = None - self._frameOp = None + self.frame = None + self.frame_opaque = None self.bg_frame = None self.bg_image = None @@ -89,10 +89,10 @@ class Renderer(object): """ log.debug(u'set bg image %s', filename) self._bg_image_filename = unicode(filename) - if self._frame: + if self.frame: self.bg_image = resize_image(self._bg_image_filename, - self._frame.width(), - self._frame.height()) + self.frame.width(), + self.frame.height()) def set_frame_dest(self, frame_width, frame_height, preview=False): """ @@ -111,14 +111,13 @@ class Renderer(object): self.bg_frame = None log.debug(u'set frame dest (frame) w %d h %d', frame_width, frame_height) - self._frame = QtGui.QImage(frame_width, frame_height, + self.frame = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) - self._frameOp = QtGui.QImage(frame_width, frame_height, + self.frame_opaque = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) if self._bg_image_filename and not self.bg_image: self.bg_image = resize_image(self._bg_image_filename, - self._frame.width(), - self._frame.height()) + self.frame.width(), self.frame.height()) if self.bg_frame is None: self._generate_background_frame() @@ -223,7 +222,7 @@ class Renderer(object): ``rect_footer`` The footer text block. """ - log.debug(u'set_text_rectangle %s , %s' %(rect_main, rect_footer) ) + log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer)) self._rect = rect_main self._rect_footer = rect_footer @@ -243,8 +242,9 @@ class Renderer(object): if footer_lines: bbox1 = self._render_lines_unaligned(footer_lines, True) # reset the frame. first time do not worry about what you paint on. - self._frame = QtGui.QImage(self.bg_frame) - self._frameOp = QtGui.QImage(self.bg_frame) + self.frame = QtGui.QImage(self.bg_frame) + if self._theme.display_slideTransition: + self.frame_opaque = QtGui.QImage(self.bg_frame) x, y = self._correctAlignment(self._rect, bbox) bbox = self._render_lines_unaligned(lines, False, (x, y), True) if footer_lines: @@ -252,9 +252,9 @@ class Renderer(object): (self._rect_footer.left(), self._rect_footer.top()), True) log.debug(u'generate_frame_from_lines - Finish') if self._theme.display_slideTransition: - return {u'main':self._frame, u'trans':self._frameOp} + return {u'main':self.frame, u'trans':self.frame_opaque} else: - return {u'main':self._frame, u'trans':None} + return {u'main':self.frame, u'trans':None} def _generate_background_frame(self): """ @@ -264,36 +264,36 @@ class Renderer(object): assert(self._theme) if self._theme.background_mode == u'transparent': self.bg_frame = \ - QtGui.QPixmap(self._frame.width(), self._frame.height()) + QtGui.QPixmap(self.frame.width(), self.frame.height()) self.bg_frame.fill(QtCore.Qt.transparent) else: - self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + self.bg_frame = QtGui.QImage(self.frame.width(), + self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied) log.debug(u'render background %s start', self._theme.background_type) painter = QtGui.QPainter() painter.begin(self.bg_frame) if self._theme.background_mode == u'transparent': - painter.fillRect(self._frame.rect(), QtCore.Qt.transparent) + painter.fillRect(self.frame.rect(), QtCore.Qt.transparent) else: if self._theme.background_type == u'solid': - painter.fillRect(self._frame.rect(), + painter.fillRect(self.frame.rect(), QtGui.QColor(self._theme.background_color)) elif self._theme.background_type == u'gradient': # gradient gradient = None if self._theme.background_direction == u'horizontal': - w = int(self._frame.width()) / 2 + w = int(self.frame.width()) / 2 # vertical gradient = QtGui.QLinearGradient(w, 0, w, - self._frame.height()) + self.frame.height()) elif self._theme.background_direction == u'vertical': - h = int(self._frame.height()) / 2 + h = int(self.frame.height()) / 2 # Horizontal - gradient = QtGui.QLinearGradient(0, h, self._frame.width(), + gradient = QtGui.QLinearGradient(0, h, self.frame.width(), h) else: - w = int(self._frame.width()) / 2 - h = int(self._frame.height()) / 2 + w = int(self.frame.width()) / 2 + h = int(self.frame.height()) / 2 # Circular gradient = QtGui.QRadialGradient(w, h, w) gradient.setColorAt(0, @@ -302,8 +302,8 @@ class Renderer(object): QtGui.QColor(self._theme.background_endColor)) painter.setBrush(QtGui.QBrush(gradient)) rectPath = QtGui.QPainterPath() - max_x = self._frame.width() - max_y = self._frame.height() + max_x = self.frame.width() + max_y = self.frame.height() rectPath.moveTo(0, 0) rectPath.lineTo(0, max_y) rectPath.lineTo(max_x, max_y) @@ -312,7 +312,7 @@ class Renderer(object): painter.drawPath(rectPath) elif self._theme.background_type == u'image': # image - painter.fillRect(self._frame.rect(), QtCore.Qt.black) + painter.fillRect(self.frame.rect(), QtCore.Qt.black) if self.bg_image: painter.drawImage(0, 0, self.bg_image) painter.end() @@ -378,7 +378,7 @@ class Renderer(object): retval = QtCore.QRect(x, y, brx - x, bry - y) if self._debug: painter = QtGui.QPainter() - painter.begin(self._frame) + painter.begin(self.frame) painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255))) painter.drawRect(retval) painter.end() @@ -414,11 +414,11 @@ class Renderer(object): starty = y rightextent = None self.painter = QtGui.QPainter() - self.painter.begin(self._frame) + self.painter.begin(self.frame) self.painter.setRenderHint(QtGui.QPainter.Antialiasing) if self._theme.display_slideTransition: self.painter2 = QtGui.QPainter() - self.painter2.begin(self._frameOp) + self.painter2.begin(self.frame_opaque) self.painter2.setRenderHint(QtGui.QPainter.Antialiasing) self.painter2.setOpacity(0.7) # dont allow alignment messing with footers @@ -463,10 +463,11 @@ class Renderer(object): # now draw the text, and any outlines/shadows if self._theme.display_shadow: self._get_extent_and_render(line, footer, - tlcorner=(x + display_shadow_size, y + display_shadow_size), - draw=True, color = self._theme.display_shadow_color) - self._get_extent_and_render(line, footer, tlcorner=(x, y), draw=True, - outline_size=display_outline_size) + tlcorner=(x + display_shadow_size, + y + display_shadow_size), + draw=True, color = self._theme.display_shadow_color) + self._get_extent_and_render(line, footer, tlcorner=(x, y), + draw=True, outline_size=display_outline_size) y += h if linenum == 0: self._first_line_right_extent = rightextent @@ -532,7 +533,7 @@ class Renderer(object): font = self.mainFont metrics = QtGui.QFontMetrics(font) w = metrics.width(line) - h = metrics.height() + h = metrics.height() + int(self._theme.font_main_line_adjustment) if draw: self.painter.setFont(font) if color is None: @@ -543,27 +544,29 @@ class Renderer(object): else: pen = QtGui.QColor(color) x, y = tlcorner + rowpos = y + metrics.ascent() if self._theme.display_outline and outline_size != 0 and not footer: path = QtGui.QPainterPath() - path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line) + path.addText(QtCore.QPointF(x, rowpos), font, line) self.painter.setBrush(self.painter.pen().brush()) - self.painter.setPen(QtGui.QPen( - QtGui.QColor(self._theme.display_outline_color), outline_size)) + self.painter.setPen(QtGui.QPen(QtGui.QColor( + self._theme.display_outline_color), outline_size)) self.painter.drawPath(path) self.painter.setPen(pen) - self.painter.drawText(x, y + metrics.ascent(), line) + self.painter.drawText(x, rowpos, line) if self._theme.display_slideTransition: # Print 2nd image with 70% weight if self._theme.display_outline and outline_size != 0 and not footer: path = QtGui.QPainterPath() - path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line) + path.addText(QtCore.QPointF(x, rowpos), font, line) self.painter2.setBrush(self.painter2.pen().brush()) self.painter2.setPen(QtGui.QPen( - QtGui.QColor(self._theme.display_outline_color), outline_size)) + QtGui.QColor(self._theme.display_outline_color), + outline_size)) self.painter2.drawPath(path) self.painter2.setFont(font) self.painter2.setPen(pen) - self.painter2.drawText(x, y + metrics.ascent(), line) + self.painter2.drawText(x, rowpos, line) return (w, h) def snoop_Image(self, image, image2=None): @@ -578,4 +581,4 @@ class Renderer(object): """ image.save(u'renderer.png', u'png') if image2: - image2.save(u'renderer2.png', u'png') + image2.save(u'renderer2.png', u'png') \ No newline at end of file diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 8601e818e..2f6d973e2 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -30,7 +30,7 @@ import uuid from PyQt4 import QtGui -from openlp.core.lib import build_icon, Receiver, resize_image +from openlp.core.lib import build_icon, resize_image log = logging.getLogger(__name__) @@ -48,7 +48,7 @@ class ItemCapabilities(object): AllowsMaintain = 3 RequiresMedia = 4 AllowsLoop = 5 - + AllowsAdditions = 6 class ServiceItem(object): """ @@ -336,6 +336,3 @@ class ServiceItem(object): """ return self._raw_frames[row][u'path'] - def request_audit(self): - if self.audit: - Receiver.send_message(u'songusage_live', self.audit) diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index fe2858cd0..de1401d56 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -23,14 +23,16 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from openlp.core.lib import str_to_bool -from openlp.core.utils import ConfigHelper +import os + +from PyQt4 import QtCore + +from openlp.core.utils import AppLocation class SettingsManager(object): """ - Class to control the size of the UI components so they size correctly. - This class is created by the main window and then calculates the size of - individual components. + Class to control the initial settings for the UI and provide helper + functions for the loading and saving of application settings. """ def __init__(self, screen): self.screen = screen.current @@ -50,26 +52,131 @@ class SettingsManager(object): self.mainwindow_left + self.mainwindow_right) - 100 ) / 2 self.slidecontroller_image = self.slidecontroller - 50 - self.showMediaManager = str_to_bool(ConfigHelper.get_config( - u'user interface', u'media manager', True)) - self.showServiceManager = str_to_bool(ConfigHelper.get_config( - u'user interface', u'service manager', True)) - self.showThemeManager = str_to_bool(ConfigHelper.get_config( - u'user interface', u'theme manager', True)) - self.showPreviewPanel = str_to_bool(ConfigHelper.get_config( - u'user interface', u'preview panel', True)) - - def setUIItemVisibility(self, item=u'', isVisible=True): - if item: - if item == u'ThemeManagerDock': - ConfigHelper.set_config(u'user interface', - u'theme manager', isVisible) - elif item == u'ServiceManagerDock': - ConfigHelper.set_config(u'user interface', - u'service manager', isVisible) - elif item == u'MediaManagerDock': - ConfigHelper.set_config(u'user interface', - u'media manager', isVisible) + self.showPreviewPanel = QtCore.QSettings().value( + u'user interface/preview panel', True).toBool() def togglePreviewPanel(self, isVisible): - ConfigHelper.set_config(u'user interface', u'preview panel', isVisible) + QtCore.QSettings().setValue(u'user interface/preview panel', + QtCore.QVariant(isVisible)) + + @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' + last_dir = unicode(QtCore.QSettings().value( + section + u'/' + name, QtCore.QVariant(u'')).toString()) + return last_dir + + @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' + QtCore.QSettings().setValue( + section + u'/' + name, QtCore.QVariant(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 = QtCore.QSettings() + settings.beginGroup(section) + old_count = settings.value( + u'%s count' % name, QtCore.QVariant(0)).toInt()[0] + new_count = len(list) + settings.setValue(u'%s count' % name, QtCore.QVariant(new_count)) + for counter in range (0, new_count): + settings.setValue( + u'%s %d' % (name, counter), QtCore.QVariant(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 = QtCore.QSettings() + settings.beginGroup(section) + list_count = settings.value( + u'%s count' % name, QtCore.QVariant(0)).toInt()[0] + list = [] + if list_count: + for counter in range(0, list_count): + item = unicode( + settings.value(u'%s %d' % (name, counter)).toString()) + 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. + + ``extension`` + Defaults to *None*. The extension to search for. + """ + path = AppLocation.get_data_path() + if section: + path = os.path.join(path, section) + try: + files = os.listdir(path) + except: + return [] + if extension: + return [file for file in files + if extension == os.path.splitext(file)[1]] + else: + # no filtering required + return files diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index 930ce6bc8..0b862d9f8 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -25,35 +25,25 @@ from PyQt4 import QtGui -from openlp.core.lib import PluginConfig - class SettingsTab(QtGui.QWidget): """ SettingsTab is a helper widget for plugins to define Tabs for the settings dialog. """ - def __init__(self, title, section=None): + def __init__(self, title): """ Constructor to create the Settings tab item. ``title`` - Defaults to *None*. The title of the tab, which is usually - displayed on the tab. - - ``section`` - Defaults to *None*. This is the section in the configuration file - to write to when the ``save`` method is called. + The title of the tab, which is usually displayed on the tab. """ QtGui.QWidget.__init__(self) self.tabTitle = title self.tabTitleVisible = None + self.settingsSection = self.tabTitle.lower() self.setupUi() self.retranslateUi() self.initialise() - if section is None: - self.config = PluginConfig(title) - else: - self.config = PluginConfig(section) self.preLoad() self.load() diff --git a/openlp/core/lib/themexmlhandler.py b/openlp/core/lib/themexmlhandler.py index c30184328..a96cc7355 100644 --- a/openlp/core/lib/themexmlhandler.py +++ b/openlp/core/lib/themexmlhandler.py @@ -53,6 +53,7 @@ blankthemexml=\ Normal False 0 + 0 @@ -62,6 +63,7 @@ blankthemexml=\ Normal False 0 + 0 @@ -171,8 +173,8 @@ class ThemeXML(object): self.child_element(background, u'filename', filename) def add_font(self, name, color, proportion, override, fonttype=u'main', - weight=u'Normal', italics=u'False', indentation=0, xpos=0, ypos=0, - width=0, height=0): + weight=u'Normal', italics=u'False', indentation=0, line_adjustment=0, + xpos=0, ypos=0, width=0, height=0): """ Add a Font. @@ -227,6 +229,8 @@ class ThemeXML(object): self.child_element(background, u'italics', italics) #Create indentation name element self.child_element(background, u'indentation', unicode(indentation)) + #Create indentation name element + self.child_element(background, u'line_adjustment', unicode(line_adjustment)) #Create Location element element = self.theme_xml.createElement(u'location') diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 675c57476..76b84503e 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -23,6 +23,16 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +class HideMode(object): + """ + This is basically an enumeration class which specifies the mode of a Bible. + Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to + be downloaded from the Internet on an as-needed basis. + """ + Blank = 1 + Theme = 2 + Screen = 3 + from slidecontroller import HideMode from servicenoteform import ServiceNoteForm from serviceitemeditform import ServiceItemEditForm @@ -33,6 +43,7 @@ from maindisplay import DisplayManager from amendthemeform import AmendThemeForm from slidecontroller import SlideController from splashscreen import SplashScreen +from displaytab import DisplayTab from generaltab import GeneralTab from themestab import ThemesTab from aboutform import AboutForm diff --git a/openlp/core/ui/amendthemedialog.py b/openlp/core/ui/amendthemedialog.py index 65d675cd1..c713eb608 100644 --- a/openlp/core/ui/amendthemedialog.py +++ b/openlp/core/ui/amendthemedialog.py @@ -178,16 +178,22 @@ class Ui_AmendThemeDialog(object): self.FontMainWeightLabel.setObjectName("FontMainWeightLabel") self.MainFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.FontMainWeightLabel) self.MainLeftLayout.addWidget(self.FontMainGroupBox) + self.FontMainWrapLineAdjustmentLabel = QtGui.QLabel(self.FontMainGroupBox) + self.FontMainWrapLineAdjustmentLabel.setObjectName("FontMainWrapLineAdjustmentLabel") + self.MainFontLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.FontMainWrapLineAdjustmentLabel) + self.FontMainLineAdjustmentSpinBox = QtGui.QSpinBox(self.FontMainGroupBox) + self.FontMainLineAdjustmentSpinBox.setObjectName("FontMainLineAdjustmentSpinBox") + self.MainFontLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.FontMainLineAdjustmentSpinBox) self.FontMainWrapIndentationLabel = QtGui.QLabel(self.FontMainGroupBox) self.FontMainWrapIndentationLabel.setObjectName("FontMainWrapIndentationLabel") - self.MainFontLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.FontMainWrapIndentationLabel) + self.MainFontLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.FontMainWrapIndentationLabel) self.FontMainLineSpacingSpinBox = QtGui.QSpinBox(self.FontMainGroupBox) self.FontMainLineSpacingSpinBox.setObjectName("FontMainLineSpacingSpinBox") self.FontMainLineSpacingSpinBox.setMaximum(10) - self.MainFontLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.FontMainLineSpacingSpinBox) + self.MainFontLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.FontMainLineSpacingSpinBox) self.FontMainLinesPageLabel = QtGui.QLabel(self.FontMainGroupBox) self.FontMainLinesPageLabel.setObjectName("FontMainLinesPageLabel") - self.MainFontLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.FontMainLinesPageLabel) + self.MainFontLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.FontMainLinesPageLabel) spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.MainLeftLayout.addItem(spacerItem1) self.FontMainLayout.addWidget(self.MainLeftWidget) @@ -620,6 +626,7 @@ class Ui_AmendThemeDialog(object): self.FontMainSize.setText(self.trUtf8('Size:')) self.FontMainSizeSpinBox.setSuffix(self.trUtf8('pt')) self.FontMainWrapIndentationLabel.setText(self.trUtf8('Wrap Indentation')) + self.FontMainWrapLineAdjustmentLabel.setText(self.trUtf8('Adjust Line Spacing')) self.FontMainWeightComboBox.setItemText(0, self.trUtf8('Normal')) self.FontMainWeightComboBox.setItemText(1, self.trUtf8('Bold')) self.FontMainWeightComboBox.setItemText(2, self.trUtf8('Italics')) diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index 03c2df3f5..fab72c312 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -101,6 +101,9 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.QObject.connect(self.FontMainHeightSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontMainHeightSpinBoxChanged) + QtCore.QObject.connect(self.FontMainLineAdjustmentSpinBox, + QtCore.SIGNAL(u'editingFinished()'), + self.onFontMainLineAdjustmentSpinBoxChanged) QtCore.QObject.connect(self.FontMainLineSpacingSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontMainLineSpacingSpinBoxChanged) @@ -130,7 +133,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.SIGNAL(u'editingFinished()'), self.onOutlineSpinBoxChanged) QtCore.QObject.connect(self.SlideTransitionCheckedBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckedBoxChanged) + QtCore.SIGNAL(u'stateChanged(int)'), + self.onSlideTransitionCheckedBoxChanged) def accept(self): new_theme = ThemeXML() @@ -142,10 +146,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): new_theme.add_background_transparent() else: if self.theme.background_type == u'solid': - new_theme.add_background_solid( \ + new_theme.add_background_solid( unicode(self.theme.background_color)) elif self.theme.background_type == u'gradient': - new_theme.add_background_gradient( \ + new_theme.add_background_gradient( unicode(self.theme.background_startColor), unicode(self.theme.background_endColor), self.theme.background_direction) @@ -155,7 +159,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): new_theme.add_background_image(filename) save_to = os.path.join(self.path, theme_name, filename) save_from = self.theme.background_filename - new_theme.add_font(unicode(self.theme.font_main_name), unicode(self.theme.font_main_color), unicode(self.theme.font_main_proportion), @@ -163,6 +166,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): unicode(self.theme.font_main_weight), unicode(self.theme.font_main_italics), unicode(self.theme.font_main_indentation), + unicode(self.theme.font_main_line_adjustment), unicode(self.theme.font_main_x), unicode(self.theme.font_main_y), unicode(self.theme.font_main_width), @@ -173,11 +177,12 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): unicode(self.theme.font_footer_override), u'footer', unicode(self.theme.font_footer_weight), unicode(self.theme.font_footer_italics), - 0, + 0, # indentation + 0, # line adjustment unicode(self.theme.font_footer_x), unicode(self.theme.font_footer_y), unicode(self.theme.font_footer_width), - unicode(self.theme.font_footer_height) ) + unicode(self.theme.font_footer_height)) new_theme.add_display(unicode(self.theme.display_shadow), unicode(self.theme.display_shadow_color), unicode(self.theme.display_outline), @@ -261,6 +266,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): self.FontMainYSpinBox.setValue(self.theme.font_main_y) self.FontMainWidthSpinBox.setValue(self.theme.font_main_width) self.FontMainHeightSpinBox.setValue(self.theme.font_main_height) + self.FontMainLineAdjustmentSpinBox.setValue( + self.theme.font_main_line_adjustment) self.FontMainLineSpacingSpinBox.setValue( self.theme.font_main_indentation) self.stateChanging(self.theme) @@ -281,6 +288,13 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): self.theme.font_main_width = self.FontMainWidthSpinBox.value() self.previewTheme() + def onFontMainLineAdjustmentSpinBoxChanged(self): + if self.theme.font_main_line_adjustment != \ + self.FontMainLineAdjustmentSpinBox.value(): + self.theme.font_main_line_adjustment = \ + self.FontMainLineAdjustmentSpinBox.value() + self.previewTheme() + def onFontMainLineSpacingSpinBoxChanged(self): if self.theme.font_main_indentation != \ self.FontMainLineSpacingSpinBox.value(): @@ -687,7 +701,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): if self.allowPreview: #calculate main number of rows metrics = self._getThemeMetrics() - line_height = metrics.height() + line_height = metrics.height() \ + + int(self.theme.font_main_line_adjustment) if self.theme.display_shadow: line_height += int(self.theme.display_shadow_size) if self.theme.display_outline: @@ -700,7 +715,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): page_length)) page_length_text = unicode(self.trUtf8('Slide Height is %s rows')) self.FontMainLinesPageLabel.setText(page_length_text % page_length) - #a=c frame = self.thememanager.generateImage(self.theme) self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) diff --git a/openlp/core/ui/displaytab.py b/openlp/core/ui/displaytab.py new file mode 100644 index 000000000..38a0baa91 --- /dev/null +++ b/openlp/core/ui/displaytab.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # +# Thompson, Jon Tibble, Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +from PyQt4 import QtGui, QtCore + +from openlp.core.lib import SettingsTab, Receiver + +class DisplayTab(SettingsTab): + """ + Class documentation goes here. + """ + def __init__(self, screens): + """ + Constructor + """ + self.screens = screens + SettingsTab.__init__(self, u'Display') + + def setupUi(self): + self.tabTitleVisible = self.trUtf8('Displays') + self.layoutWidget = QtGui.QWidget(self) + self.layoutWidget.setGeometry(QtCore.QRect(0, 40, 241, 79)) + self.layoutWidget.setObjectName("layoutWidget") + self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget) + self.verticalLayout.setObjectName("verticalLayout") + self.CurrentGroupBox = QtGui.QGroupBox(self.layoutWidget) + self.CurrentGroupBox.setObjectName("CurrentGroupBox") + self.horizontalLayout = QtGui.QHBoxLayout(self.CurrentGroupBox) + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout_6 = QtGui.QVBoxLayout() + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.XLabel = QtGui.QLabel(self.CurrentGroupBox) + self.XLabel.setAlignment(QtCore.Qt.AlignCenter) + self.XLabel.setObjectName("XLabel") + self.verticalLayout_6.addWidget(self.XLabel) + self.Xpos = QtGui.QLabel(self.CurrentGroupBox) + self.Xpos.setAlignment(QtCore.Qt.AlignCenter) + self.Xpos.setObjectName("Xpos") + self.verticalLayout_6.addWidget(self.Xpos) + self.horizontalLayout.addLayout(self.verticalLayout_6) + self.verticalLayout_7 = QtGui.QVBoxLayout() + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.YLabel = QtGui.QLabel(self.CurrentGroupBox) + self.YLabel.setAlignment(QtCore.Qt.AlignCenter) + self.YLabel.setObjectName("YLabel") + self.verticalLayout_7.addWidget(self.YLabel) + self.Ypos = QtGui.QLabel(self.CurrentGroupBox) + self.Ypos.setAlignment(QtCore.Qt.AlignCenter) + self.Ypos.setObjectName("Ypos") + self.verticalLayout_7.addWidget(self.Ypos) + self.horizontalLayout.addLayout(self.verticalLayout_7) + self.verticalLayout_9 = QtGui.QVBoxLayout() + self.verticalLayout_9.setObjectName("verticalLayout_9") + self.HeightLabel = QtGui.QLabel(self.CurrentGroupBox) + self.HeightLabel.setMaximumSize(QtCore.QSize(100, 16777215)) + self.HeightLabel.setAlignment(QtCore.Qt.AlignCenter) + self.HeightLabel.setObjectName("HeightLabel") + self.verticalLayout_9.addWidget(self.HeightLabel) + self.Height = QtGui.QLabel(self.CurrentGroupBox) + self.Height.setAlignment(QtCore.Qt.AlignCenter) + self.Height.setObjectName("Height") + self.verticalLayout_9.addWidget(self.Height) + self.horizontalLayout.addLayout(self.verticalLayout_9) + self.verticalLayout_8 = QtGui.QVBoxLayout() + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.WidthLabel = QtGui.QLabel(self.CurrentGroupBox) + self.WidthLabel.setAlignment(QtCore.Qt.AlignCenter) + self.WidthLabel.setObjectName("WidthLabel") + self.verticalLayout_8.addWidget(self.WidthLabel) + self.Width = QtGui.QLabel(self.CurrentGroupBox) + self.Width.setAlignment(QtCore.Qt.AlignCenter) + self.Width.setObjectName("Width") + self.verticalLayout_8.addWidget(self.Width) + self.horizontalLayout.addLayout(self.verticalLayout_8) + self.verticalLayout.addWidget(self.CurrentGroupBox) + self.CurrentGroupBox_2 = QtGui.QGroupBox(self) + self.CurrentGroupBox_2.setGeometry(QtCore.QRect(0, 130, 248, 87)) + self.CurrentGroupBox_2.setMaximumSize(QtCore.QSize(500, 16777215)) + self.CurrentGroupBox_2.setObjectName("CurrentGroupBox_2") + self.horizontalLayout_2 = QtGui.QHBoxLayout(self.CurrentGroupBox_2) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.verticalLayout_2 = QtGui.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.XAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2) + self.XAmendLabel.setAlignment(QtCore.Qt.AlignCenter) + self.XAmendLabel.setObjectName("XAmendLabel") + self.verticalLayout_2.addWidget(self.XAmendLabel) + self.XposEdit = QtGui.QLineEdit(self.CurrentGroupBox_2) + self.XposEdit.setMaximumSize(QtCore.QSize(50, 16777215)) + self.XposEdit.setMaxLength(4) + self.XposEdit.setObjectName("XposEdit") + self.verticalLayout_2.addWidget(self.XposEdit) + self.horizontalLayout_2.addLayout(self.verticalLayout_2) + self.verticalLayout_3 = QtGui.QVBoxLayout() + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.YAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2) + self.YAmendLabel.setAlignment(QtCore.Qt.AlignCenter) + self.YAmendLabel.setObjectName("YAmendLabel") + self.verticalLayout_3.addWidget(self.YAmendLabel) + self.YposEdit = QtGui.QLineEdit(self.CurrentGroupBox_2) + self.YposEdit.setMaximumSize(QtCore.QSize(50, 16777215)) + self.YposEdit.setMaxLength(4) + self.YposEdit.setObjectName("YposEdit") + self.verticalLayout_3.addWidget(self.YposEdit) + self.horizontalLayout_2.addLayout(self.verticalLayout_3) + self.verticalLayout_4 = QtGui.QVBoxLayout() + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.HeightAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2) + self.HeightAmendLabel.setAlignment(QtCore.Qt.AlignCenter) + self.HeightAmendLabel.setObjectName("HeightAmendLabel") + self.verticalLayout_4.addWidget(self.HeightAmendLabel) + self.HeightEdit = QtGui.QLineEdit(self.CurrentGroupBox_2) + self.HeightEdit.setMaximumSize(QtCore.QSize(50, 16777215)) + self.HeightEdit.setMaxLength(4) + self.HeightEdit.setObjectName("HeightEdit") + self.verticalLayout_4.addWidget(self.HeightEdit) + self.horizontalLayout_2.addLayout(self.verticalLayout_4) + self.verticalLayout_5 = QtGui.QVBoxLayout() + self.verticalLayout_5.setSizeConstraint(QtGui.QLayout.SetMinimumSize) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.WidthAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2) + self.WidthAmendLabel.setMaximumSize(QtCore.QSize(100, 16777215)) + self.WidthAmendLabel.setAlignment(QtCore.Qt.AlignCenter) + self.WidthAmendLabel.setObjectName("WidthAmendLabel") + self.verticalLayout_5.addWidget(self.WidthAmendLabel) + self.WidthEdit = QtGui.QLineEdit(self.CurrentGroupBox_2) + self.WidthEdit.setMaximumSize(QtCore.QSize(60, 16777215)) + self.WidthEdit.setObjectName("WidthEdit") + self.verticalLayout_5.addWidget(self.WidthEdit) + self.horizontalLayout_2.addLayout(self.verticalLayout_5) + self.OverrideCheckBox = QtGui.QCheckBox(self) + self.OverrideCheckBox.setGeometry(QtCore.QRect(0, 10, 191, 23)) + self.OverrideCheckBox.setObjectName("OverrideCheckBox") + QtCore.QMetaObject.connectSlotsByName(self) + QtCore.QObject.connect(self.OverrideCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onOverrideCheckBoxChanged) + + def retranslateUi(self): + self.setWindowTitle(QtGui.QApplication.translate("self", "Amend Display Settings", None, QtGui.QApplication.UnicodeUTF8)) + self.CurrentGroupBox.setTitle(QtGui.QApplication.translate("self", "Default Settings", None, QtGui.QApplication.UnicodeUTF8)) + self.XLabel.setText(QtGui.QApplication.translate("self", "X", None, QtGui.QApplication.UnicodeUTF8)) + self.Xpos.setText(QtGui.QApplication.translate("self", "0", None, QtGui.QApplication.UnicodeUTF8)) + self.YLabel.setText(QtGui.QApplication.translate("self", "Y", None, QtGui.QApplication.UnicodeUTF8)) + self.Ypos.setText(QtGui.QApplication.translate("self", "0", None, QtGui.QApplication.UnicodeUTF8)) + self.HeightLabel.setText(QtGui.QApplication.translate("self", "Height", None, QtGui.QApplication.UnicodeUTF8)) + self.Height.setText(QtGui.QApplication.translate("self", "0", None, QtGui.QApplication.UnicodeUTF8)) + self.WidthLabel.setText(QtGui.QApplication.translate("self", "Width", None, QtGui.QApplication.UnicodeUTF8)) + self.Width.setText(QtGui.QApplication.translate("self", "0", None, QtGui.QApplication.UnicodeUTF8)) + self.CurrentGroupBox_2.setTitle(QtGui.QApplication.translate("self", "Amend Settings", None, QtGui.QApplication.UnicodeUTF8)) + self.XAmendLabel.setText(QtGui.QApplication.translate("self", "X", None, QtGui.QApplication.UnicodeUTF8)) + self.YAmendLabel.setText(QtGui.QApplication.translate("self", "Y", None, QtGui.QApplication.UnicodeUTF8)) + self.HeightAmendLabel.setText(QtGui.QApplication.translate("self", "Height", None, QtGui.QApplication.UnicodeUTF8)) + self.WidthAmendLabel.setText(QtGui.QApplication.translate("self", "Width", None, QtGui.QApplication.UnicodeUTF8)) + self.OverrideCheckBox.setText(QtGui.QApplication.translate("self", "Override Output Display", None, QtGui.QApplication.UnicodeUTF8)) + + def load(self): + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.Xpos.setText(unicode(self.screens.current[u'size'].x())) + self.Ypos.setText(unicode(self.screens.current[u'size'].y())) + self.Height.setText(unicode(self.screens.current[u'size'].height())) + self.Width.setText(unicode(self.screens.current[u'size'].width())) + xpos = settings.value(u'x position', + QtCore.QVariant(self.screens.current[u'size'].x())).toString() + self.XposEdit.setText(xpos) + ypos = settings.value(u'y position', + QtCore.QVariant(self.screens.current[u'size'].y())).toString() + self.YposEdit.setText(ypos) + height = settings.value(u'height', + QtCore.QVariant(self.screens.current[u'size'].height())).toString() + self.HeightEdit.setText(height) + width = settings.value(u'width', + QtCore.QVariant(self.screens.current[u'size'].width())).toString() + self.WidthEdit.setText(width) + self.amend_display = settings.value(u'amend display', + QtCore.QVariant(False)).toBool() + self.OverrideCheckBox.setChecked(self.amend_display) + self.amend_display_start = self.amend_display + + def onOverrideCheckBoxChanged(self, check_state): + self.amend_display = False + # we have a set value convert to True/False + if check_state == QtCore.Qt.Checked: + self.amend_display = True + + def save(self): + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + settings.setValue('x position', + QtCore.QVariant(self.XposEdit.text())) + settings.setValue('y position', + QtCore.QVariant(self.YposEdit.text())) + settings.setValue('height', + QtCore.QVariant(self.HeightEdit.text())) + settings.setValue('width', + QtCore.QVariant(self.WidthEdit.text())) + settings.setValue('amend display', + QtCore.QVariant(self.amend_display)) + self.postSetUp() + + def postSetUp(self): + self.screens.override[u'size'] = QtCore.QRect(int(self.XposEdit.text()),\ + int(self.YposEdit.text()), int(self.WidthEdit.text()),\ + int(self.HeightEdit.text())) + if self.amend_display: + self.screens.set_override_display() + else: + self.screens.reset_current_display() + #only trigger event if data has changed in this edit session + if self.amend_display_start != self.amend_display: + self.amend_display_start = self.amend_display + Receiver.send_message(u'config_screen_changed') diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index ec20650cf..ac4f92336 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -25,7 +25,7 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, str_to_bool, Receiver +from openlp.core.lib import SettingsTab, Receiver class GeneralTab(SettingsTab): """ @@ -41,12 +41,16 @@ class GeneralTab(SettingsTab): values. If not set before default to last screen. """ - self.MonitorNumber = int(self.config.get_config(u'monitor', - self.screens.monitor_number)) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.MonitorNumber = settings.value(u'monitor', + QtCore.QVariant(self.screens.monitor_number)).toInt()[0] self.screens.set_current_display(self.MonitorNumber) self.screens.monitor_number = self.MonitorNumber - self.DisplayOnMonitor = str_to_bool(self.config.get_config(u'display on monitor', u'True')) + self.DisplayOnMonitor = settings.value( + u'display on monitor', QtCore.QVariant(True)).toBool() self.screens.display = self.DisplayOnMonitor + settings.endGroup() def setupUi(self): self.setObjectName(u'GeneralTab') @@ -151,15 +155,18 @@ class GeneralTab(SettingsTab): QtCore.QObject.connect(self.MonitorComboBox, QtCore.SIGNAL(u'activated(int)'), self.onMonitorComboBoxChanged) QtCore.QObject.connect(self.DisplayOnMonitorCheck, - QtCore.SIGNAL(u'stateChanged(int)'), self.onDisplayOnMonitorCheckChanged) + QtCore.SIGNAL(u'stateChanged(int)'), + self.onDisplayOnMonitorCheckChanged) QtCore.QObject.connect(self.WarningCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onWarningCheckBoxChanged) QtCore.QObject.connect(self.AutoOpenCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoOpenCheckBoxChanged) QtCore.QObject.connect(self.ShowSplashCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onShowSplashCheckBoxChanged) + QtCore.SIGNAL(u'stateChanged(int)'), + self.onShowSplashCheckBoxChanged) QtCore.QObject.connect(self.SaveCheckServiceCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onSaveCheckServiceCheckBox) + QtCore.SIGNAL(u'stateChanged(int)'), + self.onSaveCheckServiceCheckBox) QtCore.QObject.connect(self.AutoPreviewCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoPreviewCheckBox) QtCore.QObject.connect(self.NumberEdit, @@ -171,15 +178,20 @@ class GeneralTab(SettingsTab): def retranslateUi(self): self.MonitorGroupBox.setTitle(self.trUtf8('Monitors')) - self.MonitorLabel.setText(self.trUtf8('Select monitor for output display:')) - self.DisplayOnMonitorCheck.setText(self.trUtf8('Display if in single screen')) + self.MonitorLabel.setText( + self.trUtf8('Select monitor for output display:')) + self.DisplayOnMonitorCheck.setText( + self.trUtf8('Display if a single screen')) self.StartupGroupBox.setTitle(self.trUtf8('Application Startup')) self.WarningCheckBox.setText(self.trUtf8('Show blank screen warning')) - self.AutoOpenCheckBox.setText(self.trUtf8('Automatically open the last service')) + self.AutoOpenCheckBox.setText( + self.trUtf8('Automatically open the last service')) self.ShowSplashCheckBox.setText(self.trUtf8('Show the splash screen')) self.SettingsGroupBox.setTitle(self.trUtf8('Application Settings')) - self.SaveCheckServiceCheckBox.setText(self.trUtf8('Prompt to save Service before starting New')) - self.AutoPreviewCheckBox.setText(self.trUtf8('Preview Next Song from Service Manager')) + self.SaveCheckServiceCheckBox.setText( + self.trUtf8('Prompt to save Service before starting New')) + self.AutoPreviewCheckBox.setText( + self.trUtf8('Preview Next Song from Service Manager')) self.CCLIGroupBox.setTitle(self.trUtf8('CCLI Details')) self.NumberLabel.setText(self.trUtf8('CCLI Number:')) self.UsernameLabel.setText(self.trUtf8('SongSelect Username:')) @@ -216,20 +228,32 @@ class GeneralTab(SettingsTab): self.Password = self.PasswordEdit.displayText() def load(self): + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) for screen in self.screens.screen_list: - screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1) + screen_name = u'%s %d' % (self.trUtf8('Screen'), + screen[u'number'] + 1) if screen[u'primary']: screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary')) self.MonitorComboBox.addItem(screen_name) # Get the configs - self.Warning = str_to_bool(self.config.get_config(u'blank warning', u'False')) - self.AutoOpen = str_to_bool(self.config.get_config(u'auto open', u'False')) - self.ShowSplash = str_to_bool(self.config.get_config(u'show splash', u'True')) - self.PromptSaveService = str_to_bool(self.config.get_config(u'save prompt', u'False')) - self.AutoPreview = str_to_bool(self.config.get_config(u'auto preview', u'False')) - self.CCLINumber = unicode(self.config.get_config(u'ccli number', u'')) - self.Username = unicode(self.config.get_config(u'songselect username', u'')) - self.Password = unicode(self.config.get_config(u'songselect password', u'')) + self.Warning = settings.value( + u'blank warning', QtCore.QVariant(False)).toBool() + self.AutoOpen = settings.value( + u'auto open', QtCore.QVariant(False)).toBool() + self.ShowSplash = settings.value( + u'show splash', QtCore.QVariant(True)).toBool() + self.PromptSaveService = settings.value( + u'save prompt', QtCore.QVariant(False)).toBool() + self.AutoPreview = settings.value( + u'auto preview', QtCore.QVariant(False)).toBool() + self.CCLINumber = unicode(settings.value( + u'ccli number', QtCore.QVariant(u'')).toString()) + self.Username = unicode(settings.value( + u'songselect username', QtCore.QVariant(u'')).toString()) + self.Password = unicode(settings.value( + u'songselect password', QtCore.QVariant(u'')).toString()) + settings.endGroup() self.SaveCheckServiceCheckBox.setChecked(self.PromptSaveService) # Set a few things up self.MonitorComboBox.setCurrentIndex(self.MonitorNumber) @@ -243,19 +267,27 @@ class GeneralTab(SettingsTab): self.PasswordEdit.setText(self.Password) def save(self): - self.config.set_config(u'monitor', self.MonitorNumber) - self.config.set_config(u'display on monitor', self.DisplayOnMonitor) - self.config.set_config(u'blank warning', self.Warning) - self.config.set_config(u'auto open', self.AutoOpen) - self.config.set_config(u'show splash', self.ShowSplash) - self.config.set_config(u'save prompt', self.PromptSaveService) - self.config.set_config(u'auto preview', self.AutoPreview) - self.config.set_config(u'ccli number', self.CCLINumber) - self.config.set_config(u'songselect username', self.Username) - self.config.set_config(u'songselect password', self.Password) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + settings.setValue(u'monitor', QtCore.QVariant(self.MonitorNumber)) + settings.setValue(u'display on monitor', + QtCore.QVariant(self.DisplayOnMonitor)) + settings.setValue(u'blank warning', QtCore.QVariant(self.Warning)) + settings.setValue(u'auto open', QtCore.QVariant(self.AutoOpen)) + settings.setValue(u'show splash', QtCore.QVariant(self.ShowSplash)) + settings.setValue(u'save prompt', + QtCore.QVariant(self.PromptSaveService)) + settings.setValue(u'auto preview', QtCore.QVariant(self.AutoPreview)) + settings.setValue(u'ccli number', QtCore.QVariant(self.CCLINumber)) + settings.setValue(u'songselect username', + QtCore.QVariant(self.Username)) + settings.setValue(u'songselect password', + QtCore.QVariant(self.Password)) + settings.endGroup() self.screens.display = self.DisplayOnMonitor #Monitor Number has changed. if self.screens.monitor_number != self.MonitorNumber: self.screens.monitor_number = self.MonitorNumber self.screens.set_current_display(self.MonitorNumber) - Receiver.send_message(u'screen_changed') + Receiver.send_message(u'config_screen_changed') + Receiver.send_message(u'config_updated') diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 15fc29650..af52e5ffd 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -34,12 +34,12 @@ from openlp.core.ui import HideMode log = logging.getLogger(__name__) - class DisplayManager(QtGui.QWidget): """ Wrapper class to hold the display widgets. I will provide API's in future to access the screens allow for extra displays to be added. + RenderManager is poked in by MainWindow """ def __init__(self, screens): QtGui.QWidget.__init__(self) @@ -66,26 +66,27 @@ class DisplayWidget(QtGui.QWidget): def __init__(self, parent=None, name=None): QtGui.QWidget.__init__(self, None) self.parent = parent - self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', - QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', - QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', - QtCore.Qt.Key_0: 'servicemanager_next_item', - QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} + self.hotkey_map = { + QtCore.Qt.Key_Return: 'servicemanager_next_item', + QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop', + QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop', + QtCore.Qt.Key_0: 'servicemanager_next_item', + QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'} def keyPressEvent(self, event): if type(event) == QtGui.QKeyEvent: #here accept the event and do something if event.key() == QtCore.Qt.Key_Up: - Receiver.send_message(u'live_slidecontroller_previous') + Receiver.send_message(u'slidecontroller_live_previous') event.accept() elif event.key() == QtCore.Qt.Key_Down: - Receiver.send_message(u'live_slidecontroller_next') + Receiver.send_message(u'slidecontroller_live_next') event.accept() elif event.key() == QtCore.Qt.Key_PageUp: - Receiver.send_message(u'live_slidecontroller_first') + Receiver.send_message(u'slidecontroller_live_first') event.accept() elif event.key() == QtCore.Qt.Key_PageDown: - Receiver.send_message(u'live_slidecontroller_last') + Receiver.send_message(u'slidecontroller_live_last') event.accept() elif event.key() in self.hotkey_map: Receiver.send_message(self.hotkey_map[event.key()]) @@ -113,7 +114,7 @@ class MainDisplay(DisplayWidget): ``screens`` The list of screens. """ - log.debug(u'Initilisation started') + log.debug(u'Initialisation started') DisplayWidget.__init__(self, parent) self.parent = parent self.setWindowTitle(u'OpenLP Display') @@ -129,31 +130,30 @@ class MainDisplay(DisplayWidget): self.displayBlank = False self.blankFrame = None self.frame = None - self.firstTime = True - self.hasTransition = False - self.mediaBackground = False QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay) + QtCore.SIGNAL(u'videodisplay_start'), self.hideDisplayForVideo) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'live_slide_show'), self.showDisplay) + QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_start'), self.hideDisplay) + QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'videodisplay_background'), self.hideDisplayForVideo) def setup(self): """ Sets up the screen on a particular screen. """ - log.debug(u'Setup %s for %s ' %(self.screens, - self.screens.monitor_number)) + log.debug(u'Setup %s for %s ' % ( + self.screens, self.screens.monitor_number)) self.setVisible(False) self.screen = self.screens.current #Sort out screen locations and sizes - self.setGeometry(self.screen[u'size']) self.display_alert.setGeometry(self.screen[u'size']) - self.display_image.resize(self.screen[u'size'].width(), - self.screen[u'size'].height()) - self.display_text.resize(self.screen[u'size'].width(), - self.screen[u'size'].height()) + self.display_image.resize( + self.screen[u'size'].width(), self.screen[u'size'].height()) + self.display_text.resize( + self.screen[u'size'].width(), self.screen[u'size'].height()) + self.setGeometry(self.screen[u'size']) #Build a custom splash screen self.InitialFrame = QtGui.QImage( self.screen[u'size'].width(), @@ -178,8 +178,8 @@ class MainDisplay(DisplayWidget): painter.begin(self.blankFrame) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) #build a blank transparent image - self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), - self.screen[u'size'].height()) + self.transparent = QtGui.QPixmap( + self.screen[u'size'].width(), self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) self.display_alert.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent) @@ -194,37 +194,69 @@ class MainDisplay(DisplayWidget): def resetDisplay(self): log.debug(u'resetDisplay') - Receiver.send_message(u'stop_display_loop') + Receiver.send_message(u'slidecontroller_live_stop_loop') if self.primary: self.setVisible(False) else: self.showFullScreen() - def hideDisplay(self): - log.debug(u'hideDisplay') - self.display_image.setPixmap(self.transparent) + def hideDisplayForVideo(self): + """ + Hides the main display if for the video to be played + """ + self.hideDisplay(HideMode.Screen) + + def hideDisplay(self, mode=HideMode.Screen): + """ + Hide the display by making all layers transparent + Store the images so they can be replaced when required + """ + log.debug(u'hideDisplay mode = %d', mode) + self.storeImage = QtGui.QPixmap(self.display_image.pixmap()) + self.storeText = QtGui.QPixmap(self.display_text.pixmap()) self.display_alert.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent) + if mode == HideMode.Screen: + self.display_image.setPixmap(self.transparent) + elif mode == HideMode.Blank: + self.display_image.setPixmap( + QtGui.QPixmap.fromImage(self.blankFrame)) + else: + if self.parent.renderManager.renderer.bg_frame: + self.display_image.setPixmap(QtGui.QPixmap.fromImage( + self.parent.renderManager.renderer.bg_frame)) + else: + self.display_image.setPixmap( + QtGui.QPixmap.fromImage(self.blankFrame)) self.moveToTop() def moveToTop(self): log.debug(u'moveToTop') - self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint \ - | QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) + self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | + QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) self.show() def showDisplay(self): + """ + Show the stored layers so the screen reappears as it was + originally. + Make the stored images None to release memory. + """ log.debug(u'showDisplay') - if not self.primary: - self.setVisible(True) - self.showFullScreen() - Receiver.send_message(u'flush_alert') + if self.storeImage: + self.display_image.setPixmap(self.storeImage) + self.display_alert.setPixmap(self.transparent) + if self.storeText: + self.display_text.setPixmap(self.storeText) + self.storeImage = None + self.store = None + self.moveToTop() + Receiver.send_message(u'maindisplay_active') def addImageWithText(self, frame): log.debug(u'addImageWithText') - frame = resize_image(frame, - self.screen[u'size'].width(), - self.screen[u'size'].height() ) + frame = resize_image( + frame, self.screen[u'size'].width(), self.screen[u'size'].height()) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) self.moveToTop() @@ -253,14 +285,17 @@ class MainDisplay(DisplayWidget): if not self.displayBlank: if transition: if self.frame is not None: - self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.frame)) + self.display_text.setPixmap( + QtGui.QPixmap.fromImage(self.frame)) self.repaint() self.frame = None if frame[u'trans'] is not None: - self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) + self.display_text.setPixmap( + QtGui.QPixmap.fromImage(frame[u'trans'])) self.repaint() self.frame = frame[u'trans'] - self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) + self.display_text.setPixmap( + QtGui.QPixmap.fromImage(frame[u'main'])) self.display_frame = frame[u'main'] self.repaint() else: @@ -276,27 +311,6 @@ class MainDisplay(DisplayWidget): self.waitingFrame = frame self.waitingFrameTrans = transition - def blankDisplay(self, blankType=HideMode.Blank, blanked=True): - log.debug(u'Blank main Display %d' % blanked) - if blanked: - self.displayBlank = True - if blankType == HideMode.Blank: - self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) - elif blankType == HideMode.Theme: - theme = self.parent.RenderManager.renderer.bg_frame - if not theme: - theme = self.blankFrame - self.display_text.setPixmap(QtGui.QPixmap.fromImage(theme)) - self.waitingFrame = None - self.waitingFrameTrans = False - else: - self.displayBlank = False - if self.waitingFrame: - self.frameView(self.waitingFrame, self.waitingFrameTrans) - elif self.display_frame: - self.frameView(self.display_frame) - - class VideoDisplay(Phonon.VideoWidget): """ This is the form that is used to display videos on the projector. @@ -314,26 +328,39 @@ class VideoDisplay(Phonon.VideoWidget): ``screens`` The list of screens. """ - log.debug(u'VideoDisplay Initilisation started') + log.debug(u'VideoDisplay Initialisation started') Phonon.VideoWidget.__init__(self) self.setWindowTitle(u'OpenLP Video Display') self.parent = parent self.screens = screens + self.hidden = False + self.message = None self.mediaObject = Phonon.MediaObject() self.setAspectRatio(aspect) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) Phonon.createPath(self.mediaObject, self) Phonon.createPath(self.mediaObject, self.audioObject) + self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint | + QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_start'), self.onMediaQueue) + QtCore.SIGNAL(u'maindisplay_hide'), self.mediaHide) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_play'), self.onMediaPlay) + QtCore.SIGNAL(u'maindisplay_show'), self.mediaShow) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_pause'), self.onMediaPause) + QtCore.SIGNAL(u'videodisplay_start'), self.onMediaQueue) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_stop'), self.onMediaStop) + QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_config'), self.setup) + QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'videodisplay_stop'), self.onMediaStop) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'config_updated'), self.setup) + QtCore.QObject.connect(self.mediaObject, + QtCore.SIGNAL(u'finished()'), self.onMediaBackground) + self.setVisible(False) def keyPressEvent(self, event): if type(event) == QtGui.QKeyEvent: @@ -349,43 +376,101 @@ class VideoDisplay(Phonon.VideoWidget): """ Sets up the screen on a particular screen. """ - log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens, - self.screens.monitor_number)) - self.setVisible(False) + log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens, + self.screens.monitor_number)) self.screen = self.screens.current #Sort out screen locations and sizes self.setGeometry(self.screen[u'size']) # To display or not to display? - if not self.screen[u'primary']: + if not self.screen[u'primary'] and self.isVisible(): self.showFullScreen() self.primary = False else: self.setVisible(False) self.primary = True - def onMediaQueue(self, message): + def onMediaBackground(self, message=None): + """ + Play a video triggered from the video plugin with the + file name passed in on the event. + Also triggered from the Finish event so the video will loop + if it is triggered from the plugin + """ log.debug(u'VideoDisplay Queue new media message %s' % message) - file = os.path.join(message[1], message[2]) - source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) - self.onMediaPlay() + #If not file take the stored one + if not message: + message = self.message + # still no file name then stop as it was a normal video stopping + if message: + self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) + self.message = message + self._play() + + def onMediaQueue(self, message): + """ + Set up a video to play from the serviceitem. + """ + log.debug(u'VideoDisplay Queue new media message %s' % message) + file = os.path.join(message[0].get_frame_path(), + message[0].get_frame_title()) + self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + self._play() def onMediaPlay(self): - log.debug(u'VideoDisplay Play the new media, Live ') + """ + Respond to the Play button on the slide controller unless the display + has been hidden by the slidecontroller + """ + if not self.hidden: + log.debug(u'VideoDisplay Play the new media, Live ') + self._play() + + def _play(self): + """ + We want to play the video so start it and display the screen + """ + log.debug(u'VideoDisplay _play called') self.mediaObject.play() self.setVisible(True) self.showFullScreen() def onMediaPause(self): + """ + Pause the video and refresh the screen + """ log.debug(u'VideoDisplay Media paused by user') self.mediaObject.pause() self.show() def onMediaStop(self): + """ + Stop the video and clean up + """ log.debug(u'VideoDisplay Media stopped by user') + self.message = None self.mediaObject.stop() self.onMediaFinish() def onMediaFinish(self): + """ + Clean up the Object queue + """ log.debug(u'VideoDisplay Reached end of media playlist') self.mediaObject.clearQueue() self.setVisible(False) + + def mediaHide(self): + """ + Hide the video display + """ + self.mediaObject.pause() + self.hidden = True + self.setVisible(False) + + def mediaShow(self): + """ + Show the video disaply if it was already hidden + """ + if self.hidden: + self.hidden = False + self._play() diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index e0e8465f5..df275dd20 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -28,12 +28,11 @@ import time from PyQt4 import QtCore, QtGui -from openlp.core.ui import AboutForm, SettingsForm, \ - ServiceManager, ThemeManager, SlideController, \ - PluginForm, MediaDockManager, DisplayManager -from openlp.core.lib import RenderManager, PluginConfig, build_icon, \ - OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool -from openlp.core.utils import check_latest_version, AppLocation +from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ + ThemeManager, SlideController, PluginForm, MediaDockManager, DisplayManager +from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \ + SettingsManager, PluginManager, Receiver +from openlp.core.utils import check_latest_version, AppLocation, add_actions log = logging.getLogger(__name__) @@ -57,22 +56,21 @@ class VersionThread(QtCore.QThread): A special Qt thread class to fetch the version of OpenLP from the website. This is threaded so that it doesn't affect the loading time of OpenLP. """ - def __init__(self, parent, app_version, generalConfig): + def __init__(self, parent, app_version): QtCore.QThread.__init__(self, parent) self.parent = parent self.app_version = app_version - self.generalConfig = generalConfig def run(self): """ Run the thread. """ time.sleep(1) - Receiver.send_message(u'blank_check') - version = check_latest_version(self.generalConfig, self.app_version) + Receiver.send_message(u'maindisplay_blank_check') + version = check_latest_version(self.app_version) #new version has arrived if version != self.app_version[u'full']: - Receiver.send_message(u'version_check', u'%s' % version) + Receiver.send_message(u'openlp_version_check', u'%s' % version) class Ui_MainWindow(object): def setupUi(self, MainWindow): @@ -163,7 +161,6 @@ class Ui_MainWindow(object): self.MediaManagerDock.setWidget(self.MediaManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock) - self.MediaManagerDock.setVisible(self.settingsmanager.showMediaManager) # Create the service manager self.ServiceManagerDock = OpenLPDockWidget(MainWindow) ServiceManagerIcon = build_icon(u':/system/system_servicemanager.png') @@ -175,18 +172,17 @@ class Ui_MainWindow(object): self.ServiceManagerDock.setWidget(self.ServiceManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock) - self.ServiceManagerDock.setVisible( - self.settingsmanager.showServiceManager) # Create the theme manager self.ThemeManagerDock = OpenLPDockWidget(MainWindow) ThemeManagerIcon = build_icon(u':/system/system_thememanager.png') self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon) self.ThemeManagerDock.setObjectName(u'ThemeManagerDock') + self.ThemeManagerDock.setMinimumWidth( + self.settingsmanager.mainwindow_right) self.ThemeManagerContents = ThemeManager(self) self.ThemeManagerDock.setWidget(self.ThemeManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock) - self.ThemeManagerDock.setVisible(self.settingsmanager.showThemeManager) # Create the menu items self.FileNewItem = QtGui.QAction(MainWindow) self.FileNewItem.setIcon( @@ -225,20 +221,18 @@ class Ui_MainWindow(object): self.OptionsSettingsItem.setObjectName(u'OptionsSettingsItem') self.ViewMediaManagerItem = QtGui.QAction(MainWindow) self.ViewMediaManagerItem.setCheckable(True) - self.ViewMediaManagerItem.setChecked( - self.settingsmanager.showMediaManager) + self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible()) self.ViewMediaManagerItem.setIcon(MediaManagerIcon) self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.ViewThemeManagerItem = QtGui.QAction(MainWindow) self.ViewThemeManagerItem.setCheckable(True) - self.ViewThemeManagerItem.setChecked( - self.settingsmanager.showThemeManager) + self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible()) self.ViewThemeManagerItem.setIcon(ThemeManagerIcon) self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem') self.ViewServiceManagerItem = QtGui.QAction(MainWindow) self.ViewServiceManagerItem.setCheckable(True) self.ViewServiceManagerItem.setChecked( - self.settingsmanager.showServiceManager) + self.ServiceManagerDock.isVisible()) self.ViewServiceManagerItem.setIcon(ServiceManagerIcon) self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem') self.PluginItem = QtGui.QAction(MainWindow) @@ -248,12 +242,14 @@ class Ui_MainWindow(object): ContentsIcon = build_icon(u':/system/system_help_contents.png') self.HelpDocumentationItem.setIcon(ContentsIcon) self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem') + self.HelpDocumentationItem.setEnabled(False) self.HelpAboutItem = QtGui.QAction(MainWindow) AboutIcon = build_icon(u':/system/system_about.png') self.HelpAboutItem.setIcon(AboutIcon) self.HelpAboutItem.setObjectName(u'HelpAboutItem') self.HelpOnlineHelpItem = QtGui.QAction(MainWindow) self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem') + self.HelpOnlineHelpItem.setEnabled(False) self.HelpWebSiteItem = QtGui.QAction(MainWindow) self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem') self.LanguageTranslateItem = QtGui.QAction(MainWindow) @@ -273,50 +269,36 @@ class Ui_MainWindow(object): self.settingsmanager.showPreviewPanel) self.ModeLiveItem = QtGui.QAction(MainWindow) self.ModeLiveItem.setObjectName(u'ModeLiveItem') - self.FileImportMenu.addAction(self.ImportThemeItem) - self.FileImportMenu.addAction(self.ImportLanguageItem) - self.FileExportMenu.addAction(self.ExportThemeItem) - self.FileExportMenu.addAction(self.ExportLanguageItem) - self.FileMenu.addAction(self.FileNewItem) - self.FileMenu.addAction(self.FileOpenItem) - self.FileMenu.addAction(self.FileSaveItem) - self.FileMenu.addAction(self.FileSaveAsItem) - self.FileMenu.addSeparator() - self.FileMenu.addAction(self.FileImportMenu.menuAction()) - self.FileMenu.addAction(self.FileExportMenu.menuAction()) - self.FileMenu.addSeparator() - self.FileMenu.addAction(self.FileExitItem) - self.ViewModeMenu.addAction(self.ModeLiveItem) - self.OptionsViewMenu.addAction(self.ViewModeMenu.menuAction()) - self.OptionsViewMenu.addSeparator() - self.OptionsViewMenu.addAction(self.ViewMediaManagerItem) - self.OptionsViewMenu.addAction(self.ViewServiceManagerItem) - self.OptionsViewMenu.addAction(self.ViewThemeManagerItem) - self.OptionsViewMenu.addSeparator() - self.OptionsViewMenu.addAction(self.action_Preview_Panel) - self.OptionsLanguageMenu.addAction(self.LanguageEnglishItem) - self.OptionsLanguageMenu.addSeparator() - self.OptionsLanguageMenu.addAction(self.LanguageTranslateItem) - self.OptionsMenu.addAction(self.OptionsLanguageMenu.menuAction()) - self.OptionsMenu.addAction(self.OptionsViewMenu.menuAction()) - self.OptionsMenu.addSeparator() - self.OptionsMenu.addAction(self.OptionsSettingsItem) - self.ToolsMenu.addAction(self.PluginItem) - self.ToolsMenu.addSeparator() - self.ToolsMenu.addAction(self.ToolsAddToolItem) - self.HelpMenu.addAction(self.HelpDocumentationItem) - self.HelpMenu.addAction(self.HelpOnlineHelpItem) - self.HelpMenu.addSeparator() - self.HelpMenu.addAction(self.HelpWebSiteItem) - self.HelpMenu.addAction(self.HelpAboutItem) - self.MenuBar.addAction(self.FileMenu.menuAction()) - self.MenuBar.addAction(self.OptionsMenu.menuAction()) - self.MenuBar.addAction(self.ToolsMenu.menuAction()) - self.MenuBar.addAction(self.HelpMenu.menuAction()) + add_actions(self.FileImportMenu, + (self.ImportThemeItem, self.ImportLanguageItem)) + add_actions(self.FileExportMenu, + (self.ExportThemeItem, self.ExportLanguageItem)) + self.FileMenuActions = (self.FileNewItem, self.FileOpenItem, + self.FileSaveItem, self.FileSaveAsItem, None, + self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(), + self.FileExitItem) + add_actions(self.ViewModeMenu, [self.ModeLiveItem]) + add_actions(self.OptionsViewMenu, (self.ViewModeMenu.menuAction(), + None, self.ViewMediaManagerItem, self.ViewServiceManagerItem, + self.ViewThemeManagerItem, None, self.action_Preview_Panel)) + add_actions(self.OptionsLanguageMenu, (self.LanguageEnglishItem, None, + self.LanguageTranslateItem)) + add_actions(self.OptionsMenu, (self.OptionsLanguageMenu.menuAction(), + self.OptionsViewMenu.menuAction(), None, self.OptionsSettingsItem)) + add_actions(self.ToolsMenu, + (self.PluginItem, None, self.ToolsAddToolItem)) + add_actions(self.HelpMenu, + (self.HelpDocumentationItem, self.HelpOnlineHelpItem, None, + self.HelpWebSiteItem, self.HelpAboutItem)) + add_actions(self.MenuBar, + (self.FileMenu.menuAction(), self.OptionsMenu.menuAction(), + self.ToolsMenu.menuAction(), self.HelpMenu.menuAction())) # Initialise the translation self.retranslateUi(MainWindow) self.MediaToolBox.setCurrentIndex(0) # Connect up some signals and slots + QtCore.QObject.connect(self.FileMenu, + QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu) QtCore.QObject.connect(self.FileExitItem, QtCore.SIGNAL(u'triggered()'), MainWindow.close) QtCore.QObject.connect(self.ControlSplitter, @@ -382,12 +364,14 @@ class Ui_MainWindow(object): self.actionLook_Feel.setText(self.trUtf8('Look && &Feel')) self.OptionsSettingsItem.setText(self.trUtf8('&Settings')) self.ViewMediaManagerItem.setText(self.trUtf8('&Media Manager')) - self.ViewMediaManagerItem.setToolTip(self.trUtf8('Toggle Media Manager')) + self.ViewMediaManagerItem.setToolTip( + self.trUtf8('Toggle Media Manager')) self.ViewMediaManagerItem.setStatusTip( self.trUtf8('Toggle the visibility of the Media Manager')) self.ViewMediaManagerItem.setShortcut(self.trUtf8('F8')) self.ViewThemeManagerItem.setText(self.trUtf8('&Theme Manager')) - self.ViewThemeManagerItem.setToolTip(self.trUtf8('Toggle Theme Manager')) + self.ViewThemeManagerItem.setToolTip( + self.trUtf8('Toggle Theme Manager')) self.ViewThemeManagerItem.setStatusTip( self.trUtf8('Toggle the visibility of the Theme Manager')) self.ViewThemeManagerItem.setShortcut(self.trUtf8('F10')) @@ -398,7 +382,8 @@ class Ui_MainWindow(object): self.trUtf8('Toggle the visibility of the Service Manager')) self.ViewServiceManagerItem.setShortcut(self.trUtf8('F9')) self.action_Preview_Panel.setText(self.trUtf8('&Preview Panel')) - self.action_Preview_Panel.setToolTip(self.trUtf8('Toggle Preview Panel')) + self.action_Preview_Panel.setToolTip( + self.trUtf8('Toggle Preview Panel')) self.action_Preview_Panel.setStatusTip( self.trUtf8('Toggle the visibility of the Preview Panel')) self.action_Preview_Panel.setShortcut(self.trUtf8('F11')) @@ -439,18 +424,28 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMainWindow.__init__(self) self.screens = screens self.applicationVersion = applicationVersion + # Set up settings sections for the main application + # (not for use by plugins) + self.uiSettingsSection = u'user interface' + self.generalSettingsSection = u'general' + self.serviceSettingsSection = u'servicemanager' + self.songsSettingsSection = u'songs' self.serviceNotSaved = False self.settingsmanager = SettingsManager(screens) - self.generalConfig = PluginConfig(u'General') self.displayManager = DisplayManager(screens) self.aboutForm = AboutForm(self, applicationVersion) self.settingsForm = SettingsForm(self.screens, self, self) + self.recentFiles = [] # Set up the path with plugins pluginpath = AppLocation.get_directory(AppLocation.PluginsDir) self.plugin_manager = PluginManager(pluginpath) self.plugin_helpers = {} # Set up the interface self.setupUi(self) + # Load settings after setupUi so default UI sizes are overwritten + self.loadSettings() + # Once settings are loaded update FileMenu with recentFiles + self.updateFileMenu() self.pluginForm = PluginForm(self) # Set up signals and slots QtCore.QObject.connect(self.ImportThemeItem, @@ -483,6 +478,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(self.PreviewController.Panel, QtCore.SIGNAL(u'visibilityChanged(bool)'), self.action_Preview_Panel.setChecked) + QtCore.QObject.connect(self.HelpWebSiteItem, + QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked) QtCore.QObject.connect(self.HelpAboutItem, QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked) QtCore.QObject.connect(self.PluginItem, @@ -490,15 +487,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(self.OptionsSettingsItem, QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged) + QtCore.SIGNAL(u'theme_update_global'), self.defaultThemeChanged) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'version_check'), self.versionCheck) + QtCore.SIGNAL(u'openlp_version_check'), self.versionCheck) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'blank_check'), self.blankCheck) + QtCore.SIGNAL(u'maindisplay_blank_check'), self.blankCheck) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'screen_changed'), self.screenChanged) + QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'status_message'), self.showStatusMessage) + QtCore.SIGNAL(u'maindisplay_status_text'), self.showStatusMessage) QtCore.QObject.connect(self.FileNewItem, QtCore.SIGNAL(u'triggered()'), self.ServiceManagerContents.onNewService) @@ -514,8 +511,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): #warning cyclic dependency #RenderManager needs to call ThemeManager and #ThemeManager needs to call RenderManager - self.RenderManager = RenderManager(self.ThemeManagerContents, - self.screens) + self.RenderManager = RenderManager( + self.ThemeManagerContents, self.screens) + self.displayManager.renderManager = self.RenderManager #Define the media Dock Manager self.mediaDockManager = MediaDockManager(self.MediaToolBox) log.info(u'Load Plugins') @@ -524,7 +522,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.plugin_helpers[u'live'] = self.LiveController self.plugin_helpers[u'render'] = self.RenderManager self.plugin_helpers[u'service'] = self.ServiceManagerContents - self.plugin_helpers[u'settings'] = self.settingsForm + self.plugin_helpers[u'settings form'] = self.settingsForm self.plugin_helpers[u'toolbox'] = self.mediaDockManager self.plugin_helpers[u'maindisplay'] = self.displayManager.mainDisplay self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers) @@ -571,13 +569,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Show the main form, as well as the display form """ - self.showMaximized() + QtGui.QWidget.show(self) #screen_number = self.getMonitorNumber() self.displayManager.setup() if self.displayManager.mainDisplay.isVisible(): self.displayManager.mainDisplay.setFocus() self.activateWindow() - if str_to_bool(self.generalConfig.get_config(u'auto open', False)): + if QtCore.QSettings().value( + self.generalSettingsSection + u'/auto open', + QtCore.QVariant(False)).toBool(): self.ServiceManagerContents.onLoadService(True) def blankCheck(self): @@ -585,22 +585,32 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Check and display message if screen blank on setup. Triggered by delay thread. """ - if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ - and str_to_bool(self.generalConfig.get_config(u'blank warning', False)): + settings = QtCore.QSettings() + settings.beginGroup(self.generalSettingsSection) + if settings.value(u'screen blank', QtCore.QVariant(False)).toBool() \ + and settings.value(u'blank warning', QtCore.QVariant(False)).toBool(): self.LiveController.onBlankDisplay(True) QtGui.QMessageBox.question(self, self.trUtf8('OpenLP Main Display Blanked'), self.trUtf8('The Main Display has been blanked out'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) + settings.endGroup() def versionThread(self): """ Start an initial setup thread to delay notifications """ - vT = VersionThread(self, self.applicationVersion, self.generalConfig) + vT = VersionThread(self, self.applicationVersion) vT.start() + def onHelpWebSiteClicked(self): + """ + Load the OpenLP website + """ + import webbrowser + webbrowser.open_new(u'http://openlp.org/') + def onHelpAboutItemClicked(self): """ Show the About form @@ -638,7 +648,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if self.serviceNotSaved: ret = QtGui.QMessageBox.question(self, self.trUtf8('Save Changes to Service?'), - self.trUtf8('Your service has changed, do you want to save those changes?'), + self.trUtf8('Your service has changed. ' + 'Do you want to save those changes?'), QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Discard | @@ -666,12 +677,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Call the cleanup method to shutdown plugins. log.info(u'cleanup plugins') self.plugin_manager.finalise_plugins() + # Save settings + self.saveSettings() #Close down the displays self.displayManager.close() def serviceChanged(self, reset=False, serviceName=None): """ - Hook to change the main window title when the service chmainwindow.pyanges + Hook to change the main window title when the service changes ``reset`` Shows if the service has been cleared or saved @@ -701,22 +714,75 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def toggleMediaManager(self, visible): if self.MediaManagerDock.isVisible() != visible: self.MediaManagerDock.setVisible(visible) - self.settingsmanager.setUIItemVisibility( - self.MediaManagerDock.objectName(), visible) def toggleServiceManager(self, visible): if self.ServiceManagerDock.isVisible() != visible: self.ServiceManagerDock.setVisible(visible) - self.settingsmanager.setUIItemVisibility( - self.ServiceManagerDock.objectName(), visible) def toggleThemeManager(self, visible): if self.ThemeManagerDock.isVisible() != visible: self.ThemeManagerDock.setVisible(visible) - self.settingsmanager.setUIItemVisibility( - self.ThemeManagerDock.objectName(), visible) def togglePreviewPanel(self): previewBool = self.PreviewController.Panel.isVisible() self.PreviewController.Panel.setVisible(not previewBool) self.settingsmanager.togglePreviewPanel(not previewBool) + + def loadSettings(self): + log.debug(u'Loading QSettings') + settings = QtCore.QSettings() + settings.beginGroup(self.generalSettingsSection) + self.recentFiles = settings.value(u'recent files').toStringList() + settings.endGroup() + settings.beginGroup(self.uiSettingsSection) + self.move(settings.value(u'main window position', + QtCore.QVariant(QtCore.QPoint(0, 0))).toPoint()) + self.restoreGeometry( + settings.value(u'main window geometry').toByteArray()) + self.restoreState(settings.value(u'main window state').toByteArray()) + settings.endGroup() + + def saveSettings(self): + log.debug(u'Saving QSettings') + settings = QtCore.QSettings() + settings.beginGroup(self.generalSettingsSection) + recentFiles = QtCore.QVariant(self.recentFiles) \ + if self.recentFiles else QtCore.QVariant() + settings.setValue(u'recent files', recentFiles) + settings.endGroup() + settings.beginGroup(self.uiSettingsSection) + settings.setValue(u'main window position', + QtCore.QVariant(self.pos())) + settings.setValue(u'main window state', + QtCore.QVariant(self.saveState())) + settings.setValue(u'main window geometry', + QtCore.QVariant(self.saveGeometry())) + settings.endGroup() + + def updateFileMenu(self): + self.FileMenu.clear() + add_actions(self.FileMenu, self.FileMenuActions[:-1]) + existingRecentFiles = [] + for file in self.recentFiles: + if QtCore.QFile.exists(file): + existingRecentFiles.append(file) + if existingRecentFiles: + self.FileMenu.addSeparator() + for fileId, filename in enumerate(existingRecentFiles): + action = QtGui.QAction(u'&%d %s' % (fileId +1, + QtCore.QFileInfo(filename).fileName()), self) + action.setData(QtCore.QVariant(filename)) + self.connect(action, QtCore.SIGNAL(u'triggered()'), + self.ServiceManagerContents.loadService) + self.FileMenu.addAction(action) + self.FileMenu.addSeparator() + self.FileMenu.addAction(self.FileMenuActions[-1]) + + def addRecentFile(self, filename): + recentFileCount = QtCore.QSettings().value( + self.generalSettingsSection + u'/max recent files', + QtCore.QVariant(4)).toInt()[0] + if filename and not self.recentFiles.contains(filename): + self.recentFiles.prepend(QtCore.QString(filename)) + while self.recentFiles.count() > recentFileCount: + self.recentFiles.takeLast() diff --git a/openlp/core/ui/mediadockmanager.py b/openlp/core/ui/mediadockmanager.py index 574b181da..782383cd4 100644 --- a/openlp/core/ui/mediadockmanager.py +++ b/openlp/core/ui/mediadockmanager.py @@ -45,17 +45,17 @@ class MediaDockManager(object): log.debug(u'Inserting %s dock' % media_item.title) match = False for dock_index in range(0, self.media_dock.count()): - if self.media_dock.widget(dock_index).ConfigSection == media_item.title.lower(): + if self.media_dock.widget(dock_index).settingsSection == \ + media_item.title.lower(): match = True break if not match: self.media_dock.addItem(media_item, icon, media_item.title) - def remove_dock(self, name): log.debug(u'remove %s dock' % name) for dock_index in range(0, self.media_dock.count()): if self.media_dock.widget(dock_index): - if self.media_dock.widget(dock_index).ConfigSection == name: + if self.media_dock.widget(dock_index).settingsSection == name: self.media_dock.widget(dock_index).hide() self.media_dock.removeItem(dock_index) diff --git a/openlp/core/ui/screen.py b/openlp/core/ui/screen.py index 32cc5ba50..19c4e01b5 100644 --- a/openlp/core/ui/screen.py +++ b/openlp/core/ui/screen.py @@ -24,6 +24,7 @@ ############################################################################### import logging +import copy log = logging.getLogger(__name__) @@ -36,6 +37,7 @@ class ScreenList(object): def __init__(self): self.preview = None self.current = None + self.override = None self.screen_list = [] self.display_count = 0 #actual display number @@ -59,12 +61,31 @@ class ScreenList(object): """ Set up the current screen dimensions """ + log.debug(u'set_override_display %s', number, ) if number + 1 > self.display_count: self.current = self.screen_list[0] self.current_display = 0 else: self.current = self.screen_list[number] - self.preview = self.current + self.override = copy.deepcopy(self.current) + self.preview = copy.deepcopy(self.current) self.current_display = number if self.display_count == 1: self.preview = self.screen_list[0] + + def set_override_display(self): + """ + replace the current size with the override values + user wants to have their own screen attributes + """ + log.debug(u'set_override_display') + self.current = copy.deepcopy(self.override) + self.preview = copy.deepcopy(self.current) + + def reset_current_display(self): + """ + replace the current values with the correct values + user wants to use the correct screen attributes + """ + log.debug(u'reset_current_display') + self.set_current_display(self.current_display) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 27ca95d0e..03cdbcecc 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -32,14 +32,15 @@ log = logging.getLogger(__name__) from PyQt4 import QtCore, QtGui -from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \ - contextMenuAction, Receiver, str_to_bool, build_icon, ItemCapabilities +from openlp.core.lib import OpenLPToolbar, ServiceItem, contextMenuAction, \ + Receiver, build_icon, ItemCapabilities, SettingsManager from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm +from openlp.core.utils import AppLocation class ServiceManagerList(QtGui.QTreeWidget): def __init__(self, parent=None, name=None): - QtGui.QTreeWidget.__init__(self,parent) + QtGui.QTreeWidget.__init__(self, parent) self.parent = parent def keyPressEvent(self, event): @@ -83,7 +84,7 @@ class ServiceManagerList(QtGui.QTreeWidget): mimeData = QtCore.QMimeData() drag.setMimeData(mimeData) mimeData.setText(u'ServiceManager') - dropAction = drag.start(QtCore.Qt.CopyAction) + drag.start(QtCore.Qt.CopyAction) class ServiceManager(QtGui.QWidget): """ @@ -103,9 +104,6 @@ class ServiceManager(QtGui.QWidget): self.droppos = 0 #is a new service and has not been saved self.isNew = True - #Indicates if remoteTriggering is active. If it is the next addServiceItem call - #will replace the currently selected one. - self.remoteEditTriggered = False self.serviceNoteForm = ServiceNoteForm() self.serviceItemEditForm = ServiceItemEditForm() #start with the layout @@ -186,29 +184,38 @@ class ServiceManager(QtGui.QWidget): QtCore.QObject.connect(self.ServiceManagerList, QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_themes'), self.updateThemeList) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'presentation types'), self.onPresentationTypes) + QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) + 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'servicemanager_list_request'), self.listRequest) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems) # Last little bits of setting up - self.config = PluginConfig(u'ServiceManager') - self.servicePath = self.config.get_data_path() - self.service_theme = unicode( - self.config.get_config(u'service theme', u'')) + self.service_theme = unicode(QtCore.QSettings().value( + self.parent.serviceSettingsSection + u'/service theme', + QtCore.QVariant(u'')).toString()) + self.servicePath = AppLocation.get_section_data_path(u'servicemanager') + #build the drag and drop context menu + self.dndMenu = QtGui.QMenu() + self.newAction = self.dndMenu.addAction(self.trUtf8('&Add New Item')) + self.newAction.setIcon(build_icon(u':/general/general_edit.png')) + self.addToAction = self.dndMenu.addAction(self.trUtf8('&Add to Selected Item')) + self.addToAction.setIcon(build_icon(u':/general/general_edit.png')) #build the context menu self.menu = QtGui.QMenu() self.editAction = self.menu.addAction(self.trUtf8('&Edit Item')) self.editAction.setIcon(build_icon(u':/general/general_edit.png')) self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item')) - self.editAction.setIcon(build_icon(u':/general/general_edit.png')) + self.maintainAction.setIcon(build_icon(u':/general/general_edit.png')) self.notesAction = self.menu.addAction(self.trUtf8('&Notes')) self.notesAction.setIcon(build_icon(u':/services/service_notes.png')) - self.deleteAction = self.menu.addAction(self.trUtf8('&Delete From Service')) + self.deleteAction = self.menu.addAction( + self.trUtf8('&Delete From Service')) self.deleteAction.setIcon(build_icon(u':/general/general_delete.png')) self.sep1 = self.menu.addAction(u'') self.sep1.setSeparator(True) @@ -257,9 +264,6 @@ class ServiceManager(QtGui.QWidget): if action == self.liveAction: self.makeLive() - def onPresentationTypes(self, presentation_types): - self.presentation_types = presentation_types - def onServiceItemNoteForm(self): item, count = self.findServiceItem() self.serviceNoteForm.textEdit.setPlainText( @@ -297,6 +301,41 @@ class ServiceManager(QtGui.QWidget): lookFor = 1 serviceIterator += 1 + def previousItem(self): + """ + Called by the SlideController to select the + previous service item + """ + if len(self.ServiceManagerList.selectedItems()) == 0: + return + selected = self.ServiceManagerList.selectedItems()[0] + prevItem = None + serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList) + while serviceIterator.value(): + if serviceIterator.value() == selected: + if prevItem: + self.ServiceManagerList.setCurrentItem(prevItem) + self.makeLive() + return + if serviceIterator.value().parent() is None: + prevItem = serviceIterator.value() + serviceIterator += 1 + + def onSetItem(self, message): + """ + Called by a signal to select a specific item + """ + self.setItem(int(message[0])) + + def setItem(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() + def onMoveSelectionUp(self): """ Moves the selection up the window @@ -411,13 +450,13 @@ class ServiceManager(QtGui.QWidget): """ Clear the list to create a new service """ - if self.parent.serviceNotSaved and \ - str_to_bool(PluginConfig(u'General'). - get_config(u'save prompt', u'False')): + if self.parent.serviceNotSaved and QtCore.QSettings().value( + self.parent.generalSettingsSection + u'/save prompt', + QtCore.QVariant(False)).toBool(): ret = QtGui.QMessageBox.question(self, self.trUtf8('Save Changes to Service?'), - self.trUtf8('Your service is unsaved, do you want to save those ' - 'changes before creating a new one ?'), + self.trUtf8('Your service is unsaved, do you want to save ' + 'those changes before creating a new one?'), QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Save), @@ -496,17 +535,21 @@ class ServiceManager(QtGui.QWidget): log.debug(u'onSaveService') if not quick or self.isNew: filename = QtGui.QFileDialog.getSaveFileName(self, - self.trUtf8(u'Save Service'), self.config.get_last_dir(), + self.trUtf8(u'Save Service'), + SettingsManager.get_last_dir(self.parent.serviceSettingsSection), self.trUtf8(u'OpenLP Service Files (*.osz)')) else: - filename = self.config.get_last_dir() + filename = SettingsManager.get_last_dir( + self.parent.serviceSettingsSection) if filename: splittedFile = filename.split(u'.') if splittedFile[-1] != u'osz': filename = filename + u'.osz' filename = unicode(filename) self.isNew = False - self.config.set_last_dir(filename) + SettingsManager.set_last_dir( + self.parent.serviceSettingsSection, + os.path.split(filename)[0]) service = [] servicefile = filename + u'.osd' zip = None @@ -514,7 +557,8 @@ class ServiceManager(QtGui.QWidget): try: zip = zipfile.ZipFile(unicode(filename), 'w') for item in self.serviceItems: - service.append({u'serviceitem':item[u'service_item'].get_service_repr()}) + service.append({u'serviceitem':item[u'service_item'] + .get_service_repr()}) if item[u'service_item'].uses_file(): for frame in item[u'service_item'].get_frames(): path_from = unicode(os.path.join( @@ -538,27 +582,52 @@ class ServiceManager(QtGui.QWidget): pass #if not present do not worry name = filename.split(os.path.sep) self.serviceName = name[-1] + self.parent.addRecentFile(filename) self.parent.serviceChanged(True, self.serviceName) def onQuickSaveService(self): self.onSaveService(True) def onLoadService(self, lastService=False): + if lastService: + filename = SettingsManager.get_last_dir( + self.parent.serviceSettingsSection) + else: + filename = QtGui.QFileDialog.getOpenFileName( + self, self.trUtf8('Open Service'), + SettingsManager.get_last_dir( + self.parent.serviceSettingsSection), u'Services (*.osz)') + self.loadService(filename) + + def loadService(self, filename=None): """ Load an existing service from disk and rebuild the serviceitems. All files retrieved from the zip file are placed in a temporary directory and will only be used for this service. """ - if lastService: - filename = self.config.get_last_dir() - else: - filename = QtGui.QFileDialog.getOpenFileName( - self, self.trUtf8('Open Service'), - self.config.get_last_dir(), u'Services (*.osz)') + if self.parent.serviceNotSaved: + ret = QtGui.QMessageBox.question(self, + self.trUtf8('Save Changes to Service?'), + self.trUtf8('Your current service is unsaved, do you want to ' + 'save the changes before opening a new one?'), + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Discard | + QtGui.QMessageBox.Save), + QtGui.QMessageBox.Save) + if ret == QtGui.QMessageBox.Save: + self.onSaveService() + if filename is None: + action = self.sender() + if isinstance(action, QtGui.QAction): + filename = action.data().toString() + else: + return filename = unicode(filename) name = filename.split(os.path.sep) if filename: - self.config.set_last_dir(filename) + SettingsManager.set_last_dir( + self.parent.serviceSettingsSection, + os.path.split(filename)[0]) zip = None f = None try: @@ -598,6 +667,7 @@ class ServiceManager(QtGui.QWidget): zip.close() self.isNew = False self.serviceName = name[len(name) - 1] + self.parent.addRecentFile(filename) self.parent.serviceChanged(True, self.serviceName) def validateItem(self, serviceItem): @@ -626,7 +696,9 @@ class ServiceManager(QtGui.QWidget): """ self.service_theme = unicode(self.ThemeComboBox.currentText()) self.parent.RenderManager.set_service_theme(self.service_theme) - self.config.set_config(u'service theme', self.service_theme) + QtCore.QSettings().setValue( + self.parent.serviceSettingsSection + u'/service theme', + QtCore.QVariant(self.service_theme)) self.regenerateServiceItems() def regenerateServiceItems(self): @@ -638,12 +710,13 @@ class ServiceManager(QtGui.QWidget): self.serviceItems = [] self.isNew = True for item in tempServiceItems: - self.addServiceItem(item[u'service_item'], False, item[u'expanded']) + self.addServiceItem( + item[u'service_item'], False, item[u'expanded']) #Set to False as items may have changed rendering #does not impact the saved song so True may also be valid self.parent.serviceChanged(False, self.serviceName) - def addServiceItem(self, item, rebuild=False, expand=True): + def addServiceItem(self, item, rebuild=False, expand=True, replace=False): """ Add a Service item to the list @@ -653,10 +726,9 @@ class ServiceManager(QtGui.QWidget): """ sitem, count = self.findServiceItem() item.render() - if self.remoteEditTriggered: + if replace: item.merge(self.serviceItems[sitem][u'service_item']) self.serviceItems[sitem][u'service_item'] = item - self.remoteEditTriggered = False self.repaintServiceList(sitem + 1, 0) self.parent.LiveController.replaceServiceManagerItem(item) else: @@ -699,8 +771,6 @@ class ServiceManager(QtGui.QWidget): if item == -1: return False else: - #Switch on remote edit update functionality. - self.remoteEditTriggered = True return self.serviceItems[item][u'service_item'] def makeLive(self): @@ -710,11 +780,13 @@ class ServiceManager(QtGui.QWidget): item, count = self.findServiceItem() self.parent.LiveController.addServiceManagerItem( self.serviceItems[item][u'service_item'], count) - if str_to_bool(PluginConfig(u'General'). - get_config(u'auto preview', u'False')): + if QtCore.QSettings().value( + self.parent.generalSettingsSection + u'/auto preview', + QtCore.QVariant(False)).toBool(): item += 1 if self.serviceItems and item < len(self.serviceItems) and \ - self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.AllowsPreview): + self.serviceItems[item][u'service_item'].is_capable( + ItemCapabilities.AllowsPreview): self.parent.PreviewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], 0) @@ -725,14 +797,10 @@ class ServiceManager(QtGui.QWidget): item, count = self.findServiceItem() if self.serviceItems[item][u'service_item']\ .is_capable(ItemCapabilities.AllowsEdit): - self.remoteEditTriggered = True Receiver.send_message(u'%s_edit' % - self.serviceItems[item][u'service_item'].name, u'L:%s' % + self.serviceItems[item][u'service_item'].name.lower(), u'L:%s' % self.serviceItems[item][u'service_item'].editId ) - def onRemoteEditClear(self): - self.remoteEditTriggered = False - def findServiceItem(self): """ Finds a ServiceItem in the list @@ -774,8 +842,9 @@ class ServiceManager(QtGui.QWidget): if link.hasText(): plugin = event.mimeData().text() item = self.ServiceManagerList.itemAt(event.pos()) + #ServiceManager started the drag and drop if plugin == u'ServiceManager': - startpos, startCount = self.findServiceItem() + startpos, startCount = self.findServiceItem() if item is None: endpos = len(self.serviceItems) else: @@ -789,11 +858,28 @@ class ServiceManager(QtGui.QWidget): self.serviceItems.insert(newpos, serviceItem) self.repaintServiceList(endpos, startCount) else: + #we are not over anything so drop + replace = False if item == None: self.droppos = len(self.serviceItems) else: - self.droppos = self._getParentItemData(item) - Receiver.send_message(u'%s_add_service_item' % plugin) + #we are over somthing so lets investigate + pos = self._getParentItemData(item) - 1 + serviceItem = self.serviceItems[pos] + if plugin == serviceItem[u'service_item'].name \ + and serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsAdditions): + action = self.dndMenu.exec_(QtGui.QCursor.pos()) + #New action required + if action == self.newAction: + self.droppos = self._getParentItemData(item) + #Append to existing action + if action == self.addToAction: + self.droppos = self._getParentItemData(item) + item.setSelected(True) + replace = True + else: + self.droppos = self._getParentItemData(item) + Receiver.send_message(u'%s_add_service_item' % plugin, replace) def updateThemeList(self, theme_list): """ @@ -834,3 +920,20 @@ class ServiceManager(QtGui.QWidget): return item.data(0, QtCore.Qt.UserRole).toInt()[0] else: return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] + + def listRequest(self, message=None): + data = [] + curindex, count = self.findServiceItem() + if curindex >= 0 and curindex < len(self.serviceItems): + curitem = self.serviceItems[curindex] + else: + curitem = None + for item in self.serviceItems: + service_item = item[u'service_item'] + data_item = {} + data_item[u'title'] = unicode(service_item.title) + data_item[u'plugin'] = unicode(service_item.name) + data_item[u'notes'] = unicode(service_item.notes) + data_item[u'selected'] = (item == curitem) + data.append(data_item) + Receiver.send_message(u'servicemanager_list_response', data) diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index c86525a54..f923c9d7d 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -27,7 +27,7 @@ import logging from PyQt4 import QtGui -from openlp.core.ui import GeneralTab, ThemesTab +from openlp.core.ui import GeneralTab, ThemesTab, DisplayTab from settingsdialog import Ui_SettingsDialog log = logging.getLogger(__name__) @@ -43,6 +43,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): # Themes tab self.ThemesTab = ThemesTab(mainWindow) self.addTab(u'Themes', self.ThemesTab) + # Display tab + self.DisplayTab = DisplayTab(screens) + self.addTab(u'Display', self.DisplayTab) def addTab(self, name, tab): log.info(u'Adding %s tab' % tab.tabTitle) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index aae646f52..c0d0d915f 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -30,19 +30,9 @@ import os from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon -from openlp.core.lib import ItemCapabilities - -class HideMode(object): - """ - This is basically an enumeration class which specifies the mode of a Bible. - Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to - be downloaded from the Internet on an as-needed basis. - """ - Blank = 1 - Theme = 2 - -from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \ - PluginConfig, resize_image +from openlp.core.ui import HideMode +from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ +ItemCapabilities log = logging.getLogger(__name__) @@ -54,11 +44,12 @@ class SlideList(QtGui.QTableWidget): def __init__(self, parent=None, name=None): QtGui.QTableWidget.__init__(self, parent.Controller) self.parent = parent - self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', - QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', - QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', - QtCore.Qt.Key_0: 'servicemanager_next_item', - QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} + self.hotkey_map = { + QtCore.Qt.Key_Return: 'servicemanager_next_item', + QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop', + QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop', + QtCore.Qt.Key_0: 'servicemanager_next_item', + QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'} def keyPressEvent(self, event): if type(event) == QtGui.QKeyEvent: @@ -95,7 +86,7 @@ class SlideController(QtGui.QWidget): self.settingsmanager = settingsmanager self.isLive = isLive self.parent = parent - self.songsconfig = PluginConfig(u'Songs') + self.mainDisplay = self.parent.displayManager.mainDisplay self.loop_list = [ u'Start Loop', u'Stop Loop', @@ -124,11 +115,11 @@ class SlideController(QtGui.QWidget): if self.isLive: self.TypeLabel.setText(self.trUtf8('Live')) self.split = 1 - prefix = u'live_slidecontroller' + self.type_prefix = u'live' else: self.TypeLabel.setText(self.trUtf8('Preview')) self.split = 0 - prefix = u'preview_slidecontroller' + self.type_prefix = u'preview' self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;') self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter) self.PanelLayout.addWidget(self.TypeLabel) @@ -152,13 +143,15 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.horizontalHeader().setVisible(False) self.PreviewListWidget.verticalHeader().setVisible(False) self.PreviewListWidget.setColumnWidth(1, self.labelWidth) - self.PreviewListWidget.setColumnWidth(1, self.Controller.width() - self.labelWidth) + self.PreviewListWidget.setColumnWidth( + 1, self.Controller.width() - self.labelWidth) self.PreviewListWidget.isLive = self.isLive self.PreviewListWidget.setObjectName(u'PreviewListWidget') self.PreviewListWidget.setSelectionBehavior(1) self.PreviewListWidget.setEditTriggers( QtGui.QAbstractItemView.NoEditTriggers) - self.PreviewListWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.PreviewListWidget.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarAlwaysOff) self.PreviewListWidget.setAlternatingRowColors(True) self.ControllerLayout.addWidget(self.PreviewListWidget) # Build the full toolbar @@ -195,8 +188,6 @@ class SlideController(QtGui.QWidget): self.hideButton = self.Toolbar.addToolbarButton( u'Hide screen', u':/slides/slide_desktop.png', self.trUtf8('Hide Screen'), self.onHideDisplay, True) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen) if not self.isLive: self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarButton( @@ -209,7 +200,7 @@ class SlideController(QtGui.QWidget): if isLive: self.Toolbar.addToolbarSeparator(u'Loop Separator') self.Toolbar.addToolbarButton( - u'Start Loop', u':/media/media_time.png', + u'Start Loop', u':/media/media_time.png', self.trUtf8('Start continuous loop'), self.onStartLoop) self.Toolbar.addToolbarButton( u'Stop Loop', u':/media/media_stop.png', @@ -220,19 +211,30 @@ class SlideController(QtGui.QWidget): self.Toolbar.addToolbarWidget( u'Image SpinBox', self.DelaySpinBox) self.DelaySpinBox.setSuffix(self.trUtf8('s')) - self.DelaySpinBox.setToolTip(self.trUtf8('Delay between slides in seconds')) + self.DelaySpinBox.setToolTip( + self.trUtf8('Delay between slides in seconds')) self.ControllerLayout.addWidget(self.Toolbar) #Build a Media ToolBar self.Mediabar = OpenLPToolbar(self) self.Mediabar.addToolbarButton( - u'Media Start', u':/slides/media_playback_start.png', + u'Media Start', u':/slides/media_playback_start.png', self.trUtf8('Start playing media'), self.onMediaPlay) self.Mediabar.addToolbarButton( - u'Media Pause', u':/slides/media_playback_pause.png', + u'Media Pause', u':/slides/media_playback_pause.png', self.trUtf8('Start playing media'), self.onMediaPause) self.Mediabar.addToolbarButton( - u'Media Stop', u':/slides/media_playback_stop.png', + u'Media Stop', u':/slides/media_playback_stop.png', self.trUtf8('Start playing media'), self.onMediaStop) + if self.isLive: + self.blankButton = self.Mediabar.addToolbarButton( + u'Blank Screen', u':/slides/slide_blank.png', + self.trUtf8('Blank Screen'), self.onBlankDisplay, True) + self.themeButton = self.Mediabar.addToolbarButton( + u'Display Theme', u':/slides/slide_theme.png', + self.trUtf8('Theme Screen'), self.onThemeDisplay, True) + self.hideButton = self.Mediabar.addToolbarButton( + u'Hide screen', u':/slides/slide_desktop.png', + self.trUtf8('Hide Screen'), self.onHideDisplay, True) if not self.isLive: self.seekSlider = Phonon.SeekSlider() self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) @@ -251,13 +253,15 @@ class SlideController(QtGui.QWidget): self.SongMenu.setText(self.trUtf8('Go to Verse')) self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup) self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu) - self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'), self.Toolbar)) + self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'), + self.Toolbar)) self.Toolbar.makeWidgetsInvisible([u'Song Menu']) # Screen preview area self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225)) self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy( - QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Label)) + QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum, + QtGui.QSizePolicy.Label)) self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel) self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken) self.PreviewFrame.setObjectName(u'PreviewFrame') @@ -302,30 +306,50 @@ class SlideController(QtGui.QWidget): QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) if isLive: QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) - Receiver.send_message(u'request_spin_delay') + QtCore.SIGNAL(u'slidecontroller_live_spin_delay'), + self.receiveSpinDelay) if isLive: self.Toolbar.makeWidgetsInvisible(self.loop_list) else: self.Toolbar.makeWidgetsInvisible(self.song_edit_list) self.Mediabar.setVisible(False) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'stop_display_loop'), self.onStopLoop) + QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.type_prefix), + self.onStopLoop) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_first' % prefix), self.onSlideSelectedFirst) + QtCore.SIGNAL(u'slidecontroller_%s_first' % self.type_prefix), + self.onSlideSelectedFirst) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_next' % prefix), self.onSlideSelectedNext) + QtCore.SIGNAL(u'slidecontroller_%s_next' % self.type_prefix), + self.onSlideSelectedNext) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_previous' % prefix), self.onSlideSelectedPrevious) + QtCore.SIGNAL(u'slidecontroller_%s_previous' % self.type_prefix), + self.onSlideSelectedPrevious) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_next_noloop' % prefix), self.onSlideSelectedNextNoloop) + QtCore.SIGNAL(u'slidecontroller_%s_next_noloop' % self.type_prefix), + self.onSlideSelectedNextNoloop) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_previous_noloop' % prefix), + QtCore.SIGNAL(u'slidecontroller_%s_previous_noloop' % + self.type_prefix), self.onSlideSelectedPreviousNoloop) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_last' % prefix), self.onSlideSelectedLast) + QtCore.SIGNAL(u'slidecontroller_%s_last' % self.type_prefix), + self.onSlideSelectedLast) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_change' % prefix), self.onSlideChange) + QtCore.SIGNAL(u'slidecontroller_%s_change' % self.type_prefix), + self.onSlideChange) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_set' % self.type_prefix), + self.onSlideSelectedIndex) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_blank' % self.type_prefix), + self.onSlideBlank) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.type_prefix), + self.onSlideUnblank) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.type_prefix), + self.onTextRequest) QtCore.QObject.connect(self.Splitter, QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter) QtCore.QObject.connect(Receiver.get_receiver(), @@ -383,8 +407,9 @@ class SlideController(QtGui.QWidget): self.Toolbar.makeWidgetsInvisible(self.loop_list) if item.is_text(): self.Toolbar.makeWidgetsInvisible(self.loop_list) - if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \ - and len(self.slideList) > 0: + if QtCore.QSettings().value( + self.parent.songsSettingsSection + u'/show songbar', + QtCore.QVariant(True)).toBool() and len(self.slideList) > 0: self.Toolbar.makeWidgetsVisible([u'Song Menu']) if item.is_capable(ItemCapabilities.AllowsLoop) and \ len(item.get_frames()) > 1: @@ -392,7 +417,7 @@ class SlideController(QtGui.QWidget): if item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) - #self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) + #self.volumeSlider.setAudioOutput(self.mainDisplay.videoDisplay.audio) def enablePreviewToolBar(self, item): """ @@ -460,20 +485,18 @@ class SlideController(QtGui.QWidget): Loads a ServiceItem into the system from ServiceManager Display the slide number passed """ - log.debug(u'processsManagerItem') + log.debug(u'processManagerItem') #If old item was a command tell it to stop if self.serviceItem and self.serviceItem.is_command(): self.onMediaStop() if serviceItem.is_media(): self.onMediaStart(serviceItem) - elif serviceItem.is_command(): - if self.isLive: - blanked = self.blankButton.isChecked() - else: - blanked = False - Receiver.send_message(u'%s_start' % serviceItem.name.lower(), \ - [serviceItem.title, serviceItem.get_frame_path(), - serviceItem.get_frame_title(), slideno, self.isLive, blanked]) + if self.isLive: + blanked = self.blankButton.isChecked() + else: + blanked = False + Receiver.send_message(u'%s_start' % serviceItem.name.lower(), + [serviceItem, self.isLive, blanked, slideno]) self.slideList = {} width = self.parent.ControlSplitter.sizes()[self.split] #Set pointing cursor when we have somthing to point at @@ -537,7 +560,7 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.resizeRowsToContents() self.PreviewListWidget.setColumnWidth(0, self.labelWidth) self.PreviewListWidget.setColumnWidth(1, - self.PreviewListWidget.viewport().size().width() - self.labelWidth ) + self.PreviewListWidget.viewport().size().width() - self.labelWidth) if slideno > self.PreviewListWidget.rowCount(): self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) else: @@ -545,9 +568,29 @@ class SlideController(QtGui.QWidget): self.enableToolBar(serviceItem) self.onSlideSelected() self.PreviewListWidget.setFocus() + Receiver.send_message(u'slidecontroller_%s_started' % self.type_prefix, + [serviceItem]) log.log(15, u'Display Rendering took %4s' % (time.time() - before)) - if self.isLive: - self.serviceItem.request_audit() + + def onTextRequest(self): + """ + Return the text for the current item in controller + """ + data = [] + if self.serviceItem: + for framenumber, frame in enumerate(self.serviceItem.get_frames()): + data_item = {} + if self.serviceItem.is_text(): + data_item[u'tag'] = unicode(frame[u'verseTag']) + data_item[u'text'] = unicode(frame[u'text']) + else: + data_item[u'tag'] = unicode(framenumber) + data_item[u'text'] = u'' + data_item[u'selected'] = \ + (self.PreviewListWidget.currentRow() == framenumber) + data.append(data_item) + Receiver.send_message(u'slidecontroller_%s_text_response' + % self.type_prefix, data) #Screen event methods def onSlideSelectedFirst(self): @@ -556,60 +599,99 @@ class SlideController(QtGui.QWidget): """ if not self.serviceItem: return + Receiver.send_message(u'%s_first' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) if self.serviceItem.is_command(): - Receiver.send_message(u'%s_first'% \ - self.serviceItem.name.lower(), self.isLive) self.updatePreview() else: self.PreviewListWidget.selectRow(0) self.onSlideSelected() - def onBlankDisplay(self, force=False): + def onSlideSelectedIndex(self, message): + """ + Go to the requested slide + """ + index = int(message[0]) + if not self.serviceItem: + return + Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive, index]) + if self.serviceItem.is_command(): + self.updatePreview() + else: + self.PreviewListWidget.selectRow(index) + self.onSlideSelected() + + def onSlideBlank(self): + """ + Handle the slidecontroller blank event + """ + self.onBlankDisplay(True) + + def onSlideUnblank(self): + """ + Handle the slidecontroller unblank event + """ + self.onBlankDisplay(False) + + def onBlankDisplay(self, checked): """ Handle the blank screen button """ - log.debug(u'onBlankDisplay %d' % force) - if force: - self.blankButton.setChecked(True) - self.blankScreen(HideMode.Blank, self.blankButton.isChecked()) - self.parent.generalConfig.set_config(u'screen blank', - self.blankButton.isChecked()) + log.debug(u'onBlankDisplay %d' % checked) + self.hideButton.setChecked(False) + self.themeButton.setChecked(False) + QtCore.QSettings().setValue( + self.parent.generalSettingsSection + u'/screen blank', + QtCore.QVariant(checked)) + if checked: + Receiver.send_message(u'maindisplay_hide', HideMode.Blank) + self.blankPlugin(True) + else: + Receiver.send_message(u'maindisplay_show') + self.blankPlugin(False) - def onThemeDisplay(self, force=False): + def onThemeDisplay(self, checked): """ Handle the Theme screen button """ - log.debug(u'onThemeDisplay %d' % force) - if force: - self.themeButton.setChecked(True) - self.blankScreen(HideMode.Theme, self.themeButton.isChecked()) + log.debug(u'onThemeDisplay %d' % checked) + self.blankButton.setChecked(False) + self.hideButton.setChecked(False) + if checked: + Receiver.send_message(u'maindisplay_hide', HideMode.Theme) + self.blankPlugin(True) + else: + Receiver.send_message(u'maindisplay_show') + self.blankPlugin(False) - def onHideDisplay(self, force=False): + def onHideDisplay(self, checked): """ Handle the Hide screen button """ - log.debug(u'onHideDisplay %d' % force) - if force: - self.hideButton.setChecked(True) - if self.hideButton.isChecked(): - self.parent.mainDisplay.hideDisplay() + log.debug(u'onHideDisplay %d' % checked) + self.blankButton.setChecked(False) + self.themeButton.setChecked(False) + if checked: + Receiver.send_message(u'maindisplay_hide', HideMode.Screen) + self.blankPlugin(True) else: - self.parent.mainDisplay.showDisplay() + Receiver.send_message(u'maindisplay_show') + self.blankPlugin(False) - def blankScreen(self, blankType, blanked=False): + def blankPlugin(self, blank): """ Blank the display screen. """ if self.serviceItem is not None: - if self.serviceItem.is_command(): - if blanked: - Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) - else: - Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower()) + if blank: + Receiver.send_message(u'%s_blank' + % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) else: - self.parent.mainDisplay.blankDisplay(blankType, blanked) - else: - self.parent.mainDisplay.blankDisplay(blankType, blanked) + Receiver.send_message(u'%s_unblank' + % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) def onSlideSelected(self): """ @@ -619,9 +701,9 @@ class SlideController(QtGui.QWidget): row = self.PreviewListWidget.currentRow() self.selectedRow = 0 if row > -1 and row < self.PreviewListWidget.rowCount(): + Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive, row]) if self.serviceItem.is_command() and self.isLive: - Receiver.send_message(u'%s_slide'% \ - self.serviceItem.name.lower(), u'%s:%s' % (row, self.isLive)) self.updatePreview() else: before = time.time() @@ -630,13 +712,18 @@ class SlideController(QtGui.QWidget): self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) else: if isinstance(frame[u'main'], basestring): - self.SlidePreview.setPixmap(QtGui.QPixmap(frame[u'main'])) + self.SlidePreview.setPixmap( + QtGui.QPixmap(frame[u'main'])) else: - self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) - log.log(15, u'Slide Rendering took %4s' % (time.time() - before)) + self.SlidePreview.setPixmap( + QtGui.QPixmap.fromImage(frame[u'main'])) + log.log( + 15, u'Slide Rendering took %4s' % (time.time() - before)) if self.isLive: - self.parent.displayManager.mainDisplay.frameView(frame, True) + self.mainDisplay.frameView(frame, True) self.selectedRow = row + Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix, + row) def onSlideChange(self, row): """ @@ -644,6 +731,8 @@ class SlideController(QtGui.QWidget): """ self.PreviewListWidget.selectRow(row) self.updatePreview() + Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix, + row) def updatePreview(self): rm = self.parent.RenderManager @@ -673,9 +762,9 @@ class SlideController(QtGui.QWidget): """ if not self.serviceItem: return + Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) if self.serviceItem.is_command(): - Receiver.send_message(u'%s_next' % \ - self.serviceItem.name.lower(), self.isLive) self.updatePreview() else: row = self.PreviewListWidget.currentRow() + 1 @@ -697,9 +786,9 @@ class SlideController(QtGui.QWidget): """ if not self.serviceItem: return + Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) if self.serviceItem.is_command(): - Receiver.send_message( - u'%s_previous'% self.serviceItem.name.lower(), self.isLive) self.updatePreview() else: row = self.PreviewListWidget.currentRow() - 1 @@ -717,9 +806,9 @@ class SlideController(QtGui.QWidget): """ if not self.serviceItem: return + Receiver.send_message(u'%s_last' % self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) if self.serviceItem.is_command(): - Receiver.send_message(u'%s_last' % \ - self.serviceItem.name.lower(), self.isLive) self.updatePreview() else: self.PreviewListWidget.selectRow( @@ -748,9 +837,12 @@ class SlideController(QtGui.QWidget): self.onSlideSelectedNext() def onEditSong(self): + """ + From the preview display requires the service Item to be editied + """ self.songEdit = True - Receiver.send_message(u'%s_edit' % self.serviceItem.name, u'P:%s' % - self.serviceItem.editId ) + Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(), + u'P:%s' % self.serviceItem.editId) def onGoLive(self): """ @@ -762,10 +854,13 @@ class SlideController(QtGui.QWidget): self.serviceItem, row) def onMediaStart(self, item): + """ + Respond to the arrival of a media service item + """ + log.debug(u'SlideController onMediaStart') if self.isLive: - Receiver.send_message(u'%s_start' % item.name.lower(), \ - [item.title, item.get_frame_path(), - item.get_frame_title(), self.isLive, self.blankButton.isChecked()]) + Receiver.send_message(u'videodisplay_start', + [item, self.blankButton.isChecked()]) else: self.mediaObject.stop() self.mediaObject.clearQueue() @@ -776,22 +871,34 @@ class SlideController(QtGui.QWidget): self.onMediaPlay() def onMediaPause(self): + """ + Respond to the Pause from the media Toolbar + """ + log.debug(u'SlideController onMediaPause') if self.isLive: - Receiver.send_message(u'%s_pause'% self.serviceItem.name.lower()) + Receiver.send_message(u'videodisplay_pause') else: self.mediaObject.pause() def onMediaPlay(self): + """ + Respond to the Play from the media Toolbar + """ + log.debug(u'SlideController onMediaPlay') if self.isLive: - Receiver.send_message(u'%s_play'% self.serviceItem.name.lower(), self.isLive) + Receiver.send_message(u'videodisplay_play') else: self.SlidePreview.hide() self.video.show() self.mediaObject.play() def onMediaStop(self): + """ + Respond to the Stop from the media Toolbar + """ + log.debug(u'SlideController onMediaStop') if self.isLive: - Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive) + Receiver.send_message(u'videodisplay_stop') else: self.mediaObject.stop() self.video.hide() diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index e35afa9a7..4b356f758 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -33,10 +33,10 @@ from PyQt4 import QtCore, QtGui from openlp.core.ui import AmendThemeForm from openlp.core.theme import Theme -from openlp.core.lib import PluginConfig, OpenLPToolbar, contextMenuAction, \ +from openlp.core.lib import OpenLPToolbar, contextMenuAction, \ ThemeXML, str_to_bool, get_text_file_string, build_icon, Receiver, \ - contextMenuSeparator -from openlp.core.utils import ConfigHelper + contextMenuSeparator, SettingsManager +from openlp.core.utils import AppLocation log = logging.getLogger(__name__) @@ -47,6 +47,7 @@ class ThemeManager(QtGui.QWidget): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) self.parent = parent + self.settingsSection = u'themes' self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) self.Layout.setMargin(0) @@ -102,19 +103,18 @@ class ThemeManager(QtGui.QWidget): QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.changeGlobalFromScreen) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab) + QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab) #Variables self.themelist = [] - self.path = os.path.join(ConfigHelper.get_data_path(), u'themes') + self.path = AppLocation.get_section_data_path(self.settingsSection) self.checkThemesExists(self.path) - self.thumbPath = os.path.join(self.path, u'.thumbnails') + self.thumbPath = os.path.join(self.path, u'thumbnails') self.checkThemesExists(self.thumbPath) self.amendThemeForm.path = self.path # Last little bits of setting up - self.config = PluginConfig(u'themes') - self.servicePath = self.config.get_data_path() - self.global_theme = unicode( - self.config.get_config(u'global theme', u'')) + self.global_theme = unicode(QtCore.QSettings().value( + self.settingsSection + u'/global theme', + QtCore.QVariant(u'')).toString()) def changeGlobalFromTab(self, themeName): log.debug(u'changeGlobalFromTab %s', themeName) @@ -146,9 +146,10 @@ class ThemeManager(QtGui.QWidget): self.ThemeListWidget.item(count).text()) name = u'%s (%s)' % (self.global_theme, self.trUtf8('default')) self.ThemeListWidget.item(count).setText(name) - self.config.set_config(u'global theme', self.global_theme) - Receiver.send_message( - u'update_global_theme', self.global_theme) + QtCore.QSettings().setValue( + self.settingsSection + u'/global theme', + QtCore.QVariant(self.global_theme)) + Receiver.send_message(u'theme_update_global', self.global_theme) self.pushThemes() def onAddTheme(self): @@ -168,8 +169,9 @@ class ThemeManager(QtGui.QWidget): self.amendThemeForm.exec_() def onDeleteTheme(self): - self.global_theme = unicode( - self.config.get_config(u'global theme', u'')) + self.global_theme = unicode(QtCore.QSettings().value( + self.settingsSection + u'/global theme', + QtCore.QVariant(u'')).toString()) item = self.ThemeListWidget.currentItem() if item: theme = unicode(item.text()) @@ -222,10 +224,10 @@ class ThemeManager(QtGui.QWidget): theme = unicode(item.data(QtCore.Qt.UserRole).toString()) path = QtGui.QFileDialog.getExistingDirectory(self, unicode(self.trUtf8('Save Theme - (%s)')) % theme, - self.config.get_last_dir(1) ) + SettingsManager.get_last_dir(self.settingsSection, 1)) path = unicode(path) if path: - self.config.set_last_dir(path, 1) + SettingsManager.set_last_dir(self.settingsSection, path, 1) themePath = os.path.join(path, theme + u'.theme') zip = None try: @@ -234,7 +236,8 @@ class ThemeManager(QtGui.QWidget): for root, dirs, files in os.walk(source): for name in files: zip.write( - os.path.join(source, name), os.path.join(theme, name)) + os.path.join(source, name), + os.path.join(theme, name)) except: log.exception(u'Export Theme Failed') finally: @@ -244,11 +247,12 @@ class ThemeManager(QtGui.QWidget): def onImportTheme(self): files = QtGui.QFileDialog.getOpenFileNames( self, self.trUtf8('Select Theme Import File'), - self.config.get_last_dir(), u'Theme (*.*)') + SettingsManager.get_last_dir(self.settingsSection), u'Theme (*.*)') log.info(u'New Themes %s', unicode(files)) if files: for file in files: - self.config.set_last_dir(unicode(file)) + SettingsManager.set_last_dir( + self.settingsSection, unicode(file)) self.unzipTheme(file, self.path) self.loadThemes() @@ -291,7 +295,7 @@ class ThemeManager(QtGui.QWidget): self.pushThemes() def pushThemes(self): - Receiver.send_message(u'update_themes', self.getThemes() ) + Receiver.send_message(u'theme_update_list', self.getThemes()) def getThemes(self): return self.themelist diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 0deca94e9..dba07eb6d 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -103,7 +103,7 @@ class ThemesTab(SettingsTab): QtCore.QObject.connect(self.DefaultComboBox, QtCore.SIGNAL(u'activated(int)'), self.onDefaultComboBoxChanged) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_themes'), self.updateThemeList) + QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) def retranslateUi(self): self.GlobalGroupBox.setTitle(self.trUtf8('Global theme')) @@ -123,9 +123,13 @@ class ThemesTab(SettingsTab): 'songs.')) def load(self): - self.theme_level = int(self.config.get_config(u'theme level', - ThemeLevel.Global)) - self.global_theme = self.config.get_config(u'global theme', u'') + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.theme_level = settings.value( + u'theme level', QtCore.QVariant(ThemeLevel.Global)).toInt()[0] + self.global_theme = unicode(settings.value( + u'global theme', QtCore.QVariant(u'')).toString()) + settings.endGroup() if self.theme_level == ThemeLevel.Global: self.GlobalLevelRadioButton.setChecked(True) elif self.theme_level == ThemeLevel.Service: @@ -134,14 +138,19 @@ class ThemesTab(SettingsTab): self.SongLevelRadioButton.setChecked(True) def save(self): - self.config.set_config(u'theme level', self.theme_level) - self.config.set_config(u'global theme',self.global_theme) - Receiver.send_message(u'update_global_theme', self.global_theme) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + settings.setValue(u'theme level', + QtCore.QVariant(self.theme_level)) + settings.setValue(u'global theme', + QtCore.QVariant(self.global_theme)) + settings.endGroup() + Receiver.send_message(u'theme_update_global', self.global_theme) self.parent.RenderManager.set_global_theme( self.global_theme, self.theme_level) def postSetUp(self): - Receiver.send_message(u'update_global_theme', self.global_theme) + Receiver.send_message(u'theme_update_global', self.global_theme) def onSongLevelButtonPressed(self): self.theme_level = ThemeLevel.Song @@ -169,7 +178,9 @@ class ThemesTab(SettingsTab): Called from ThemeManager when the Themes have changed """ #reload as may have been triggered by the ThemeManager - self.global_theme = self.config.get_config(u'global theme', u'') + self.global_theme = unicode(QtCore.QSettings().value( + self.settingsSection + u'/global theme', + QtCore.QVariant(u'')).toString()) self.DefaultComboBox.clear() for theme in theme_list: self.DefaultComboBox.addItem(theme) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 12fc4a293..0aaa31de3 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -64,7 +64,8 @@ class AppLocation(object): else: try: from xdg import BaseDirectory - path = os.path.join(BaseDirectory.xdg_config_home, u'openlp') + path = os.path.join( + BaseDirectory.xdg_config_home, u'openlp') except ImportError: path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path @@ -97,27 +98,44 @@ class AppLocation(object): plugin_path = os.path.split(openlp.__file__)[0] return plugin_path + @staticmethod + def get_data_path(): + path = AppLocation.get_directory(AppLocation.DataDir) + if not os.path.exists(path): + os.makedirs(path) + return path -def check_latest_version(config, current_version): + @staticmethod + def get_section_data_path(section): + data_path = AppLocation.get_data_path() + path = os.path.join(data_path, section) + if not os.path.exists(path): + os.makedirs(path) + return path + + +def check_latest_version(current_version): """ Check the latest version of OpenLP against the version file on the OpenLP site. - ``config`` - The OpenLP config object. - ``current_version`` The current version of OpenLP. """ version_string = current_version[u'full'] - #set to prod in the distribution confif file. - last_test = config.get_config(u'last version test', datetime.now().date()) + #set to prod in the distribution config file. + settings = QtCore.QSettings() + settings.beginGroup(u'general') + last_test = unicode(settings.value(u'last version test', + QtCore.QVariant(datetime.now().date())).toString()) this_test = unicode(datetime.now().date()) - config.set_config(u'last version test', this_test) + settings.setValue(u'last version test', QtCore.QVariant(this_test)) + settings.endGroup() if last_test != this_test: version_string = u'' if current_version[u'build']: - req = urllib2.Request(u'http://www.openlp.org/files/dev_version.txt') + req = urllib2.Request( + u'http://www.openlp.org/files/dev_version.txt') else: req = urllib2.Request(u'http://www.openlp.org/files/version.txt') req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full']) @@ -149,7 +167,21 @@ def variant_to_unicode(variant): string = string_to_unicode(string) return string -from registry import Registry -from confighelper import ConfigHelper +def add_actions(target, actions): + """ + Adds multiple actions to a menu or toolbar in one command. -__all__ = [u'Registry', u'ConfigHelper', u'AppLocation', u'check_latest_version'] + ``target`` + The menu or toolbar to add actions to. + + ``actions`` + The actions to be added. An action consisting of the keyword 'None' + will result in a separator being inserted into the target. + """ + for action in actions: + if action is None: + target.addSeparator() + else: + target.addAction(action) + +__all__ = [u'AppLocation', u'check_latest_version', u'add_actions'] diff --git a/openlp/core/utils/confighelper.py b/openlp/core/utils/confighelper.py deleted file mode 100644 index c2be4bd24..000000000 --- a/openlp/core/utils/confighelper.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2010 Raoul Snyman # -# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # -# Thompson, Jon Tibble, Carsten Tinggaard # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### - -import os - -from openlp.core.utils import AppLocation -from openlp.core.utils.registry import Registry - -class ConfigHelper(object): - """ - Utility Helper to allow classes to find directories in a standard manner. - """ - __registry__ = None - - @staticmethod - def get_data_path(): - path = AppLocation.get_directory(AppLocation.DataDir) - if not os.path.exists(path): - os.makedirs(path) - return path - - @staticmethod - def get_config(section, key, default=None): - reg = ConfigHelper.get_registry() - if reg.has_value(section, key): - return reg.get_value(section, key, default) - else: - if default: - ConfigHelper.set_config(section, key, default) - return default - - @staticmethod - def set_config(section, key, value): - reg = ConfigHelper.get_registry() - if not reg.has_section(section): - reg.create_section(section) - return reg.set_value(section, key, value) - - @staticmethod - def delete_config(section, key): - reg = ConfigHelper.get_registry() - reg.delete_value(section, key) - - @staticmethod - def get_registry(): - """ - This static method loads the appropriate registry class based on the - current operating system, and returns an instantiation of that class. - """ - if ConfigHelper.__registry__ is None: - config_path = AppLocation.get_directory(AppLocation.ConfigDir) - ConfigHelper.__registry__ = Registry(config_path) - return ConfigHelper.__registry__ - diff --git a/openlp/core/utils/registry.py b/openlp/core/utils/registry.py deleted file mode 100644 index 3d7137dfd..000000000 --- a/openlp/core/utils/registry.py +++ /dev/null @@ -1,134 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2010 Raoul Snyman # -# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # -# Thompson, Jon Tibble, Carsten Tinggaard # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### - -import os - -from ConfigParser import SafeConfigParser - -class Registry(object): - """ - The Registry class is a high-level class for working with a configuration - file. - """ - def __init__(self, dir): - self.config = SafeConfigParser() - self.file_name = os.path.join(dir, u'openlp.conf') - self._load() - - def has_value(self, section, key): - """ - Check if a value exists. - """ - return self.config.has_option(section.encode('utf-8'), - key.encode('utf-8')) - - def get_value(self, section, key, default=None): - """ - Get a single value from the registry. - """ - try: - if self.config.get(section.encode('utf-8'), key.encode('utf-8')): - return self.config.get(section.encode('utf-8'), - key.encode('utf-8')).decode('utf-8') - else: - return default - except: - return default - - def set_value(self, section, key, value): - """ - Set a single value in the registry. - """ - try : - self.config.set(section.encode('utf-8'), key.encode('utf-8'), - unicode(value).encode('utf-8')) - return self._save() - except: - return False - - def delete_value(self, section, key): - """ - Delete a single value from the registry. - """ - try: - self.config.remove_option(section.encode('utf-8'), - key.encode('utf-8')) - return self._save() - except: - return False - - def has_section(self, section): - """ - Check if a section exists. - """ - return self.config.has_section(section.encode('utf-8')) - - def create_section(self, section): - """ - Create a new section in the registry. - """ - try: - self.config.add_section(section.encode('utf-8')) - return self._save() - except: - return False - - def delete_section(self, section): - """ - Delete a section (including all values). - """ - try: - self.config.remove_section(section.encode('utf-8')) - return self._save() - except: - return False - - def _load(self): - if not os.path.isfile(self.file_name): - return False - file_handle = None - try: - file_handle = open(self.file_name, u'r') - self.config.readfp(file_handle) - return True - except: - return False - finally: - if file_handle: - file_handle.close() - - def _save(self): - file_handle = None - try: - if not os.path.exists(os.path.dirname(self.file_name)): - os.makedirs(os.path.dirname(self.file_name)) - file_handle = open(self.file_name, u'w') - self.config.write(file_handle) - return self._load() - except: - return False - finally: - if file_handle: - file_handle.close() diff --git a/openlp/migration/migratebibles.py b/openlp/migration/migratebibles.py index c0d47fdb8..cad6afc3f 100644 --- a/openlp/migration/migratebibles.py +++ b/openlp/migration/migratebibles.py @@ -31,7 +31,8 @@ from sqlalchemy import * from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker, mapper -from openlp.core.lib import PluginConfig +from openlp.core.lib import SettingsManager +from openlp.core.utils import AppLocation from openlp.plugins.bibles.lib.models import * class BaseModel(object): @@ -111,9 +112,8 @@ def init_models(url): class MigrateBibles(): def __init__(self, display): self.display = display - self.config = PluginConfig(u'Bibles') - self.data_path = self.config.get_data_path() - self.database_files = self.config.get_files(u'sqlite') + self.data_path = AppLocation.get_section_data_path(u'bibles') + self.database_files = SettingsManager.get_files(u'bibles', u'.sqlite') print self.database_files def progress(self, text): diff --git a/openlp/migration/migratefiles.py b/openlp/migration/migratefiles.py index 4fa6b5a29..ceca99718 100644 --- a/openlp/migration/migratefiles.py +++ b/openlp/migration/migratefiles.py @@ -23,7 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from openlp.core.utils import ConfigHelper +from openlp.core.utils import AppLocation class MigrateFiles(): def __init__(self, display): @@ -36,14 +36,19 @@ class MigrateFiles(): def _initial_setup(self): self.display.output(u'Initial Setup started') - ConfigHelper.get_data_path() + data_path = AppLocation.get_data_path() + print data_path self.display.sub_output(u'Config created') - ConfigHelper.get_config(u'bible', u'data path') + bibles_path = AppLocation.get_section_data_path(u'bibles') + print bibles_path self.display.sub_output(u'Config created') - ConfigHelper.get_config(u'videos', u'data path') - self.display.sub_output(u'videos created') - ConfigHelper.get_config(u'images', u'data path') + # Media doesn't use a directory like the other plugins. + #media_path = AppLocation.get_section_data_path(u'media') + #self.display.sub_output(u'videos created') + images_path = AppLocation.get_section_data_path(u'images') + print images_path self.display.sub_output(u'images created') - ConfigHelper.get_config(u'presentations', u'data path') + presentations_path = AppLocation.get_section_data_path(u'presentations') + print presentations_path self.display.sub_output(u'presentations created') self.display.output(u'Initial Setup finished') diff --git a/openlp/migration/migratesongs.py b/openlp/migration/migratesongs.py index 89b55bdee..b43b1e68a 100644 --- a/openlp/migration/migratesongs.py +++ b/openlp/migration/migratesongs.py @@ -31,7 +31,8 @@ from sqlalchemy import * from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation -from openlp.core.lib import PluginConfig +from openlp.core.lib import SettingsManager +from openlp.core.utils import AppLocation from openlp.plugins.songs.lib.models import metadata, songs_table, Song, \ Author, Topic, Book from openlp.plugins.songs.lib.tables import * @@ -46,7 +47,7 @@ def init_models(url): mapper(TAuthor, temp_authors_table) mapper(Book, song_books_table) mapper(Song, songs_table, - properties={'authors': relation(Author, backref='songs', + properties={'authors': relation(Author, backref='songs', secondary=authors_songs_table), 'book': relation(Book, backref='songs'), 'topics': relation(Topic, backref='songs', @@ -111,9 +112,8 @@ class TSongAuthor(BaseModel): class MigrateSongs(): def __init__(self, display): self.display = display - self.config = PluginConfig(u'Songs') - self.data_path = self.config.get_data_path() - self.database_files = self.config.get_files(u'sqlite') + self.data_path = AppLocation.get_section_data_path(u'songs') + self.database_files = SettingsManager.get_files(u'songs', u'.sqlite') print self.database_files def process(self): @@ -156,13 +156,13 @@ class MigrateSongs(): print songs_temp.songtitle aa = self.session.execute( u'select * from songauthors_temp where songid =' + \ - unicode(songs_temp.songid) ) + unicode(songs_temp.songid)) for row in aa: a = row['authorid'] authors_temp = self.session.query(TAuthor).get(a) bb = self.session.execute( u'select * from authors where display_name = \"%s\"' % \ - unicode(authors_temp.authorname) ).fetchone() + unicode(authors_temp.authorname)).fetchone() if bb is None: author = Author() author.display_name = authors_temp.authorname diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index aeba0ab41..f97540029 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -27,9 +27,9 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver -from openlp.plugins.alerts.lib import AlertsManager, DBManager -from openlp.plugins.alerts.forms import AlertsTab, AlertForm +from openlp.core.lib import Plugin, build_icon, PluginStatus +from openlp.plugins.alerts.lib import AlertsManager, AlertsTab, DBManager +from openlp.plugins.alerts.forms import AlertForm log = logging.getLogger(__name__) @@ -41,7 +41,7 @@ class alertsPlugin(Plugin): self.weight = -3 self.icon = build_icon(u':/media/media_image.png') self.alertsmanager = AlertsManager(self) - self.manager = DBManager(self.config) + self.manager = DBManager() self.alertForm = AlertForm(self.manager, self) self.status = PluginStatus.Active @@ -83,12 +83,13 @@ class alertsPlugin(Plugin): def togglealertsState(self): self.alertsActive = not self.alertsActive - self.config.set_config(u'active', self.alertsActive) + QtCore.QSettings().setValue( + self.settingsSection + u'/active', + QtCore.QVariant(self.alertsActive)) def onAlertsTrigger(self): self.alertForm.loadList() self.alertForm.exec_() - Receiver.send_message(u'text_onTop') def about(self): about_text = self.trUtf8('Alerts Plugin
This plugin ' diff --git a/openlp/plugins/alerts/forms/__init__.py b/openlp/plugins/alerts/forms/__init__.py index 2ef91059f..9cccd8a01 100644 --- a/openlp/plugins/alerts/forms/__init__.py +++ b/openlp/plugins/alerts/forms/__init__.py @@ -23,5 +23,4 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from alertstab import AlertsTab from alertform import AlertForm diff --git a/openlp/plugins/alerts/forms/alertdialog.py b/openlp/plugins/alerts/forms/alertdialog.py index 804975ff1..00203f1f2 100644 --- a/openlp/plugins/alerts/forms/alertdialog.py +++ b/openlp/plugins/alerts/forms/alertdialog.py @@ -1,82 +1,92 @@ # -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 -# Form implementation generated from reading ui file 'alertdialog.ui' -# -# Created: Sat Apr 17 08:07:40 2010 -# by: PyQt4 UI code generator 4.7 -# -# WARNING! All changes made in this file will be lost! +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # +# Thompson, Jon Tibble, Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### from PyQt4 import QtCore, QtGui class Ui_AlertDialog(object): def setupUi(self, AlertDialog): - AlertDialog.setObjectName("AlertDialog") + AlertDialog.setObjectName(u'AlertDialog') AlertDialog.resize(567, 440) icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/icon/openlp.org-icon-32.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'), QtGui.QIcon.Normal, QtGui.QIcon.Off) AlertDialog.setWindowIcon(icon) self.AlertFormLayout = QtGui.QVBoxLayout(AlertDialog) self.AlertFormLayout.setSpacing(8) self.AlertFormLayout.setMargin(8) - self.AlertFormLayout.setObjectName("AlertFormLayout") + self.AlertFormLayout.setObjectName(u'AlertFormLayout') self.AlertTextLayout = QtGui.QFormLayout() self.AlertTextLayout.setContentsMargins(0, 0, -1, -1) self.AlertTextLayout.setSpacing(8) - self.AlertTextLayout.setObjectName("AlertTextLayout") + self.AlertTextLayout.setObjectName(u'AlertTextLayout') self.AlertEntryLabel = QtGui.QLabel(AlertDialog) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.AlertEntryLabel.sizePolicy().hasHeightForWidth()) self.AlertEntryLabel.setSizePolicy(sizePolicy) - self.AlertEntryLabel.setObjectName("AlertEntryLabel") + self.AlertEntryLabel.setObjectName(u'AlertEntryLabel') self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.AlertEntryLabel) self.AlertParameter = QtGui.QLabel(AlertDialog) - self.AlertParameter.setObjectName("AlertParameter") + self.AlertParameter.setObjectName(u'AlertParameter') self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.AlertParameter) self.ParameterEdit = QtGui.QLineEdit(AlertDialog) - self.ParameterEdit.setObjectName("ParameterEdit") + self.ParameterEdit.setObjectName(u'ParameterEdit') self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.ParameterEdit) self.AlertTextEdit = QtGui.QLineEdit(AlertDialog) - self.AlertTextEdit.setObjectName("AlertTextEdit") + self.AlertTextEdit.setObjectName(u'AlertTextEdit') self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.AlertTextEdit) self.AlertFormLayout.addLayout(self.AlertTextLayout) self.ManagementLayout = QtGui.QHBoxLayout() self.ManagementLayout.setSpacing(8) self.ManagementLayout.setContentsMargins(-1, -1, -1, 0) - self.ManagementLayout.setObjectName("ManagementLayout") + self.ManagementLayout.setObjectName(u'ManagementLayout') self.AlertListWidget = QtGui.QListWidget(AlertDialog) self.AlertListWidget.setAlternatingRowColors(True) - self.AlertListWidget.setObjectName("AlertListWidget") + self.AlertListWidget.setObjectName(u'AlertListWidget') self.ManagementLayout.addWidget(self.AlertListWidget) self.ManageButtonLayout = QtGui.QVBoxLayout() self.ManageButtonLayout.setSpacing(8) - self.ManageButtonLayout.setObjectName("ManageButtonLayout") + self.ManageButtonLayout.setObjectName(u'ManageButtonLayout') self.NewButton = QtGui.QPushButton(AlertDialog) icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/general/general_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap(QtGui.QPixmap(u':/general/general_new.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.NewButton.setIcon(icon1) - self.NewButton.setObjectName("NewButton") + self.NewButton.setObjectName(u'NewButton') self.ManageButtonLayout.addWidget(self.NewButton) self.SaveButton = QtGui.QPushButton(AlertDialog) self.SaveButton.setEnabled(False) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/general/general_save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap(QtGui.QPixmap(u':/general/general_save.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.SaveButton.setIcon(icon2) - self.SaveButton.setObjectName("SaveButton") + self.SaveButton.setObjectName(u'SaveButton') self.ManageButtonLayout.addWidget(self.SaveButton) - self.EditButton = QtGui.QPushButton(AlertDialog) - icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/general/general_edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.EditButton.setIcon(icon3) - self.EditButton.setObjectName("EditButton") - self.ManageButtonLayout.addWidget(self.EditButton) self.DeleteButton = QtGui.QPushButton(AlertDialog) - icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(":/general/general_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.DeleteButton.setIcon(icon4) - self.DeleteButton.setObjectName("DeleteButton") + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(u':/general/general_delete.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.DeleteButton.setIcon(icon3) + self.DeleteButton.setObjectName(u'DeleteButton') self.ManageButtonLayout.addWidget(self.DeleteButton) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.ManageButtonLayout.addItem(spacerItem) @@ -84,51 +94,52 @@ class Ui_AlertDialog(object): self.AlertFormLayout.addLayout(self.ManagementLayout) self.AlertButtonLayout = QtGui.QHBoxLayout() self.AlertButtonLayout.setSpacing(8) - self.AlertButtonLayout.setObjectName("AlertButtonLayout") - spacerItem1 = QtGui.QSpacerItem(181, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.AlertButtonLayout.setObjectName(u'AlertButtonLayout') + spacerItem1 = QtGui.QSpacerItem(181, 0, QtGui.QSizePolicy.Expanding, + QtGui.QSizePolicy.Minimum) self.AlertButtonLayout.addItem(spacerItem1) self.DisplayButton = QtGui.QPushButton(AlertDialog) - icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(":/general/general_live.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.DisplayButton.setIcon(icon5) - self.DisplayButton.setObjectName("DisplayButton") + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(u':/general/general_live.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.DisplayButton.setIcon(icon4) + self.DisplayButton.setObjectName(u'DisplayButton') self.AlertButtonLayout.addWidget(self.DisplayButton) self.DisplayCloseButton = QtGui.QPushButton(AlertDialog) - self.DisplayCloseButton.setIcon(icon5) - self.DisplayCloseButton.setObjectName("DisplayCloseButton") + self.DisplayCloseButton.setIcon(icon4) + self.DisplayCloseButton.setObjectName(u'DisplayCloseButton') self.AlertButtonLayout.addWidget(self.DisplayCloseButton) self.CloseButton = QtGui.QPushButton(AlertDialog) - icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(":/system/system_close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.CloseButton.setIcon(icon6) - self.CloseButton.setObjectName("CloseButton") + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(u':/system/system_close.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.CloseButton.setIcon(icon5) + self.CloseButton.setObjectName(u'CloseButton') self.AlertButtonLayout.addWidget(self.CloseButton) self.AlertFormLayout.addLayout(self.AlertButtonLayout) self.AlertEntryLabel.setBuddy(self.AlertTextEdit) self.AlertParameter.setBuddy(self.ParameterEdit) self.retranslateUi(AlertDialog) - QtCore.QObject.connect(self.CloseButton, QtCore.SIGNAL("clicked()"), AlertDialog.close) + QtCore.QObject.connect(self.CloseButton, QtCore.SIGNAL(u'clicked()'), AlertDialog.close) QtCore.QMetaObject.connectSlotsByName(AlertDialog) AlertDialog.setTabOrder(self.AlertTextEdit, self.ParameterEdit) AlertDialog.setTabOrder(self.ParameterEdit, self.AlertListWidget) AlertDialog.setTabOrder(self.AlertListWidget, self.NewButton) AlertDialog.setTabOrder(self.NewButton, self.SaveButton) - AlertDialog.setTabOrder(self.SaveButton, self.EditButton) - AlertDialog.setTabOrder(self.EditButton, self.DeleteButton) + AlertDialog.setTabOrder(self.SaveButton, self.DeleteButton) AlertDialog.setTabOrder(self.DeleteButton, self.DisplayButton) AlertDialog.setTabOrder(self.DisplayButton, self.DisplayCloseButton) AlertDialog.setTabOrder(self.DisplayCloseButton, self.CloseButton) def retranslateUi(self, AlertDialog): - AlertDialog.setWindowTitle(QtGui.QApplication.translate("AlertDialog", "Alert Message", None, QtGui.QApplication.UnicodeUTF8)) - self.AlertEntryLabel.setText(QtGui.QApplication.translate("AlertDialog", "Alert &text:", None, QtGui.QApplication.UnicodeUTF8)) - self.AlertParameter.setText(QtGui.QApplication.translate("AlertDialog", "&Parameter(s):", None, QtGui.QApplication.UnicodeUTF8)) - self.NewButton.setText(QtGui.QApplication.translate("AlertDialog", "&New", None, QtGui.QApplication.UnicodeUTF8)) - self.SaveButton.setText(QtGui.QApplication.translate("AlertDialog", "&Save", None, QtGui.QApplication.UnicodeUTF8)) - self.EditButton.setText(QtGui.QApplication.translate("AlertDialog", "&Edit", None, QtGui.QApplication.UnicodeUTF8)) - self.DeleteButton.setText(QtGui.QApplication.translate("AlertDialog", "&Delete", None, QtGui.QApplication.UnicodeUTF8)) - self.DisplayButton.setText(QtGui.QApplication.translate("AlertDialog", "Displ&ay", None, QtGui.QApplication.UnicodeUTF8)) - self.DisplayCloseButton.setText(QtGui.QApplication.translate("AlertDialog", "Display && Cl&ose", None, QtGui.QApplication.UnicodeUTF8)) - self.CloseButton.setText(QtGui.QApplication.translate("AlertDialog", "&Close", None, QtGui.QApplication.UnicodeUTF8)) + AlertDialog.setWindowTitle(self.trUtf8('Alert Message')) + self.AlertEntryLabel.setText(self.trUtf8('Alert &text:')) + self.AlertParameter.setText(self.trUtf8('&Parameter(s):')) + self.NewButton.setText(self.trUtf8('&New')) + self.SaveButton.setText(self.trUtf8('&Save')) + self.DeleteButton.setText(self.trUtf8('&Delete')) + self.DisplayButton.setText(self.trUtf8('Displ&ay')) + self.DisplayCloseButton.setText(self.trUtf8('Display && Cl&ose')) + self.CloseButton.setText(self.trUtf8('&Close')) diff --git a/openlp/plugins/alerts/forms/alertform.py b/openlp/plugins/alerts/forms/alertform.py index 08e5f5e02..9656dea42 100644 --- a/openlp/plugins/alerts/forms/alertform.py +++ b/openlp/plugins/alerts/forms/alertform.py @@ -39,7 +39,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): """ self.manager = manager self.parent = parent - self.history_required = True + self.item_id = None QtGui.QDialog.__init__(self, None) self.setupUi(self) QtCore.QObject.connect(self.DisplayButton, @@ -57,9 +57,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): QtCore.QObject.connect(self.DeleteButton, QtCore.SIGNAL(u'clicked()'), self.onDeleteClick) - QtCore.QObject.connect(self.EditButton, - QtCore.SIGNAL(u'clicked()'), - self.onEditClick) QtCore.QObject.connect(self.SaveButton, QtCore.SIGNAL(u'clicked()'), self.onSaveClick) @@ -79,12 +76,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) self.AlertListWidget.addItem(item_name) self.SaveButton.setEnabled(False) - self.EditButton.setEnabled(False) self.DeleteButton.setEnabled(False) def onDisplayClicked(self): if self.triggerAlert(unicode(self.AlertTextEdit.text())): - self.history_required = False self.loadList() def onDisplayCloseClicked(self): @@ -103,15 +98,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): self.DeleteButton.setEnabled(False) self.EditButton.setEnabled(False) - def onEditClick(self): - item = self.AlertListWidget.currentItem() - if item: - self.item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - self.AlertTextEdit.setText(unicode(item.text())) - self.SaveButton.setEnabled(True) - self.DeleteButton.setEnabled(True) - self.EditButton.setEnabled(False) - def onNewClick(self): if len(self.AlertTextEdit.text()) == 0: QtGui.QMessageBox.information(self, @@ -121,19 +107,22 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): alert = AlertItem() alert.text = unicode(self.AlertTextEdit.text()) self.manager.save_alert(alert) - self.onClearClick() + self.AlertTextEdit.setText(u'') self.loadList() def onSaveClick(self): - alert = self.manager.get_alert(self.item_id) - alert.text = unicode(self.AlertTextEdit.text()) - self.manager.save_alert(alert) - self.onClearClick() - self.loadList() + if self.item_id: + alert = self.manager.get_alert(self.item_id) + alert.text = unicode(self.AlertTextEdit.text()) + self.manager.save_alert(alert) + self.item_id = None + self.loadList() + else: + self.onNewClick() def onTextChanged(self): #Data has changed by editing it so potential storage required - self.history_required = True + self.SaveButton.setEnabled(True) def onDoubleClick(self): """ @@ -143,7 +132,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): for item in items: bitem = self.AlertListWidget.item(item.row()) self.triggerAlert(bitem.text()) - self.history_required = False + self.AlertTextEdit.setText(bitem.text()) + self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] + self.SaveButton.setEnabled(False) + self.DeleteButton.setEnabled(True) def onSingleClick(self): """ @@ -154,16 +146,13 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): for item in items: bitem = self.AlertListWidget.item(item.row()) self.AlertTextEdit.setText(bitem.text()) - self.history_required = False - self.EditButton.setEnabled(True) + self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] + self.SaveButton.setEnabled(False) self.DeleteButton.setEnabled(True) def triggerAlert(self, text): if text: + text = text.replace(u'<>', unicode(self.ParameterEdit.text())) self.parent.alertsmanager.displayAlert(text) - if self.parent.alertsTab.save_history and self.history_required: - alert = AlertItem() - alert.text = unicode(self.AlertTextEdit.text()) - self.manager.save_alert(alert) return True return False diff --git a/openlp/plugins/alerts/lib/__init__.py b/openlp/plugins/alerts/lib/__init__.py index 59a27b28e..81a2641f6 100644 --- a/openlp/plugins/alerts/lib/__init__.py +++ b/openlp/plugins/alerts/lib/__init__.py @@ -24,4 +24,5 @@ ############################################################################### from alertsmanager import AlertsManager +from alertstab import AlertsTab from manager import DBManager diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 2243b5bef..35be3b7c2 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -44,13 +44,11 @@ class AlertsManager(QtCore.QObject): self.timer_id = 0 self.alertList = [] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'flush_alert'), self.generateAlert) + QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'alert_text'), self.displayAlert) + QtCore.SIGNAL(u'alerts_text'), self.onAlertText) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'screen_changed'), self.screenChanged) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'config_updated'), self.screenChanged) + QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged) def screenChanged(self): log.debug(u'screen changed') @@ -72,6 +70,16 @@ class AlertsManager(QtCore.QObject): self.parent.maindisplay.setAlertSize(self.alertScreenPosition,\ self.alertHeight) + def onAlertText(self, message): + """ + Called via a alerts_text event. Message is single element array + containing text + """ + if message: + self.displayAlert(message[0]) + else: + self.displayAlert(u'') + def displayAlert(self, text=u''): """ Called from the Alert Tab to display an alert @@ -84,10 +92,10 @@ class AlertsManager(QtCore.QObject): self.screenChanged() self.alertList.append(text) if self.timer_id != 0: - Receiver.send_message(u'status_message', + Receiver.send_message(u'maindisplay_status_text', self.trUtf8(u'Alert message created and delayed')) return - Receiver.send_message(u'status_message', u'') + Receiver.send_message(u'maindisplay_status_text', u'') self.generateAlert() def generateAlert(self): diff --git a/openlp/plugins/alerts/forms/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py similarity index 82% rename from openlp/plugins/alerts/forms/alertstab.py rename to openlp/plugins/alerts/lib/alertstab.py index d15865a6d..7cda09488 100644 --- a/openlp/plugins/alerts/forms/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -25,18 +25,16 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, str_to_bool -from openlp.plugins.alerts.lib.models import AlertItem +from openlp.core.lib import SettingsTab class AlertsTab(SettingsTab): """ AlertsTab is the alerts settings tab in the settings dialog. """ - def __init__(self, parent, section=None): + def __init__(self, parent): self.parent = parent self.manager = parent.manager - self.alertsmanager = parent.alertsmanager - SettingsTab.__init__(self, parent.name, section) + SettingsTab.__init__(self, parent.name) def setupUi(self): self.setObjectName(u'AlertsTab') @@ -136,22 +134,6 @@ class AlertsTab(SettingsTab): QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.LocationLayout.addItem(self.LocationSpacer) self.FontLayout.addWidget(self.LocationWidget) - self.HistoryWidget = QtGui.QWidget(self.FontGroupBox) - self.HistoryWidget.setObjectName(u'HistoryWidget') - self.HistoryLayout = QtGui.QHBoxLayout(self.HistoryWidget) - self.HistoryLayout.setSpacing(8) - self.HistoryLayout.setMargin(0) - self.HistoryLayout.setObjectName(u'HistoryLayout') - self.HistoryLabel = QtGui.QLabel(self.HistoryWidget) - self.HistoryLabel.setObjectName(u'HistoryLabel') - self.HistoryLayout.addWidget(self.HistoryLabel) - self.HistoryCheckBox = QtGui.QCheckBox(self.HistoryWidget) - self.HistoryCheckBox.setObjectName(u'HistoryCheckBox') - self.HistoryLayout.addWidget(self.HistoryCheckBox) - self.HistorySpacer = QtGui.QSpacerItem(147, 20, - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.HistoryLayout.addItem(self.HistorySpacer) - self.FontLayout.addWidget(self.HistoryWidget) self.SlideLeftLayout.addWidget(self.FontGroupBox) self.SlideLeftSpacer = QtGui.QSpacerItem(20, 94, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) @@ -190,9 +172,6 @@ class AlertsTab(SettingsTab): self.SlideRightLayout.addItem(self.SlideRightSpacer) self.AlertsLayout.addWidget(self.AlertRightColumn) # Signals and slots - QtCore.QObject.connect(self.HistoryCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), - self.onHistoryCheckBoxChanged) QtCore.QObject.connect(self.BackgroundColorButton, QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked) QtCore.QObject.connect(self.FontColorButton, @@ -216,7 +195,6 @@ class AlertsTab(SettingsTab): self.TimeoutLabel.setText(self.trUtf8('Alert timeout:')) self.TimeoutSpinBox.setSuffix(self.trUtf8('s')) self.LocationLabel.setText(self.trUtf8('Location:')) - self.HistoryLabel.setText(self.trUtf8('Keep History:')) self.PreviewGroupBox.setTitle(self.trUtf8('Preview')) self.FontPreview.setText(self.trUtf8('openlp.org')) self.LocationComboBox.setItemText(0, self.trUtf8('Top')) @@ -235,12 +213,6 @@ class AlertsTab(SettingsTab): def onLocationComboBoxClicked(self, location): self.location = location - def onHistoryCheckBoxChanged(self, check_state): - self.save_history = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.save_history = True - def onFontColorButtonClicked(self): self.font_color = QtGui.QColorDialog.getColor( QtGui.QColor(self.font_color), self).name() @@ -256,17 +228,20 @@ class AlertsTab(SettingsTab): self.updateDisplay() def load(self): - self.timeout = int(self.config.get_config(u'timeout', 5)) - self.font_color = unicode( - self.config.get_config(u'font color', u'#ffffff')) - self.font_size = int(self.config.get_config(u'font size', 40)) - self.bg_color = unicode( - self.config.get_config(u'background color', u'#660000')) - self.font_face = unicode( - self.config.get_config(u'font face', QtGui.QFont().family())) - self.location = int(self.config.get_config(u'location', 0)) - self.save_history = str_to_bool( - self.config.get_config(u'save history', u'False')) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.timeout = settings.value(u'timeout', QtCore.QVariant(5)).toInt()[0] + self.font_color = unicode(settings.value( + u'font color', QtCore.QVariant(u'#ffffff')).toString()) + self.font_size = settings.value( + u'font size', QtCore.QVariant(40)).toInt()[0] + self.bg_color = unicode(settings.value( + u'background color', QtCore.QVariant(u'#660000')).toString()) + self.font_face = unicode(settings.value( + u'font face', QtCore.QVariant(QtGui.QFont().family())).toString()) + self.location = settings.value( + u'location', QtCore.QVariant(0)).toInt()[0] + settings.endGroup() self.FontSizeSpinBox.setValue(self.font_size) self.TimeoutSpinBox.setValue(self.timeout) self.FontColorButton.setStyleSheet( @@ -274,7 +249,6 @@ class AlertsTab(SettingsTab): self.BackgroundColorButton.setStyleSheet( u'background-color: %s' % self.bg_color) self.LocationComboBox.setCurrentIndex(self.location) - self.HistoryCheckBox.setChecked(self.save_history) font = QtGui.QFont() font.setFamily(self.font_face) self.FontComboBox.setCurrentFont(font) @@ -285,15 +259,17 @@ class AlertsTab(SettingsTab): self.DeleteButton.setEnabled(True) def save(self): + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) self.font_face = self.FontComboBox.currentFont().family() - self.config.set_config(u'background color', unicode(self.bg_color)) - self.config.set_config(u'font color', unicode(self.font_color)) - self.config.set_config(u'font size', unicode(self.font_size)) - self.config.set_config(u'font face', unicode(self.font_face)) - self.config.set_config(u'timeout', unicode(self.timeout)) - self.config.set_config(u'location', - unicode(self.LocationComboBox.currentIndex())) - self.config.set_config(u'save history', unicode(self.save_history)) + settings.setValue(u'background color', QtCore.QVariant(self.bg_color)) + settings.setValue(u'font color', QtCore.QVariant(self.font_color)) + settings.setValue(u'font size', QtCore.QVariant(self.font_size)) + settings.setValue(u'font face', QtCore.QVariant(self.font_face)) + settings.setValue(u'timeout', QtCore.QVariant(self.timeout)) + settings.setValue(u'location', + QtCore.QVariant(self.LocationComboBox.currentIndex())) + settings.endGroup() def updateDisplay(self): font = QtGui.QFont() diff --git a/openlp/plugins/alerts/lib/manager.py b/openlp/plugins/alerts/lib/manager.py index ec4654807..f82266f49 100644 --- a/openlp/plugins/alerts/lib/manager.py +++ b/openlp/plugins/alerts/lib/manager.py @@ -25,6 +25,9 @@ import logging +from PyQt4 import QtCore + +from openlp.core.utils import AppLocation from openlp.plugins.alerts.lib.models import init_models, metadata, AlertItem log = logging.getLogger(__name__) @@ -36,27 +39,29 @@ class DBManager(): """ log.info(u'Alerts DB loaded') - def __init__(self, config): + def __init__(self): """ Creates the connection to the database, and creates the tables if they don't exist. """ - self.config = config log.debug(u'Alerts Initialising') + settings = QtCore.QSettings() + settings.beginGroup(u'alerts') self.db_url = u'' - db_type = self.config.get_config(u'db type', u'sqlite') + db_type = unicode( + settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) if db_type == u'sqlite': self.db_url = u'sqlite:///%s/alerts.sqlite' % \ - self.config.get_data_path() + AppLocation.get_section_data_path(u'alerts') else: - self.db_url = u'%s://%s:%s@%s/%s' % \ - (db_type, self.config.get_config(u'db username'), - self.config.get_config(u'db password'), - self.config.get_config(u'db hostname'), - self.config.get_config(u'db database')) + self.db_url = u'%s://%s:%s@%s/%s' % (db_type, + unicode(settings.value(u'db username').toString()), + unicode(settings.value(u'db password').toString()), + unicode(settings.value(u'db hostname').toString()), + unicode(settings.value(u'db database').toString())) + settings.endGroup() self.session = init_models(self.db_url) metadata.create_all(checkfirst=True) - log.debug(u'Alerts Initialised') def get_all_alerts(self): diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 61724ffb6..5b4070665 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -46,7 +46,7 @@ class BiblePlugin(Plugin): def initialise(self): log.info(u'bibles Initialising') if self.manager is None: - self.manager = BibleManager(self, self.config) + self.manager = BibleManager(self) Plugin.initialise(self) self.insert_toolbox_item() self.ImportBibleItem.setVisible(True) diff --git a/openlp/plugins/bibles/forms/importwizardform.py b/openlp/plugins/bibles/forms/importwizardform.py index a717a4f44..f5dbc8ee0 100644 --- a/openlp/plugins/bibles/forms/importwizardform.py +++ b/openlp/plugins/bibles/forms/importwizardform.py @@ -31,7 +31,7 @@ import os.path from PyQt4 import QtCore, QtGui from bibleimportwizard import Ui_BibleImportWizard -from openlp.core.lib import Receiver +from openlp.core.lib import Receiver, SettingsManager from openlp.core.utils import AppLocation, variant_to_unicode from openlp.plugins.bibles.lib.manager import BibleFormat @@ -59,16 +59,13 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): """ log.info(u'BibleImportForm loaded') - def __init__(self, parent, config, manager, bibleplugin): + def __init__(self, parent, manager, bibleplugin): """ Instantiate the wizard, and run any extra setup we need to. ``parent`` The QWidget-derived parent of the wizard. - ``config`` - The configuration object for storing and retrieving settings. - ``manager`` The Bible manager. @@ -81,7 +78,6 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.finishButton = self.button(QtGui.QWizard.FinishButton) self.cancelButton = self.button(QtGui.QWizard.CancelButton) self.manager = manager - self.config = config self.bibleplugin = bibleplugin self.manager.set_process_dialog(self) self.web_bible_list = {} @@ -240,7 +236,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): """ log.debug('Cancel button pressed!') if self.currentId() == 3: - Receiver.send_message(u'openlpstopimport') + Receiver.send_message(u'bibles_stop_import') def onCurrentIdChanged(self, id): if id == 3: @@ -277,6 +273,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): u'license_permission', self.PermissionEdit) def setDefaults(self): + settings = QtCore.QSettings() + settings.beginGroup(self.bibleplugin.settingsSection) self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'csv_booksfile', QtCore.QVariant('')) @@ -285,15 +283,17 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.setField(u'web_location', QtCore.QVariant(WebDownload.Crosswalk)) self.setField(u'web_biblename', QtCore.QVariant(self.BibleComboBox)) self.setField(u'proxy_server', - QtCore.QVariant(self.config.get_config(u'proxy address', ''))) + settings.value(u'proxy address', QtCore.QVariant(u''))) self.setField(u'proxy_username', - QtCore.QVariant(self.config.get_config(u'proxy username',''))) + settings.value(u'proxy username', QtCore.QVariant(u''))) self.setField(u'proxy_password', - QtCore.QVariant(self.config.get_config(u'proxy password',''))) + settings.value(u'proxy password', QtCore.QVariant(u''))) self.setField(u'license_version', QtCore.QVariant(self.VersionNameEdit)) self.setField(u'license_copyright', QtCore.QVariant(self.CopyrightEdit)) - self.setField(u'license_permission', QtCore.QVariant(self.PermissionEdit)) + self.setField(u'license_permission', + QtCore.QVariant(self.PermissionEdit)) self.onLocationComboBoxChanged(WebDownload.Crosswalk) + settings.endGroup() def loadWebBibles(self): """ @@ -302,10 +302,10 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): #Load and store Crosswalk Bibles filepath = AppLocation.get_directory(AppLocation.PluginsDir) filepath = os.path.join(filepath, u'bibles', u'resources') - fbibles = None try: self.web_bible_list[WebDownload.Crosswalk] = {} - books_file = open(os.path.join(filepath, u'crosswalkbooks.csv'), 'r') + books_file = open( + os.path.join(filepath, u'crosswalkbooks.csv'), 'r') dialect = csv.Sniffer().sniff(books_file.read(1024)) books_file.seek(0) books_reader = csv.reader(books_file, dialect) @@ -345,16 +345,17 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): def getFileName(self, title, editbox): filename = QtGui.QFileDialog.getOpenFileName(self, title, - self.config.get_last_dir(1)) + SettingsManager.get_last_dir(self.bibleplugin.settingsSection, 1)) if filename: editbox.setText(filename) - self.config.set_last_dir(filename, 1) + SettingsManager.set_last_dir( + self.bibleplugin.settingsSection, filename, 1) def incrementProgressBar(self, status_text): log.debug(u'IncrementBar %s', status_text) self.ImportProgressLabel.setText(status_text) self.ImportProgressBar.setValue(self.ImportProgressBar.value() + 1) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') def preImport(self): self.finishButton.setVisible(False) @@ -362,13 +363,14 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setValue(0) self.ImportProgressLabel.setText(self.trUtf8('Starting import...')) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') def performImport(self): bible_type = self.field(u'source_format').toInt()[0] license_version = variant_to_unicode(self.field(u'license_version')) license_copyright = variant_to_unicode(self.field(u'license_copyright')) - license_permission = variant_to_unicode(self.field(u'license_permission')) + license_permission = variant_to_unicode( + self.field(u'license_permission')) importer = None if bible_type == BibleFormat.OSIS: # Import an OSIS bible @@ -424,4 +426,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.ImportProgressBar.setValue(self.ImportProgressBar.maximum()) self.finishButton.setVisible(True) self.cancelButton.setVisible(False) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index 4c205b920..80e0cef5e 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -27,7 +27,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import str_to_bool, Receiver, SettingsTab +from openlp.core.lib import Receiver, SettingsTab log = logging.getLogger(__name__) @@ -37,11 +37,11 @@ class BiblesTab(SettingsTab): """ log.info(u'Bible Tab loaded') - def __init__(self, title, section=None): + def __init__(self, title): self.paragraph_style = True self.show_new_chapters = False self.display_style = 0 - SettingsTab.__init__(self, title, section) + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'BiblesTab') @@ -146,11 +146,12 @@ class BiblesTab(SettingsTab): self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onBibleDualCheckBox) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_themes'), self.updateThemeList) + QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) def retranslateUi(self): self.VerseDisplayGroupBox.setTitle(self.trUtf8('Verse Display')) - self.NewChaptersCheckBox.setText(self.trUtf8('Only show new chapter numbers')) + self.NewChaptersCheckBox.setText( + self.trUtf8('Only show new chapter numbers')) self.LayoutStyleLabel.setText(self.trUtf8('Layout Style:')) self.DisplayStyleLabel.setText(self.trUtf8('Display Style:')) self.BibleThemeLabel.setText(self.trUtf8('Bible Theme:')) @@ -161,8 +162,8 @@ class BiblesTab(SettingsTab): self.DisplayStyleComboBox.setItemText(1, self.trUtf8('( and )')) self.DisplayStyleComboBox.setItemText(2, self.trUtf8('{ and }')) self.DisplayStyleComboBox.setItemText(3, self.trUtf8('[ and ]')) - self.ChangeNoteLabel.setText( - self.trUtf8('Note:\nChanges don\'t affect verses already in the service')) + self.ChangeNoteLabel.setText(self.trUtf8( + 'Note:\nChanges don\'t affect verses already in the service')) self.BibleDualCheckBox.setText(self.trUtf8('Display Dual Bible Verses')) def onBibleThemeComboBoxChanged(self): @@ -187,29 +188,36 @@ class BiblesTab(SettingsTab): self.duel_bibles = True def load(self): - self.show_new_chapters = str_to_bool( - self.config.get_config(u'display new chapter', u'False')) - self.display_style = int( - self.config.get_config(u'display brackets', u'0')) - self.layout_style = int( - self.config.get_config(u'verse layout style', u'0')) - self.bible_theme = self.config.get_config(u'bible theme', u'0') - self.duel_bibles = str_to_bool( - self.config.get_config(u'dual bibles', u'True')) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.show_new_chapters = settings.value( + u'display new chapter', QtCore.QVariant(False)).toBool() + self.display_style = settings.value( + u'display brackets', QtCore.QVariant(0)).toInt()[0] + self.layout_style = settings.value( + u'verse layout style', QtCore.QVariant(0)).toInt()[0] + self.bible_theme = unicode( + settings.value(u'bible theme', QtCore.QVariant(u'')).toString()) + self.duel_bibles = settings.value( + u'dual bibles', QtCore.QVariant(True)).toBool() self.NewChaptersCheckBox.setChecked(self.show_new_chapters) self.DisplayStyleComboBox.setCurrentIndex(self.display_style) self.LayoutStyleComboBox.setCurrentIndex(self.layout_style) self.BibleDualCheckBox.setChecked(self.duel_bibles) + settings.endGroup() def save(self): - self.config.set_config( - u'display new chapter', unicode(self.show_new_chapters)) - self.config.set_config( - u'display brackets', unicode(self.display_style)) - self.config.set_config( - u'verse layout style', unicode(self.layout_style)) - self.config.set_config(u'dual bibles', unicode(self.duel_bibles)) - self.config.set_config(u'bible theme', unicode(self.bible_theme)) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + settings.setValue(u'display new chapter', + QtCore.QVariant(self.show_new_chapters)) + settings.setValue(u'display brackets', + QtCore.QVariant(self.display_style)) + settings.setValue(u'verse layout style', + QtCore.QVariant(self.layout_style)) + settings.setValue(u'dual bibles', QtCore.QVariant(self.duel_bibles)) + settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme)) + settings.endGroup() def updateThemeList(self, theme_list): """ diff --git a/openlp/plugins/bibles/lib/csvbible.py b/openlp/plugins/bibles/lib/csvbible.py index 2f40e4b96..5b49852e5 100644 --- a/openlp/plugins/bibles/lib/csvbible.py +++ b/openlp/plugins/bibles/lib/csvbible.py @@ -52,7 +52,7 @@ class CSVBible(BibleDB): raise KeyError(u'You have to supply a file to import verses from.') self.versesfile = kwargs[u'versesfile'] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) + QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) def stop_import(self): """ @@ -77,7 +77,7 @@ class CSVBible(BibleDB): details = chardet.detect(line[1]) self.create_book(unicode(line[1], details['encoding']), line[2], int(line[0])) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') except: log.exception(u'Loading books from file failed') success = False @@ -105,7 +105,7 @@ class CSVBible(BibleDB): self.commit() self.create_verse(book.id, line[1], line[2], unicode(line[3], details['encoding'])) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') self.commit() except: log.exception(u'Loading verses from file failed') @@ -118,4 +118,3 @@ class CSVBible(BibleDB): return False else: return success - diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 66b956109..79a650541 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -56,20 +56,14 @@ class BibleDB(QtCore.QObject): ``name`` The name of the database. This is also used as the file name for SQLite databases. - - ``config`` - The configuration object, passed in from the plugin. """ log.info(u'BibleDB loaded') QtCore.QObject.__init__(self) if u'path' not in kwargs: raise KeyError(u'Missing keyword argument "path".') - if u'config' not in kwargs: - raise KeyError(u'Missing keyword argument "config".') if u'name' not in kwargs and u'file' not in kwargs: raise KeyError(u'Missing keyword argument "name" or "file".') self.stop_import_flag = False - self.config = kwargs[u'config'] if u'name' in kwargs: self.name = kwargs[u'name'] if not isinstance(self.name, unicode): @@ -79,16 +73,20 @@ class BibleDB(QtCore.QObject): self.file = kwargs[u'file'] self.db_file = os.path.join(kwargs[u'path'], self.file) log.debug(u'Load bible %s on path %s', self.file, self.db_file) - db_type = self.config.get_config(u'db type', u'sqlite') + settings = QtCore.QSettings() + settings.beginGroup(u'bibles') + db_type = unicode( + settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) db_url = u'' if db_type == u'sqlite': db_url = u'sqlite:///' + self.db_file else: - db_url = u'%s://%s:%s@%s/%s' % \ - (db_type, self.config.get_config(u'db username'), - self.config.get_config(u'db password'), - self.config.get_config(u'db hostname'), - self.config.get_config(u'db database')) + db_url = u'%s://%s:%s@%s/%s' % (db_type, + unicode(settings.value(u'db username').toString()), + unicode(settings.value(u'db password').toString()), + unicode(settings.value(u'db hostname').toString()), + unicode(settings.value(u'db database').toString())) + settings.endGroup() self.metadata, self.session = init_models(db_url) self.metadata.create_all(checkfirst=True) if u'file' in kwargs: @@ -113,7 +111,7 @@ class BibleDB(QtCore.QObject): ``old_filename`` The "dirty" file name or version name. """ - if not isinstance(old_filename, unicode): + if not isinstance(old_filename, unicode): old_filename = unicode(old_filename, u'utf-8') old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') return old_filename + u'.sqlite' diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index b14f9b3a2..37d42f833 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -203,9 +203,9 @@ class BGExtract(BibleCommon): # Let's get the page, and then open it in BeautifulSoup, so as to # attempt to make "easy" work of bad HTML. page = urllib2.urlopen(urlstring) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') soup = BeautifulSoup(page) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') verses = soup.find(u'div', u'result-text-style-normal') verse_number = 0 verse_list = {0: u''} @@ -213,7 +213,7 @@ class BGExtract(BibleCommon): # This is a PERFECT example of opening the Cthulu tag! # O Bible Gateway, why doth ye such horrific HTML produce? for verse in verses: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes': break if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum': @@ -222,7 +222,7 @@ class BGExtract(BibleCommon): continue if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents: for item in verse.contents: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'): continue if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum': @@ -235,7 +235,7 @@ class BGExtract(BibleCommon): continue if isinstance(item, Tag) and item.name == u'font': for subitem in item.contents: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum': continue if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents: @@ -294,37 +294,37 @@ class CWExtract(BibleCommon): (version, urlbookname.lower(), chapter) log.debug(u'URL: %s', chapter_url) page = urllib2.urlopen(chapter_url) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if not page: return None soup = BeautifulSoup(page) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') htmlverses = soup.findAll(u'span', u'versetext') verses = {} reduce_spaces = re.compile(r'[ ]{2,}') fix_punctuation = re.compile(r'[ ]+([.,;])') for verse in htmlverses: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') versenumber = int(verse.contents[0].contents[0]) versetext = u'' for part in verse.contents: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(part, NavigableString): versetext = versetext + part elif part and part.attrMap and \ (part.attrMap[u'class'] == u'WordsOfChrist' or \ part.attrMap[u'class'] == u'strongs'): for subpart in part.contents: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(subpart, NavigableString): versetext = versetext + subpart elif subpart and subpart.attrMap and \ subpart.attrMap[u'class'] == u'strongs': for subsub in subpart.contents: - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') if isinstance(subsub, NavigableString): versetext = versetext + subsub - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') # Fix up leading and trailing spaces, multiple spaces, and spaces # between text and , and . versetext = versetext.strip(u'\n\r\t ') @@ -415,14 +415,14 @@ class HTTPBible(BibleDB): if not db_book: book_details = self.lookup_book(book) if not book_details: - Receiver.send_message(u'bible_nobook') + Receiver.send_message(u'bibles_nobook') return [] db_book = self.create_book(book_details[u'name'], book_details[u'abbreviation'], book_details[u'testament_id']) book = db_book.name if BibleDB.get_verse_count(self, book, reference[1]) == 0: - Receiver.send_message(u'bible_showprogress') - Receiver.send_message(u'process_events') + Receiver.send_message(u'bibles_showprogress') + Receiver.send_message(u'openlp_process_events') search_results = self.get_chapter(self.name, book, reference[1]) if search_results and search_results.has_verselist(): ## We have found a book of the bible lets check to see @@ -430,14 +430,14 @@ class HTTPBible(BibleDB): ## we get a correct book. For example it is possible ## to request ac and get Acts back. bookname = search_results.get_book() - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') # check to see if book/chapter exists db_book = self.get_book(bookname) self.create_chapter(db_book.id, search_results.get_chapter(), search_results.get_verselist()) - Receiver.send_message(u'process_events') - Receiver.send_message(u'bible_hideprogress') - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') + Receiver.send_message(u'bibles_hideprogress') + Receiver.send_message(u'openlp_process_events') return BibleDB.get_verses(self, reference_list) def get_chapter(self, version, book, chapter): @@ -496,4 +496,3 @@ class HTTPBible(BibleDB): The hostname or IP address of the proxy server. """ self.proxy_server = server - diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index 8e622963d..8a87288f3 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -25,6 +25,11 @@ import logging +from PyQt4 import QtCore + +from openlp.core.lib import SettingsManager +from openlp.core.utils import AppLocation + from common import parse_reference from opensong import OpenSongBible from osis import OSISBible @@ -94,25 +99,24 @@ class BibleManager(object): """ log.info(u'Bible manager loaded') - def __init__(self, parent, config): + def __init__(self, parent): """ Finds all the bibles defined for the system and creates an interface object for each bible containing connection information. Throws Exception if no Bibles are found. Init confirms the bible exists and stores the database path. - - ``config`` - The plugin's configuration object. """ log.debug(u'Bible Initialising') - self.config = config self.parent = parent + self.settingsSection = u'bibles' self.web = u'Web' self.db_cache = None - self.path = self.config.get_data_path() - self.proxy_name = self.config.get_config(u'proxy name') - self.suffix = u'sqlite' + self.path = AppLocation.get_section_data_path(self.settingsSection) + self.proxy_name = unicode( + QtCore.QSettings().value(self.settingsSection + u'/proxy name', + QtCore.QVariant(u'')).toString()) + self.suffix = u'.sqlite' self.import_wizard = None self.reload_bibles() self.media = None @@ -124,23 +128,23 @@ class BibleManager(object): BibleDB class. """ log.debug(u'Reload bibles') - files = self.config.get_files(self.suffix) + files = SettingsManager.get_files(self.settingsSection, self.suffix) log.debug(u'Bible Files %s', files) self.db_cache = {} for filename in files: - bible = BibleDB(self.parent, path=self.path, file=filename, - config=self.config) + bible = BibleDB(self.parent, path=self.path, file=filename) name = bible.get_name() log.debug(u'Bible Name: "%s"', name) self.db_cache[name] = bible # look to see if lazy load bible exists and get create getter. source = self.db_cache[name].get_meta(u'download source') if source: - download_name = self.db_cache[name].get_meta(u'download name').value + download_name = \ + self.db_cache[name].get_meta(u'download name').value meta_proxy = self.db_cache[name].get_meta(u'proxy url') web_bible = HTTPBible(self.parent, path=self.path, - file=filename, config=self.config, - download_source=source.value, download_name=download_name) + file=filename, download_source=source.value, + download_name=download_name) if meta_proxy: web_bible.set_proxy_server(meta_proxy.value) self.db_cache[name] = web_bible @@ -167,7 +171,6 @@ class BibleManager(object): """ class_ = BibleFormat.get_class(type) kwargs['path'] = self.path - kwargs['config'] = self.config importer = class_(self.parent, **kwargs) name = importer.register(self.import_wizard) self.db_cache[name] = importer @@ -208,7 +211,8 @@ class BibleManager(object): Returns all the number of verses for a given book and chapterMaxBibleBookVerses """ - log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)', bible, book, chapter) + log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)', + bible, book, chapter) return self.db_cache[bible].get_verse_count(book, chapter) def get_verses(self, bible, versetext): @@ -260,4 +264,3 @@ class BibleManager(object): if bible == name: return True return False - diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index ab067575b..e44c424a4 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -28,8 +28,8 @@ import time from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, Receiver, str_to_bool, \ - BaseListWithDnD, ItemCapabilities +from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \ + ItemCapabilities from openlp.plugins.bibles.forms import ImportWizardForm log = logging.getLogger(__name__) @@ -54,7 +54,6 @@ class BibleMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.PluginNameShort = u'Bible' - self.ConfigSection = title self.IconPath = u'songs/song' self.ListViewWithDnD_class = BibleListView self.lastReference = [] @@ -63,7 +62,7 @@ class BibleMediaItem(MediaManagerItem): # place to store the search results self.search_results = {} QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'openlpreloadbibles'), self.reloadBibles) + QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles) def _decodeQtObject(self, listobj, key): obj = listobj[QtCore.QString(key)] @@ -257,11 +256,11 @@ class BibleMediaItem(MediaManagerItem): QtCore.QObject.connect(self.QuickSearchEdit, QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bible_showprogress'), self.onSearchProgressShow) + QtCore.SIGNAL(u'bibles_showprogress'), self.onSearchProgressShow) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bible_hideprogress'), self.onSearchProgressHide) + QtCore.SIGNAL(u'bibles_hideprogress'), self.onSearchProgressHide) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bible_nobook'), self.onNoBookFound) + QtCore.SIGNAL(u'bibles_nobook'), self.onNoBookFound) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) @@ -276,8 +275,8 @@ class BibleMediaItem(MediaManagerItem): self.SearchProgress.setObjectName(u'SearchProgress') def configUpdated(self): - if str_to_bool( - self.parent.config.get_config(u'dual bibles', u'False')): + if QtCore.QSettings().value(self.settingsSection + u'/dual bibles', + QtCore.QVariant(False)).toBool(): self.AdvancedSecondBibleLabel.setVisible(True) self.AdvancedSecondBibleComboBox.setVisible(True) self.QuickSecondVersionLabel.setVisible(True) @@ -322,7 +321,7 @@ class BibleMediaItem(MediaManagerItem): def setQuickMessage(self, text): self.QuickMessage.setText(text) self.AdvancedMessage.setText(text) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') #minor delay to get the events processed time.sleep(0.1) @@ -353,7 +352,7 @@ class BibleMediaItem(MediaManagerItem): def onSearchProgressShow(self): self.SearchProgress.setVisible(True) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') #self.SearchProgress.setMinimum(0) #self.SearchProgress.setMaximum(2) #self.SearchProgress.setValue(1) @@ -381,7 +380,7 @@ class BibleMediaItem(MediaManagerItem): self.AdvancedBookComboBox.itemData(item).toInt()[0]) def onImportClick(self): - self.bibleimportform = ImportWizardForm(self, self.parent.config, + self.bibleimportform = ImportWizardForm(self, self.parent.manager, self.parent) self.bibleimportform.exec_() self.reloadBibles() @@ -450,6 +449,7 @@ class BibleMediaItem(MediaManagerItem): bible_text = u'' service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) + service_item.add_capability(ItemCapabilities.AllowsAdditions) #If we want to use a 2nd translation / version bible2 = u'' if self.SearchTabWidget.currentIndex() == 0: diff --git a/openlp/plugins/bibles/lib/opensong.py b/openlp/plugins/bibles/lib/opensong.py index 2f7e3e451..ea8bd3538 100644 --- a/openlp/plugins/bibles/lib/opensong.py +++ b/openlp/plugins/bibles/lib/opensong.py @@ -49,7 +49,7 @@ class OpenSongBible(BibleDB): raise KeyError(u'You have to supply a file name to import from.') self.filename = kwargs['filename'] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) + QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) def stop_import(self): """ @@ -92,7 +92,7 @@ class OpenSongBible(BibleDB): int(verse.attrib[u'n']), unicode(verse.text) ) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') self.wizard.incrementProgressBar( QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\ db_book.name, chapter.attrib[u'n']))) diff --git a/openlp/plugins/bibles/lib/osis.py b/openlp/plugins/bibles/lib/osis.py index 4416bb2c6..104e2adb8 100644 --- a/openlp/plugins/bibles/lib/osis.py +++ b/openlp/plugins/bibles/lib/osis.py @@ -84,7 +84,7 @@ class OSISBible(BibleDB): if fbibles: fbibles.close() QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) + QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) def stop_import(self): """ @@ -98,7 +98,8 @@ class OSISBible(BibleDB): Loads a Bible from file. """ log.debug(u'Starting OSIS import from "%s"' % self.filename) - self.wizard.incrementProgressBar(u'Detecting encoding (this may take a few minutes)...') + self.wizard.incrementProgressBar( + u'Detecting encoding (this may take a few minutes)...') detect_file = None try: detect_file = open(self.filename, u'r') @@ -164,10 +165,10 @@ class OSISBible(BibleDB): verse_text = verse_text.replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ - .replace(u'', u'').replace(u'', u'') + .replace(u'', u'').replace(u'', u'') verse_text = self.spaces_regex.sub(u' ', verse_text) self.create_verse(db_book.id, chapter, verse, verse_text) - Receiver.send_message(u'process_events') + Receiver.send_message(u'openlp_process_events') self.commit() self.wizard.incrementProgressBar(u'Finishing import...') if match_count == 0: diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index 979df411c..a59596f22 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -45,7 +45,7 @@ class CustomPlugin(Plugin): def __init__(self, plugin_helpers): Plugin.__init__(self, u'Custom', u'1.9.1', plugin_helpers) self.weight = -5 - self.custommanager = CustomManager(self.config) + self.custommanager = CustomManager() self.edit_custom_form = EditCustomForm(self.custommanager) self.icon = build_icon(u':/media/media_custom.png') self.status = PluginStatus.Active diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index cbbb023aa..373c29794 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -77,7 +77,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), self.onVerseListViewPressed) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_themes'), self.loadThemes) + QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) # Create other objects and forms self.custommanager = custommanager self.initialise() @@ -86,7 +86,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): log.debug(u'onPreview') if button.text() == unicode(self.trUtf8('Save && Preview')) \ and self.saveCustom(): - Receiver.send_message(u'preview_custom') + Receiver.send_message(u'custom_preview') def initialise(self): self.editAll = False @@ -135,13 +135,13 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.previewButton.setVisible(True) def closePressed(self): - Receiver.send_message(u'remote_edit_clear') + Receiver.send_message(u'custom_edit_clear') self.close() def accept(self): log.debug(u'accept') if self.saveCustom(): - Receiver.send_message(u'load_custom_list') + Receiver.send_message(u'custom_load_list') self.close() def saveCustom(self): @@ -271,4 +271,4 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): if self.VerseTextEdit.toPlainText(): self.VerseTextEdit.setFocus() return False, self.trUtf8('You have unsaved data, please save or clear') - return True, u'' + return True, u'' diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index cceca1148..2b6cedfbf 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -25,14 +25,14 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, str_to_bool +from openlp.core.lib import SettingsTab class CustomTab(SettingsTab): """ CustomTab is the Custom settings tab in the settings dialog. """ - def __init__(self, title, section=None): - SettingsTab.__init__(self, title, section) + def __init__(self, title): + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'CustomTab') @@ -57,7 +57,7 @@ class CustomTab(SettingsTab): def retranslateUi(self): self.CustomModeGroupBox.setTitle(self.trUtf8('Custom Display')) self.DisplayFooterCheckBox.setText( - self.trUtf8('Display Footer:')) + self.trUtf8('Display Footer')) def onDisplayFooterCheckBoxChanged(self, check_state): self.displayFooter = False @@ -66,9 +66,11 @@ class CustomTab(SettingsTab): self.displayFooter = True def load(self): - self.displayFooter = str_to_bool( - self.config.get_config(u'display footer', True)) + self.displayFooter = QtCore.QSettings().value( + self.settingsSection + u'/display footer', + QtCore.QVariant(True)).toBool() self.DisplayFooterCheckBox.setChecked(self.displayFooter) def save(self): - self.config.set_config(u'display footer', unicode(self.displayFooter)) + QtCore.QSettings().setValue(self.settingsSection + u'/display footer', + QtCore.QVariant(self.displayFooter)) diff --git a/openlp/plugins/custom/lib/manager.py b/openlp/plugins/custom/lib/manager.py index 2deee9ba2..9e781f560 100644 --- a/openlp/plugins/custom/lib/manager.py +++ b/openlp/plugins/custom/lib/manager.py @@ -25,6 +25,9 @@ import logging +from PyQt4 import QtCore + +from openlp.core.utils import AppLocation from openlp.plugins.custom.lib.models import init_models, metadata, CustomSlide log = logging.getLogger(__name__) @@ -36,27 +39,29 @@ class CustomManager(): """ log.info(u'Custom manager loaded') - def __init__(self, config): + def __init__(self): """ Creates the connection to the database, and creates the tables if they don't exist. """ - self.config = config log.debug(u'Custom Initialising') + settings = QtCore.QSettings() + settings.beginGroup(u'custom') self.db_url = u'' - db_type = self.config.get_config(u'db type', u'sqlite') + db_type = unicode( + settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) if db_type == u'sqlite': self.db_url = u'sqlite:///%s/custom.sqlite' % \ - self.config.get_data_path() + AppLocation.get_section_data_path(u'custom') else: - self.db_url = u'%s://%s:%s@%s/%s' % \ - (db_type, self.config.get_config(u'db username'), - self.config.get_config(u'db password'), - self.config.get_config(u'db hostname'), - self.config.get_config(u'db database')) + self.db_url = u'%s://%s:%s@%s/%s' % (db_type, + unicode(settings.value(u'db username').toString()), + unicode(settings.value(u'db password').toString()), + unicode(settings.value(u'db hostname').toString()), + unicode(settings.value(u'db database').toString())) self.session = init_models(self.db_url) metadata.create_all(checkfirst=True) - + settings.endGroup() log.debug(u'Custom Initialised') def get_all_slides(self): @@ -107,4 +112,5 @@ class CustomManager(): return True def get_customs_for_theme(self, theme): - return self.session.query(CustomSlide).filter(CustomSlide.theme_name == theme).all() + return self.session.query( + CustomSlide).filter(CustomSlide.theme_name == theme).all() diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 3d55db719..599d73625 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -27,8 +27,8 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD,\ -Receiver, str_to_bool, ItemCapabilities +from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \ + Receiver, ItemCapabilities log = logging.getLogger(__name__) @@ -45,7 +45,6 @@ class CustomMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.PluginNameShort = u'Custom' - self.ConfigSection = title self.IconPath = u'custom/custom' # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem @@ -58,13 +57,13 @@ class CustomMediaItem(MediaManagerItem): def addEndHeaderBar(self): QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) + QtCore.SIGNAL(u'custom_edit'), self.onRemoteEdit) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear) + QtCore.SIGNAL(u'custom_edit_clear' ), self.onRemoteEditClear) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'load_custom_list'), self.initialise) + QtCore.SIGNAL(u'custom_load_list'), self.initialise) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'preview_custom'), self.onPreviewClick) + QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) def initPluginNameVisible(self): self.PluginNameVisible = self.trUtf8('Custom') @@ -133,7 +132,7 @@ class CustomMediaItem(MediaManagerItem): self.ListView.takeItem(row) def generateSlideData(self, service_item, item=None): - raw_slides =[] + raw_slides = [] raw_footer = [] slide = None theme = None @@ -164,8 +163,8 @@ class CustomMediaItem(MediaManagerItem): service_item.title = title for slide in raw_slides: service_item.add_from_text(slide[:30], slide) - if str_to_bool(self.parent.config.get_config(u'display footer', True)) \ - or credit: + if QtCore.QSettings().value(self.settingsSection + u'/display footer', + QtCore.QVariant(True)).toBool() or credit: raw_footer.append(title + u' ' + credit) else: raw_footer.append(u'') diff --git a/openlp/plugins/images/lib/imagetab.py b/openlp/plugins/images/lib/imagetab.py index 203b36842..346d28b16 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -31,8 +31,8 @@ class ImageTab(SettingsTab): """ ImageTab is the Image settings tab in the settings dialog. """ - def __init__(self, title, section=None): - SettingsTab.__init__(self, title, section) + def __init__(self, title): + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'ImageTab') @@ -71,12 +71,17 @@ class ImageTab(SettingsTab): self.loop_delay = self.TimeoutSpinBox.value() def load(self): - self.loop_delay = int(self.config.get_config(u'loop delay', 5)) + self.loop_delay = QtCore.QSettings().value( + self.settingsSection + u'/loop delay', + QtCore.QVariant(5)).toInt()[0] self.TimeoutSpinBox.setValue(self.loop_delay) def save(self): - self.config.set_config(u'loop delay', self.loop_delay) - Receiver.send_message(u'update_spin_delay', self.loop_delay) + QtCore.QSettings().setValue(self.settingsSection + u'/loop delay', + QtCore.QVariant(self.loop_delay)) + Receiver.send_message(u'slidecontroller_live_spin_delay', + self.loop_delay) def postSetUp(self): - Receiver.send_message(u'update_spin_delay', self.loop_delay) + Receiver.send_message(u'slidecontroller_live_spin_delay', + self.loop_delay) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 6fbf66022..306664fe3 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -27,8 +27,10 @@ import logging import os from PyQt4 import QtCore, QtGui + from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ - contextMenuAction, ItemCapabilities + contextMenuAction, ItemCapabilities, SettingsManager +from openlp.core.utils import AppLocation log = logging.getLogger(__name__) @@ -47,7 +49,6 @@ class ImageMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.PluginNameShort = u'Image' - self.ConfigSection = title self.IconPath = u'images/image' # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem @@ -59,8 +60,8 @@ class ImageMediaItem(MediaManagerItem): def retranslateUi(self): self.OnNewPrompt = self.trUtf8('Select Image(s)') - self.OnNewFileMasks = \ - self.trUtf8('Images (*.jpg *.jpeg *.gif *.png *.bmp);; All files (*)') + self.OnNewFileMasks = self.trUtf8( + 'Images (*.jpg *.jpeg *.gif *.png *.bmp);; All files (*)') def requiredIcons(self): MediaManagerItem.requiredIcons(self) @@ -76,10 +77,12 @@ class ImageMediaItem(MediaManagerItem): QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setIconSize(QtCore.QSize(88,50)) self.servicePath = os.path.join( - self.parent.config.get_data_path(), u'.thumbnails') + AppLocation.get_section_data_path(self.settingsSection), + u'thumbnails') if not os.path.exists(self.servicePath): os.mkdir(self.servicePath) - self.loadList(self.parent.config.load_list(self.ConfigSection)) + self.loadList(SettingsManager.load_list( + self.settingsSection, self.settingsSection)) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) @@ -112,20 +115,24 @@ class ImageMediaItem(MediaManagerItem): for item in items: text = self.ListView.item(item.row()) try: - os.remove(os.path.join(self.servicePath, unicode(text.text()))) + os.remove( + os.path.join(self.servicePath, unicode(text.text()))) except: #if not present do not worry pass self.ListView.takeItem(item.row()) - self.parent.config.set_list(self.ConfigSection, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def loadList(self, list): for file in list: (path, filename) = os.path.split(unicode(file)) thumb = os.path.join(self.servicePath, filename) if os.path.exists(thumb): - self.validate(file, thumb) - icon = build_icon(thumb) + if self.validate(file, thumb): + icon = build_icon(thumb) + else: + icon = build_icon(u':/general/general_delete.png') else: icon = self.IconFromFile(file, thumb) item_name = QtGui.QListWidgetItem(filename) @@ -140,6 +147,7 @@ class ImageMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) + service_item.add_capability(ItemCapabilities.AllowsAdditions) for item in items: bitem = self.ListView.item(item.row()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index aa1a8f38a..3ba632239 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -29,7 +29,7 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ -ItemCapabilities + ItemCapabilities, SettingsManager, contextMenuAction, Receiver log = logging.getLogger(__name__) @@ -47,12 +47,12 @@ class MediaMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.PluginNameShort = u'Media' self.IconPath = u'images/image' - self.ConfigSection = u'media' - self.ConfigSection = title + self.background = False # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem self.ListViewWithDnD_class = MediaListView - self.PreviewFunction = QtGui.QPixmap(u':/media/media_video.png').toImage() + self.PreviewFunction = QtGui.QPixmap( + u':/media/media_video.png').toImage() MediaManagerItem.__init__(self, parent, icon, title) self.singleServiceItem = False self.ServiceItemIconName = u':/media/media_video.png' @@ -72,6 +72,47 @@ class MediaMediaItem(MediaManagerItem): self.hasNewIcon = False self.hasEditIcon = False + def addListViewToToolBar(self): + MediaManagerItem.addListViewToToolBar(self) + self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) + self.ListView.addAction( + contextMenuAction( + self.ListView, u':/slides/slide_blank.png', + self.trUtf8('Replace Live Background'), + self.onReplaceClick)) + + def addEndHeaderBar(self): + self.ImageWidget = QtGui.QWidget(self) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth( + self.ImageWidget.sizePolicy().hasHeightForWidth()) + self.ImageWidget.setSizePolicy(sizePolicy) + self.ImageWidget.setObjectName(u'ImageWidget') + self.blankButton = self.Toolbar.addToolbarButton( + u'Replace Background', u':/slides/slide_blank.png', + self.trUtf8('Replace Live Background'), self.onReplaceClick, False) + # Add the song widget to the page layout + self.PageLayout.addWidget(self.ImageWidget) + + def onReplaceClick(self): + if self.background: + self.background = False + Receiver.send_message(u'videodisplay_stop') + else: + self.background = True + if not self.ListView.selectedIndexes(): + QtGui.QMessageBox.information(self, + self.trUtf8('No item selected'), + self.trUtf8('You must select one item')) + items = self.ListView.selectedIndexes() + for item in items: + bitem = self.ListView.item(item.row()) + filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) + Receiver.send_message(u'videodisplay_background', filename) + def generateSlideData(self, service_item, item=None): if item is None: item = self.ListView.currentItem() @@ -89,15 +130,16 @@ class MediaMediaItem(MediaManagerItem): self.ListView.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setIconSize(QtCore.QSize(88,50)) - self.loadList(self.parent.config.load_list(self.ConfigSection)) + self.loadList(SettingsManager.load_list( + self.settingsSection, self.settingsSection)) def onDeleteClick(self): item = self.ListView.currentItem() if item: row = self.ListView.row(item) self.ListView.takeItem(row) - self.parent.config.set_list( - self.ConfigSection, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) def loadList(self, list): for file in list: @@ -106,4 +148,4 @@ class MediaMediaItem(MediaManagerItem): img = QtGui.QPixmap(u':/media/media_video.png').toImage() item_name.setIcon(build_icon(img)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) - self.ListView.addItem(item_name) \ No newline at end of file + self.ListView.addItem(item_name) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 92717b6d7..a1a025c02 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -47,7 +47,7 @@ else: from PyQt4 import QtCore -from presentationcontroller import PresentationController, PresentationDocument +from presentationcontroller import PresentationController, PresentationDocument log = logging.getLogger(__name__) @@ -171,13 +171,13 @@ class ImpressController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc OpenOffice') - doc = ImpressDocument(self, name) + doc = ImpressDocument(self, name) self.docs.append(doc) return doc class ImpressDocument(PresentationDocument): - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation OpenOffice') self.controller = controller self.document = None diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 79c8600f0..9c654b198 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -28,7 +28,9 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, BaseListWithDnD +from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ + SettingsManager +from openlp.core.utils import AppLocation from openlp.plugins.presentations.lib import MessageListener log = logging.getLogger(__name__) @@ -50,7 +52,6 @@ class PresentationMediaItem(MediaManagerItem): def __init__(self, parent, icon, title, controllers): self.controllers = controllers self.PluginNameShort = u'Presentation' - self.ConfigSection = title self.IconPath = u'presentations/presentation' self.Automatic = u'' # this next is a class, not an instance of a class - it will @@ -68,7 +69,8 @@ class PresentationMediaItem(MediaManagerItem): fileType = u'' for controller in self.controllers: if self.controllers[controller].enabled: - types = self.controllers[controller].supports + self.controllers[controller].alsosupports + types = self.controllers[controller].supports + \ + self.controllers[controller].alsosupports for type in types: if fileType.find(type) == -1: fileType += u'*%s ' % type @@ -103,7 +105,14 @@ class PresentationMediaItem(MediaManagerItem): self.PageLayout.addWidget(self.PresentationWidget) def initialise(self): - list = self.parent.config.load_list(u'presentations') + self.servicePath = os.path.join( + AppLocation.get_section_data_path(self.settingsSection), + u'thumbnails') + self.ListView.setIconSize(QtCore.QSize(88,50)) + if not os.path.exists(self.servicePath): + os.mkdir(self.servicePath) + list = SettingsManager.load_list( + self.settingsSection, u'presentations') self.loadList(list) for item in self.controllers: #load the drop down selection @@ -128,8 +137,32 @@ class PresentationMediaItem(MediaManagerItem): 'A presentation with that filename already exists.'), QtGui.QMessageBox.Ok) else: + icon = None + for controller in self.controllers: + thumbPath = os.path.join( + AppLocation.get_section_data_path( + self.settingsSection), + u'thumbnails', controller, filename) + thumb = os.path.join(thumbPath, u'slide1.png') + preview = os.path.join( + AppLocation.get_section_data_path( + self.settingsSection), + controller, u'thumbnails', filename, u'slide1.png') + if os.path.exists(preview): + if os.path.exists(thumb): + if self.validate(preview, thumb): + icon = build_icon(thumb) + else: + icon = build_icon( + u':/general/general_delete.png') + else: + os.makedirs(thumbPath) + icon = self.IconFromFile(preview, thumb) + if not icon: + icon = build_icon(u':/general/general_delete.png') item_name = QtGui.QListWidgetItem(filename) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) + item_name.setIcon(icon) self.ListView.addItem(item_name) def onDeleteClick(self): @@ -137,8 +170,8 @@ class PresentationMediaItem(MediaManagerItem): if item: row = self.ListView.row(item) self.ListView.takeItem(row) - self.parent.config.set_list( - self.ConfigSection, self.getFileList()) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) filepath = unicode((item.data(QtCore.Qt.UserRole)).toString()) #not sure of this has errors #John please can you look at . @@ -154,26 +187,29 @@ class PresentationMediaItem(MediaManagerItem): service_item.title = unicode(self.DisplayTypeComboBox.currentText()) service_item.shortname = unicode(self.DisplayTypeComboBox.currentText()) shortname = service_item.shortname - for item in items: - bitem = self.ListView.item(item.row()) - filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) - if shortname == self.Automatic: - service_item.shortname = self.findControllerByType(filename) - if not service_item.shortname: - return False - controller = self.controllers[service_item.shortname] - (path, name) = os.path.split(filename) - doc = controller.add_doc(filename) - if doc.get_slide_preview_file(1) is None: - doc.load_presentation() - i = 1 - img = doc.get_slide_preview_file(i) - while img: - service_item.add_from_command(path, name, img) - i = i + 1 + if shortname: + for item in items: + bitem = self.ListView.item(item.row()) + filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) + if shortname == self.Automatic: + service_item.shortname = self.findControllerByType(filename) + if not service_item.shortname: + return False + controller = self.controllers[service_item.shortname] + (path, name) = os.path.split(filename) + doc = controller.add_doc(filename) + if doc.get_slide_preview_file(1) is None: + doc.load_presentation() + i = 1 img = doc.get_slide_preview_file(i) - doc.close_presentation() - return True + while img: + service_item.add_from_command(path, name, img) + i = i + 1 + img = doc.get_slide_preview_file(i) + doc.close_presentation() + return True + else: + return False def findControllerByType(self, filename): filetype = os.path.splitext(filename)[1] diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 39717d42d..b15f25642 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -44,7 +44,7 @@ class Controller(object): self.doc = None log.info(u'%s controller loaded' % live) - def addHandler(self, controller, file, isBlank): + def addHandler(self, controller, file, isBlank): log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) self.controller = controller if self.doc is not None: @@ -55,7 +55,7 @@ class Controller(object): self.doc.start_presentation() if isBlank: self.blank() - Receiver.send_message(u'live_slide_hide') + Receiver.send_message(u'maindisplay_hide') self.doc.slidenumber = 0 def activate(self): @@ -144,7 +144,7 @@ class Controller(object): """ log.debug(u'Live = %s, shutdown' % self.isLive) if self.isLive: - Receiver.send_message(u'live_slide_show') + Receiver.send_message(u'maindisplay_show') self.doc.close_presentation() self.doc = None #self.doc.slidenumber = 0 @@ -165,7 +165,8 @@ class Controller(object): if not self.isLive: return self.activate() - if self.doc.slidenumber and self.doc.slidenumber != self.doc.get_slide_number(): + if self.doc.slidenumber and \ + self.doc.slidenumber != self.doc.get_slide_number(): self.doc.goto_slide(self.doc.slidenumber) self.doc.unblank_screen() @@ -205,91 +206,88 @@ class MessageListener(object): QtCore.SIGNAL(u'presentations_unblank'), self.unblank) self.timer = QtCore.QTimer() self.timer.setInterval(500) - QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.timeout) + QtCore.QObject.connect( + self.timer, QtCore.SIGNAL("timeout()"), self.timeout) def startup(self, message): """ Start of new presentation Save the handler as any new presentations start here """ + isLive, item = self.decode_message(message) log.debug(u'Startup called with message %s' % message) - self.handler, file, isLive, isBlank = self.decodeMessage(message) + isBlank = message[2] + file = os.path.join(item.get_frame_path(), + item.get_frame_title()) + self.handler = item.title if self.handler == self.mediaitem.Automatic: self.handler = self.mediaitem.findControllerByType(file) if not self.handler: return - if isLive: controller = self.liveHandler else: controller = self.previewHandler controller.addHandler(self.controllers[self.handler], file, isBlank) - def slide(self, message): - slide, live = self.splitMessage(message) - if live: - self.liveHandler.slide(slide, live) + def decode_message(self, message): + if len(message) == 3: + return message[1], message[0], message[2] else: - self.previewHandler.slide(slide, live) + return message[1], message[0] - def first(self, isLive): + def slide(self, message): + isLive, item, slide = self.decode_message(message) + if isLive: + self.liveHandler.slide(slide, isLive) + else: + self.previewHandler.slide(slide, isLive) + + def first(self, message): + isLive, item = self.decode_message(message) if isLive: self.liveHandler.first() else: self.previewHandler.first() - def last(self, isLive): + def last(self, message): + isLive, item = self.decode_message(message) if isLive: self.liveHandler.last() else: self.previewHandler.last() - def next(self, isLive): + def next(self, message): + isLive, item = self.decode_message(message) if isLive: self.liveHandler.next() else: self.previewHandler.next() - def previous(self, isLive): + def previous(self, message): + isLive, item = self.decode_message(message) if isLive: self.liveHandler.previous() else: self.previewHandler.previous() - def shutdown(self, isLive): + def shutdown(self, message): + isLive, item = self.decode_message(message) if isLive: + Receiver.send_message(u'maindisplay_show') self.liveHandler.shutdown() - Receiver.send_message(u'live_slide_show') else: self.previewHandler.shutdown() - def blank(self): - self.liveHandler.blank() + def blank(self, message): + isLive, item = self.decode_message(message) + if isLive: + self.liveHandler.blank() - def unblank(self): - self.liveHandler.unblank() - - def splitMessage(self, message): - """ - Splits the selection messages - into it's component parts - - ``message`` - Message containing Presentaion handler name and file to be presented. - """ - bits = message.split(u':') - return bits[0], bits[1] - - def decodeMessage(self, message): - """ - Splits the initial message from the SlideController - into it's component parts - - ``message`` - Message containing Presentaion handler name and file to be presented. - """ - file = os.path.join(message[1], message[2]) - return message[0], file, message[4], message[5] + def unblank(self, message): + isLive, item = self.decode_message(message) + if isLive: + self.liveHandler.unblank() def timeout(self): self.liveHandler.poll() diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 67870574d..3ea95f509 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -31,7 +31,7 @@ if os.name == u'nt': import _winreg import win32ui -from presentationcontroller import PresentationController, PresentationDocument +from presentationcontroller import PresentationController, PresentationDocument log = logging.getLogger(__name__) @@ -62,7 +62,8 @@ class PowerpointController(PresentationController): log.debug(u'check_available') if os.name == u'nt': try: - _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close() + _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + u'PowerPoint.Application').Close() return True except: pass @@ -96,13 +97,13 @@ class PowerpointController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc PowerPoint') - doc = PowerpointDocument(self, name) + doc = PowerpointDocument(self, name) self.docs.append(doc) return doc class PowerpointDocument(PresentationDocument): - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation Powerpoint') self.presentation = None self.controller = controller diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 455e1c601..e45fac45f 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -82,7 +82,8 @@ class PptviewController(PresentationController): if self.process: return log.debug(u'start PPTView') - self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') + self.process = cdll.LoadLibrary( + r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') def kill(self): """ @@ -94,13 +95,12 @@ class PptviewController(PresentationController): def add_doc(self, name): log.debug(u'Add Doc PPTView') - doc = PptviewDocument(self, name) + doc = PptviewDocument(self, name) self.docs.append(doc) return doc class PptviewDocument(PresentationDocument): - - def __init__(self, controller, presentation): + def __init__(self, controller, presentation): log.debug(u'Init Presentation PowerPoint') self.presentation = None self.pptid = None diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 389744b0b..84a3d83a2 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -30,6 +30,7 @@ import shutil from PyQt4 import QtCore from openlp.core.lib import Receiver +from openlp.core.utils import AppLocation log = logging.getLogger(__name__) @@ -68,7 +69,8 @@ class PresentationController(object): Called at system exit to clean up any running presentations ``check_available()`` - Returns True if presentation application is installed/can run on this machine + Returns True if presentation application is installed/can run on this + machine ``presentation_deleted()`` Deletes presentation specific files, e.g. thumbnails @@ -78,13 +80,14 @@ class PresentationController(object): def __init__(self, plugin=None, name=u'PresentationController'): """ - This is the constructor for the presentationcontroller object. - This provides an easy way for descendent plugins to populate common data. + This is the constructor for the presentationcontroller object. This + provides an easy way for descendent plugins to populate common data. This method *must* be overridden, like so:: class MyPresentationController(PresentationController): def __init__(self, plugin): - PresentationController.__init(self, plugin, u'My Presenter App') + PresentationController.__init( + self, plugin, u'My Presenter App') ``plugin`` Defaults to *None*. The presentationplugin object @@ -97,13 +100,16 @@ class PresentationController(object): self.docs = [] self.plugin = plugin self.name = name + self.settingsSection = self.plugin.settingsSection self.available = self.check_available() if self.available: - self.enabled = int(plugin.config.get_config( - name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked + self.enabled = QtCore.QSettings().value( + self.settingsSection + u'/' + name, + QtCore.Qt.Unchecked).toInt()[0] == QtCore.Qt.Checked else: self.enabled = False - self.thumbnailroot = os.path.join(plugin.config.get_data_path(), + self.thumbnailroot = os.path.join( + AppLocation.get_section_data_path(self.settingsSection), name, u'thumbnails') self.thumbnailprefix = u'slide' if not os.path.isdir(self.thumbnailroot): @@ -204,7 +210,7 @@ class PresentationDocument(object): Returns a path to an image containing a preview for the requested slide """ - def __init__(self, controller, name): + def __init__(self, controller, name): self.slidenumber = 0 self.controller = controller self.store_filename(name) @@ -237,11 +243,12 @@ class PresentationDocument(object): if not os.path.isdir(self.thumbnailpath): os.mkdir(self.thumbnailpath) - def get_file_name(self, presentation): + def get_file_name(self, presentation): return os.path.split(presentation)[1] - def get_thumbnail_path(self, presentation): - return os.path.join(self.controller.thumbnailroot, self.get_file_name(presentation)) + def get_thumbnail_path(self, presentation): + return os.path.join( + self.controller.thumbnailroot, self.get_file_name(presentation)) def check_thumbnails(self): """ @@ -326,11 +333,11 @@ class PresentationDocument(object): pass def next_step(self): - """ - Triggers the next effect of slide on the running presentation - This might be the next animation on the current slide, or the next slide - """ - pass + """ + Triggers the next effect of slide on the running presentation + This might be the next animation on the current slide, or the next slide + """ + pass def previous_step(self): """ @@ -361,7 +368,7 @@ class PresentationDocument(object): prefix = u'live' else: prefix = u'preview' - Receiver.send_message(u'%s_slidecontroller_change' % prefix, + Receiver.send_message(u'slidecontroller_%s_change' % prefix, self.slidenumber - 1) def get_slide_text(self, slide_no): diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index cf18359b1..ebcbb3d7b 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -23,7 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from PyQt4 import QtGui +from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab @@ -31,9 +31,9 @@ class PresentationTab(SettingsTab): """ PresentationsTab is the Presentations settings tab in the settings dialog. """ - def __init__(self, title, controllers, section=None): + def __init__(self, title, controllers): self.controllers = controllers - SettingsTab.__init__(self, title, section) + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'PresentationTab') @@ -93,19 +93,21 @@ class PresentationTab(SettingsTab): controller = self.controllers[key] checkbox = self.PresenterCheckboxes[controller.name] checkbox.setText( - u'%s %s:' % (controller.name, self.trUtf8('available'))) + u'%s %s' % (controller.name, self.trUtf8('available'))) def load(self): for key in self.controllers: controller = self.controllers[key] if controller.available: checkbox = self.PresenterCheckboxes[controller.name] - checkbox.setChecked( - int(self.config.get_config(controller.name, 0))) + checkbox.setChecked(QtCore.QSettings().value( + self.settingsSection + u'/' + controller.name, + QtCore.QVariant(0)).toInt()[0]) def save(self): for key in self.controllers: controller = self.controllers[key] checkbox = self.PresenterCheckboxes[controller.name] - self.config.set_config( - controller.name, unicode(checkbox.checkState())) + QtCore.QSettings().setValue( + self.settingsSection + u'/' + controller.name, + QtCore.QVariant(checkbox.checkState())) diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 00a83fe4b..dd1a5259b 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -26,7 +26,7 @@ import os import logging -from openlp.core.lib import Plugin, build_icon, Receiver, PluginStatus +from openlp.core.lib import Plugin, build_icon, PluginStatus from openlp.core.utils import AppLocation from openlp.plugins.presentations.lib import * @@ -53,15 +53,10 @@ class PresentationPlugin(Plugin): log.info(u'Presentations Initialising') Plugin.initialise(self) self.insert_toolbox_item() - presentation_types = [] for controller in self.controllers: if self.controllers[controller].enabled: - presentation_types.append({u'%s' % controller : self.controllers[controller].supports}) self.controllers[controller].start_process() - Receiver.send_message( - u'presentation types', presentation_types) - def finalise(self): log.info(u'Plugin Finalise') #Ask each controller to tidy up @@ -101,7 +96,9 @@ class PresentationPlugin(Plugin): try: __import__(modulename, globals(), locals(), []) except ImportError, e: - log.error(u'Failed to import %s on path %s for reason %s', modulename, path, e.args[0]) + log.error( + u'Failed to import %s on path %s for reason %s', + modulename, path, e.args[0]) controller_classes = PresentationController.__subclasses__() for controller_class in controller_classes: controller = controller_class(self) diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html new file mode 100644 index 000000000..25b08fd43 --- /dev/null +++ b/openlp/plugins/remotes/html/index.html @@ -0,0 +1,117 @@ + + +OpenLP Controller + + + +

OpenLP Controller

+ + +
+ + +
+ + +
+ + +
+ +
+
+ +
+
+ OpenLP website + + + diff --git a/openlp/plugins/remotes/lib/__init__.py b/openlp/plugins/remotes/lib/__init__.py index bb613fb53..9307a0f51 100644 --- a/openlp/plugins/remotes/lib/__init__.py +++ b/openlp/plugins/remotes/lib/__init__.py @@ -24,3 +24,4 @@ ############################################################################### from remotetab import RemoteTab +from httpserver import HttpServer diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py new file mode 100644 index 000000000..2c4105dab --- /dev/null +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # +# Thompson, Jon Tibble, Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +import logging +import os +import json +import urlparse + +from PyQt4 import QtCore, QtNetwork + +from openlp.core.lib import Receiver +from openlp.core.utils import AppLocation + +log = logging.getLogger(__name__) + +class HttpServer(object): + """ + Ability to control OpenLP via a webbrowser + e.g. http://localhost:4316/send/slidecontroller_live_next + http://localhost:4316/send/alerts_text?q=your%20alert%20text + """ + def __init__(self, parent): + """ + Initialise the httpserver, and start the server + """ + log.debug(u'Initialise httpserver') + self.parent = parent + self.html_dir = os.path.join( + AppLocation.get_directory(AppLocation.PluginsDir), + u'remotes', u'html') + self.connections = [] + self.current_item = None + self.current_slide = None + self.start_tcp() + + def start_tcp(self): + """ + Start the http server, use the port in the settings default to 4316 + Listen out for slide and song changes so they can be broadcast to + clients. Listen out for socket connections + """ + log.debug(u'Start TCP server') + port = QtCore.QSettings().value( + self.parent.settingsSection + u'/remote port', + QtCore.QVariant(4316)).toInt()[0] + self.server = QtNetwork.QTcpServer() + self.server.listen(QtNetwork.QHostAddress(QtNetwork.QHostAddress.Any), + port) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_live_changed'), + self.slide_change) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'slidecontroller_live_started'), + self.item_change) + QtCore.QObject.connect(self.server, + QtCore.SIGNAL(u'newConnection()'), self.new_connection) + log.debug(u'TCP listening on port %d' % port) + + def slide_change(self, row): + """ + Slide change listener. Store the item and tell the clients + """ + self.current_slide = row + self.send_poll() + + def item_change(self, items): + """ + Item (song) change listener. Store the slide and tell the clients + """ + self.current_item = items[0].title + self.send_poll() + + def send_poll(self): + """ + Tell the clients something has changed + """ + Receiver.send_message(u'remotes_poll_response', + {'slide': self.current_slide, + 'item': self.current_item}) + + def new_connection(self): + """ + A new http connection has been made. Create a client object to handle + communication + """ + log.debug(u'new http connection') + socket = self.server.nextPendingConnection() + if socket: + self.connections.append(HttpConnection(self, socket)) + + def close_connection(self, connection): + """ + The connection has been closed. Clean up + """ + log.debug(u'close http connection') + self.connections.remove(connection) + + def close(self): + """ + Close down the http server + """ + log.debug(u'close http server') + self.server.close() + +class HttpConnection(object): + """ + A single connection, this handles communication between the server + and the client + """ + def __init__(self, parent, socket): + """ + Initialise the http connection. Listen out for socket signals + """ + log.debug(u'Initialise HttpConnection: %s' % + socket.peerAddress().toString()) + self.socket = socket + self.parent = parent + QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'), + self.ready_read) + QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'), + self.disconnected) + + def ready_read(self): + """ + Data has been sent from the client. Respond to it + """ + log.debug(u'ready to read socket') + if self.socket.canReadLine(): + data = unicode(self.socket.readLine()) + log.debug(u'received: ' + data) + words = data.split(u' ') + html = None + if words[0] == u'GET': + url = urlparse.urlparse(words[1]) + params = self.load_params(url.query) + folders = url.path.split(u'/') + if folders[1] == u'': + html = self.serve_file(u'') + elif folders[1] == u'files': + html = self.serve_file(folders[2]) + elif folders[1] == u'send': + html = self.process_event(folders[2], params) + elif folders[1] == u'request': + if self.process_request(folders[2], params): + return + if html: + html = self.get_200_ok() + html + u'\n' + else: + html = self.get_404_not_found() + self.socket.write(html) + self.close() + + def serve_file(self, filename): + """ + Send a file to the socket. For now, just .html files + and must be top level inside the html folder. + If subfolders requested return 404, easier for security for the present. + + Ultimately for i18n, this could first look for xx/file.html before + falling back to file.html... where xx is the language, e.g. 'en' + """ + log.debug(u'serve file request %s' % filename) + if not filename: + filename = u'index.html' + if os.path.basename(filename) != filename: + return None + (fileroot, ext) = os.path.splitext(filename) + if ext != u'.html': + return None + path = os.path.join(self.parent.html_dir, filename) + try: + f = open(path, u'rb') + except: + log.exception(u'Failed to open %s' % path) + return None + log.debug(u'Opened %s' % path) + html = f.read() + f.close() + return html + + def load_params(self, query): + """ + Decode the query string parameters sent from the browser + """ + params = urlparse.parse_qs(query) + if not params: + return None + else: + return params['q'] + + def process_event(self, event, params): + """ + Send a signal to openlp to perform an action. + Currently lets anything through. Later we should restrict and perform + basic parameter checking, otherwise rogue clients could crash openlp + """ + if params: + Receiver.send_message(event, params) + else: + Receiver.send_message(event) + return u'OK' + + def process_request(self, event, params): + """ + Client has requested data. Send the signal and parameters for openlp + to handle, then listen out for a corresponding _request signal + which will have the data to return. + For most event timeout after 10 seconds (i.e. incase the signal + recipient isn't listening) + remotes_poll_request is a special case, this is a ajax long poll which + is just waiting for slide change/song change activity. This can wait + longer (one minute) + """ + if not event.endswith(u'_request'): + return False + self.event = event + response = event.replace(u'_request', u'_response') + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(response), self.process_response) + self.timer = QtCore.QTimer() + self.timer.setSingleShot(True) + QtCore.QObject.connect(self.timer, + QtCore.SIGNAL(u'timeout()'), self.timeout) + if event == 'remotes_poll_request': + self.timer.start(60000) + else: + self.timer.start(10000) + if params: + Receiver.send_message(event, params) + else: + Receiver.send_message(event) + return True + + def process_response(self, data): + """ + The recipient of a _request signal has sent data. Convert this to + json and return it to client + """ + if not self.socket: + return + self.timer.stop() + html = json.dumps(data) + html = self.get_200_ok() + html + u'\n' + self.socket.write(html) + self.close() + + def get_200_ok(self): + """ + Successful request. Send OK headers. Assume html for now. + """ + return u'HTTP/1.1 200 OK\r\n' + \ + u'Content-Type: text/html; charset="utf-8"\r\n' + \ + u'\r\n' + + def get_404_not_found(self): + """ + Invalid url. Say so + """ + return u'HTTP/1.1 404 Not Found\r\n'+ \ + u'Content-Type: text/html; charset="utf-8"\r\n' + \ + u'\r\n' + + def get_408_timeout(self): + """ + A _request hasn't returned anything in the timeout period. + Return timeout + """ + return u'HTTP/1.1 408 Request Timeout\r\n' + + def timeout(self): + """ + Listener for timeout signal + """ + if not self.socket: + return + html = self.get_408_timeout() + self.socket.write(html) + self.close() + + def disconnected(self): + """ + The client has disconnected. Tidy up + """ + log.debug(u'socket disconnected') + self.close() + + def close(self): + """ + The server has closed the connection. Tidy up + """ + if not self.socket: + return + log.debug(u'close socket') + self.socket.close() + self.socket = None + self.parent.close_connection(self) + diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index 31af42ff2..abdda065f 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -23,7 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from PyQt4 import QtGui +from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab @@ -31,8 +31,8 @@ class RemoteTab(SettingsTab): """ RemoteTab is the Remotes settings tab in the settings dialog. """ - def __init__(self, title, section=None): - SettingsTab.__init__(self, title, section) + def __init__(self, title): + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'RemoteTab') @@ -57,8 +57,9 @@ class RemoteTab(SettingsTab): def load(self): self.RemotePortSpinBox.setValue( - int(self.config.get_config(u'remote port', 4316))) + QtCore.QSettings().value(self.settingsSection + u'/remote port', + QtCore.QVariant(4316)).toInt()[0]) def save(self): - self.config.set_config( - u'remote port', unicode(self.RemotePortSpinBox.value())) + QtCore.QSettings().setValue(self.settingsSection + u'/remote port', + QtCore.QVariant(self.RemotePortSpinBox.value())) diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py index 4e01e43ee..2c632d90d 100644 --- a/openlp/plugins/remotes/remoteplugin.py +++ b/openlp/plugins/remotes/remoteplugin.py @@ -28,7 +28,7 @@ import logging from PyQt4 import QtNetwork, QtCore from openlp.core.lib import Plugin, Receiver -from openlp.plugins.remotes.lib import RemoteTab +from openlp.plugins.remotes.lib import RemoteTab, HttpServer log = logging.getLogger(__name__) @@ -36,20 +36,26 @@ class RemotesPlugin(Plugin): log.info(u'Remote Plugin loaded') def __init__(self, plugin_helpers): + """ + remotes constructor + """ Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers) self.weight = -1 self.server = None def initialise(self): + """ + Initialise the remotes plugin, and start the http server + """ log.debug(u'initialise') Plugin.initialise(self) self.insert_toolbox_item() - self.server = QtNetwork.QUdpSocket() - self.server.bind(int(self.config.get_config(u'remote port', 4316))) - QtCore.QObject.connect(self.server, - QtCore.SIGNAL(u'readyRead()'), self.readData) + self.server = HttpServer(self) def finalise(self): + """ + Tidy up and close down the http server + """ log.debug(u'finalise') self.remove_toolbox_item() if self.server: @@ -60,26 +66,13 @@ class RemotesPlugin(Plugin): Create the settings Tab """ return RemoteTab(self.name) - - def readData(self): - log.info(u'Remoted data has arrived') - while self.server.hasPendingDatagrams(): - datagram, host, port = self.server.readDatagram( - self.server.pendingDatagramSize()) - self.handle_datagram(datagram) - - def handle_datagram(self, datagram): - log.info(u'Sending event %s ', datagram) - pos = datagram.find(u':') - event = unicode(datagram[:pos].lower()) - if event == u'alert': - Receiver.send_message(u'alert_text', unicode(datagram[pos + 1:])) - if event == u'next_slide': - Receiver.send_message(u'live_slide_next') - + def about(self): + """ + Information about this plugin + """ about_text = self.trUtf8('Remote Plugin
This plugin ' 'provides the ability to send messages to a running version of ' - 'openlp on a different computer.
The Primary use for this ' - 'would be to send alerts from a creche') + 'openlp on a different computer via a web browser or other app
' + 'The Primary use for this would be to send alerts from a creche') return about_text diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 2c03d13f6..4c3f78e2f 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -93,7 +93,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): QtCore.QObject.connect(self.CCLNumberEdit, QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'update_themes'), self.loadThemes) + QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) QtCore.QObject.connect(self.CommentsEdit, QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus) QtCore.QObject.connect(self.VerseOrderEdit, @@ -150,8 +150,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def loadBooks(self): books = self.songmanager.get_books() booksCompleter = QtGui.QCompleter( - [book.name for book in books], - self.SongbookCombo) + [book.name for book in books], self.SongbookCombo) booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive); self.SongbookCombo.setCompleter(booksCompleter); self.SongbookCombo.clear() @@ -340,7 +339,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verse_form.setVerse(u'', self.VerseListWidget.count() + 1, True) if self.verse_form.exec_(): afterText, verse, subVerse = self.verse_form.getVerse() - data = u'%s:%s' %(verse, subVerse) + data = u'%s:%s' % (verse, subVerse) item = QtGui.QListWidgetItem(afterText) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data)) item.setText(afterText) @@ -351,11 +350,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if item: tempText = item.text() verseId = unicode((item.data(QtCore.Qt.UserRole)).toString()) - self.verse_form.setVerse(tempText, \ - self.VerseListWidget.count(), True, verseId) + self.verse_form.setVerse( + tempText, self.VerseListWidget.count(), True, verseId) if self.verse_form.exec_(): afterText, verse, subVerse = self.verse_form.getVerse() - data = u'%s:%s' %(verse, subVerse) + data = u'%s:%s' % (verse, subVerse) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data)) item.setText(afterText) #number of lines has change so repaint the list moving the data @@ -484,16 +483,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): log.debug(u'onPreview') if button.text() == unicode(self.trUtf8('Save && Preview')) \ and self.saveSong(): - Receiver.send_message(u'preview_song') + Receiver.send_message(u'songs_preview') def closePressed(self): - Receiver.send_message(u'remote_edit_clear') + Receiver.send_message(u'songs_edit_clear') self.close() def accept(self): log.debug(u'accept') if self.saveSong(): - Receiver.send_message(u'load_song_list') + Receiver.send_message(u'songs_load_list') self.close() def saveSong(self): diff --git a/openlp/plugins/songs/lib/manager.py b/openlp/plugins/songs/lib/manager.py index dcb49bfcd..ff9231fe2 100644 --- a/openlp/plugins/songs/lib/manager.py +++ b/openlp/plugins/songs/lib/manager.py @@ -25,6 +25,9 @@ import logging +from PyQt4 import QtCore + +from openlp.core.utils import AppLocation from openlp.plugins.songs.lib.models import init_models, metadata, Song, \ Author, Topic, Book @@ -37,26 +40,33 @@ class SongManager(): """ log.info(u'Song manager loaded') - def __init__(self, config): + def __init__(self): """ Creates the connection to the database, and creates the tables if they don't exist. """ - self.config = config log.debug(u'Song Initialising') + settings = QtCore.QSettings() + settings.beginGroup(u'songs') self.db_url = u'' - db_type = self.config.get_config(u'db type', u'sqlite') + db_type = unicode( + settings.value(u'songs/db type', u'sqlite').toString()) if db_type == u'sqlite': self.db_url = u'sqlite:///%s/songs.sqlite' % \ - self.config.get_data_path() + AppLocation.get_section_data_path(u'songs') else: - self.db_url = db_type + 'u://' + \ - self.config.get_config(u'db username') + u':' + \ - self.config.get_config(u'db password') + u'@' + \ - self.config.get_config(u'db hostname') + u'/' + \ - self.config.get_config(u'db database') + self.db_url = u'%s://%s:%s@%s/%s' % (db_type, + unicode(settings.value( + u'db username', QtCore.QVariant(u'')).toString()), + unicode(settings.value( + u'db password', QtCore.QVariant(u'')).toString()), + unicode(settings.value( + u'db hostname', QtCore.QVariant(u'')).toString()), + unicode(settings.value( + u'db database', QtCore.QVariant(u'')).toString())) self.session = init_models(self.db_url) metadata.create_all(checkfirst=True) + settings.endGroup() log.debug(u'Song Initialised') def get_songs(self): diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 9b81540e6..040a6b26f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -28,7 +28,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, SongXMLParser, \ - BaseListWithDnD, Receiver, str_to_bool, ItemCapabilities + BaseListWithDnD, Receiver, ItemCapabilities from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm log = logging.getLogger(__name__) @@ -46,7 +46,6 @@ class SongMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.PluginNameShort = u'Song' - self.ConfigSection = title self.IconPath = u'songs/song' self.ListViewWithDnD_class = SongListView MediaManagerItem.__init__(self, parent, icon, title) @@ -122,19 +121,20 @@ class SongMediaItem(MediaManagerItem): QtCore.SIGNAL(u'textChanged(const QString&)'), self.onSearchTextEditChanged) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'load_song_list'), self.onSearchTextButtonClick) + QtCore.SIGNAL(u'songs_load_list'), self.onSearchTextButtonClick) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'preview_song'), self.onPreviewClick) + QtCore.SIGNAL(u'songs_preview'), self.onPreviewClick) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) + QtCore.SIGNAL(u'songs_edit'), self.onRemoteEdit) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) + QtCore.SIGNAL(u'songs_edit_clear'), self.onRemoteEditClear) def configUpdated(self): - self.searchAsYouType = str_to_bool( - self.parent.config.get_config(u'search as type', u'False')) + self.searchAsYouType = QtCore.QSettings().value( + self.settingsSection + u'/search as type', + QtCore.QVariant(u'False')).toBool() def retranslateUi(self): self.SearchTextLabel.setText(self.trUtf8('Search:')) @@ -350,7 +350,7 @@ class SongMediaItem(MediaManagerItem): author_list = author_list + unicode(author.display_name) author_audit.append(unicode(author.display_name)) if song.ccli_number is None or len(song.ccli_number) == 0: - ccli = self.parent.settings.GeneralTab.CCLINumber + ccli = self.parent.settings_form.GeneralTab.CCLINumber else: ccli = unicode(song.ccli_number) raw_footer.append(song.title) diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index 48139931b..9d95cf6b5 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -29,22 +29,19 @@ # http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://wiki.services.openoffice.org/wiki/Python -import re import os -import time -from PyQt4 import QtCore +import re + from songimport import SongImport from oooimport import OooImport if os.name == u'nt': - from win32com.client import Dispatch BOLD = 150.0 ITALIC = 2 PAGE_BEFORE = 4 PAGE_AFTER = 5 PAGE_BOTH = 6 else: - import uno from com.sun.star.awt.FontWeight import BOLD from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index cb780f987..5fe362842 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -24,7 +24,9 @@ ############################################################################### import string -from PyQt4 import QtGui, QtCore + +from PyQt4 import QtGui + from openlp.core.lib import SongXMLBuilder from openlp.plugins.songs.lib.models import Song, Author, Topic, Book diff --git a/openlp/plugins/songs/lib/songstab.py b/openlp/plugins/songs/lib/songstab.py index 392b15691..38bdd791d 100644 --- a/openlp/plugins/songs/lib/songstab.py +++ b/openlp/plugins/songs/lib/songstab.py @@ -25,14 +25,14 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import SettingsTab, str_to_bool +from openlp.core.lib import SettingsTab class SongsTab(SettingsTab): """ SongsTab is the Songs settings tab in the settings dialog. """ - def __init__(self, title, section=None): - SettingsTab.__init__(self, title, section) + def __init__(self, title): + SettingsTab.__init__(self, title) def setupUi(self): self.setObjectName(u'SongsTab') @@ -63,9 +63,9 @@ class SongsTab(SettingsTab): def retranslateUi(self): self.SongsModeGroupBox.setTitle(self.trUtf8('Songs Mode')) self.SearchAsTypeCheckBox.setText( - self.trUtf8('Enable search as you type:')) + self.trUtf8('Enable search as you type')) self.SongBarActiveCheckBox.setText( - self.trUtf8('Display Verses on Live Tool bar:')) + self.trUtf8('Display Verses on Live Tool bar')) def onSearchAsTypeCheckBoxChanged(self, check_state): self.song_search = False @@ -80,13 +80,19 @@ class SongsTab(SettingsTab): self.song_bar = True def load(self): - self.song_search = str_to_bool( - self.config.get_config(u'search as type', False)) - self.song_bar = str_to_bool( - self.config.get_config(u'display songbar', True)) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + self.song_search = settings.value( + u'search as type', QtCore.QVariant(False)).toBool() + self.song_bar = settings.value( + u'display songbar', QtCore.QVariant(True)).toBool() self.SearchAsTypeCheckBox.setChecked(self.song_search) self.SongBarActiveCheckBox.setChecked(self.song_bar) + settings.endGroup() def save(self): - self.config.set_config(u'search as type', unicode(self.song_search)) - self.config.set_config(u'display songbar', unicode(self.song_bar)) + settings = QtCore.QSettings() + settings.beginGroup(self.settingsSection) + settings.setValue(u'search as type', QtCore.QVariant(self.song_search)) + settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar)) + settings.endGroup() diff --git a/openlp/plugins/songs/lib/songxml.py b/openlp/plugins/songs/lib/songxml.py index 71506ff2d..2dc55ff7d 100644 --- a/openlp/plugins/songs/lib/songxml.py +++ b/openlp/plugins/songs/lib/songxml.py @@ -137,7 +137,7 @@ class _OpenSong(XmlRootClass): newtag = "Pre-chorus" else: newtag = t - s = (u'# %s %s'%(newtag, c)).rstrip() + s = (u'# %s %s' % (newtag, c)).rstrip() res.append(s) res.append(l[1:]) if (len(l) == 0) and (not tagPending): diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index cd3470e86..af05b4605 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -51,7 +51,7 @@ class SongsPlugin(Plugin): """ Plugin.__init__(self, u'Songs', u'1.9.1', plugin_helpers) self.weight = -10 - self.songmanager = SongManager(self.config) + self.songmanager = SongManager() self.openlp_import_form = OpenLPImportForm() self.opensong_import_form = OpenSongImportForm() self.openlp_export_form = OpenLPExportForm() @@ -65,7 +65,7 @@ class SongsPlugin(Plugin): def initialise(self): log.info(u'Songs Initialising') #if self.songmanager is None: - # self.songmanager = SongManager(self.config) + # self.songmanager = SongManager() Plugin.initialise(self) self.insert_toolbox_item() self.ImportSongMenu.menuAction().setVisible(True) @@ -212,7 +212,7 @@ class SongsPlugin(Plugin): + ' included with the Songs of Fellowship Music Editions'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) - Receiver.send_message(u'load_song_list') + Receiver.send_message(u'songs_load_list') def onImportOooItemClick(self): filenames = QtGui.QFileDialog.getOpenFileNames( @@ -220,7 +220,7 @@ class SongsPlugin(Plugin): u'', u'All Files(*.*)') oooimport = OooImport(self.songmanager) oooimport.import_docs(filenames) - Receiver.send_message(u'load_song_list') + Receiver.send_message(u'songs_load_list') def onExportOpenlp1ItemClicked(self): self.openlp_export_form.show() diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index 4e4f9bb55..31971f465 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -23,10 +23,12 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import logging import os from PyQt4 import QtCore, QtGui -import logging + +from openlp.core.lib import SettingsManager from songusagedetaildialog import Ui_SongUsageDetailDialog @@ -53,15 +55,16 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): fromDate = QtCore.QDate(year - 1, 9, 1) self.FromDate.setSelectedDate(fromDate) self.ToDate.setSelectedDate(toDate) - self.FileLineEdit.setText(self.parent.config.get_last_dir(1)) + self.FileLineEdit.setText( + SettingsManager.get_last_dir(self.parent.settingsSection, 1)) def defineOutputLocation(self): path = QtGui.QFileDialog.getExistingDirectory(self, self.trUtf8('Output File Location'), - self.parent.config.get_last_dir(1) ) + SettingsManager.get_last_dir(self.parent.settingsSection, 1)) path = unicode(path) if path != u'': - self.parent.config.set_last_dir(path, 1) + SettingsManager.set_last_dir(self.parent.settingsSection, path, 1) self.FileLineEdit.setText(path) def accept(self): @@ -86,4 +89,3 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): finally: if file: file.close() - diff --git a/openlp/plugins/songusage/lib/manager.py b/openlp/plugins/songusage/lib/manager.py index 2802570ab..e8816b552 100644 --- a/openlp/plugins/songusage/lib/manager.py +++ b/openlp/plugins/songusage/lib/manager.py @@ -25,7 +25,11 @@ import logging -from openlp.plugins.songusage.lib.models import init_models, metadata, SongUsageItem +from PyQt4 import QtCore + +from openlp.core.utils import AppLocation +from openlp.plugins.songusage.lib.models import init_models, metadata, \ + SongUsageItem log = logging.getLogger(__name__) @@ -36,27 +40,33 @@ class SongUsageManager(): """ log.info(u'SongUsage manager loaded') - def __init__(self, config): + def __init__(self): """ Creates the connection to the database, and creates the tables if they don't exist. """ - self.config = config log.debug(u'SongUsage Initialising') + settings = QtCore.QSettings() + settings.beginGroup(u'songusage') self.db_url = u'' - db_type = self.config.get_config(u'db type', u'sqlite') + db_type = unicode( + settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) if db_type == u'sqlite': self.db_url = u'sqlite:///%s/songusage.sqlite' % \ - self.config.get_data_path() + AppLocation.get_section_data_path(u'songusage') else: - self.db_url = u'%s://%s:%s@%s/%s' % \ - (db_type, self.config.get_config(u'db username'), - self.config.get_config(u'db password'), - self.config.get_config(u'db hostname'), - self.config.get_config(u'db database')) + self.db_url = u'%s://%s:%s@%s/%s' % (db_type, + unicode(settings.value(u'db username', + QtCore.QVariant(u'')).toString()), + unicode(settings.value(u'db password', + QtCore.QVariant(u'')).toString()), + unicode(settings.value(u'db hostname', + QtCore.QVariant(u'')).toString()), + unicode(settings.value(u'db database', + QtCore.QVariant(u'')).toString())) self.session = init_models(self.db_url) metadata.create_all(checkfirst=True) - + settings.endGroup() log.debug(u'SongUsage Initialised') def get_all_songusage(self, start_date, end_date): diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 0763e0675..10899914c 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -28,9 +28,10 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, Receiver, str_to_bool, build_icon +from openlp.core.lib import Plugin, Receiver, build_icon from openlp.plugins.songusage.lib import SongUsageManager -from openlp.plugins.songusage.forms import SongUsageDetailForm, SongUsageDeleteForm +from openlp.plugins.songusage.forms import SongUsageDetailForm, \ + SongUsageDeleteForm from openlp.plugins.songusage.lib.models import SongUsageItem log = logging.getLogger(__name__) @@ -107,12 +108,14 @@ class SongUsagePlugin(Plugin): log.info(u'SongUsage Initialising') Plugin.initialise(self) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'songusage_live'), self.onReceiveSongUsage) - self.SongUsageActive = str_to_bool( - self.config.get_config(u'active', False)) + QtCore.SIGNAL(u'songs_live_started'), + self.onReceiveSongUsage) + self.SongUsageActive = QtCore.QSettings().value( + self.settingsSection + u'/active', + QtCore.QVariant(False)).toBool() self.SongUsageStatus.setChecked(self.SongUsageActive) if self.songusagemanager is None: - self.songusagemanager = SongUsageManager(self.config) + self.songusagemanager = SongUsageManager() self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager) self.SongUsagedetailform = SongUsageDetailForm(self) self.SongUsageMenu.menuAction().setVisible(True) @@ -125,23 +128,25 @@ class SongUsagePlugin(Plugin): def toggleSongUsageState(self): self.SongUsageActive = not self.SongUsageActive - self.config.set_config(u'active', self.SongUsageActive) + QtCore.QSettings().setValue(self.settingsSection + u'/active', + QtCore.QVariant(self.SongUsageActive)) - def onReceiveSongUsage(self, SongUsageData): + def onReceiveSongUsage(self, items): """ SongUsage a live song from SlideController """ - if self.SongUsageActive: - SongUsageitem = SongUsageItem() - SongUsageitem.usagedate = datetime.today() - SongUsageitem.usagetime = datetime.now().time() - SongUsageitem.title = SongUsageData[0] - SongUsageitem.copyright = SongUsageData[2] - SongUsageitem.ccl_number = SongUsageData[3] - SongUsageitem.authors = u'' - for author in SongUsageData[1]: - SongUsageitem.authors += author + u' ' - self.songusagemanager.insert_songusage(SongUsageitem) + audit = items[0].audit + if self.SongUsageActive and audit: + song_usage_item = SongUsageItem() + song_usage_item.usagedate = datetime.today() + song_usage_item.usagetime = datetime.now().time() + song_usage_item.title = audit[0] + song_usage_item.copyright = audit[2] + song_usage_item.ccl_number = audit[3] + song_usage_item.authors = u'' + for author in audit[1]: + song_usage_item.authors += author + u' ' + self.songusagemanager.insert_songusage(song_usage_item) def onSongUsageDelete(self): self.SongUsagedeleteform.exec_() diff --git a/openlpcnv.pyw b/openlpcnv.pyw index 5d0ff62d0..f0c2748f0 100755 --- a/openlpcnv.pyw +++ b/openlpcnv.pyw @@ -35,6 +35,7 @@ if os.name == u'nt': import win32con from win32com.client import Dispatch +from openlp.core.utils import AppLocation from openlp.migration.display import * from openlp.migration.migratefiles import * from openlp.migration.migratebibles import * @@ -103,8 +104,10 @@ class Migration(object): def convert_sqlite2_to_3(self, olddb, newdb): print u'Converting sqlite2 ' + olddb + ' to sqlite3 ' + newdb if os.name == u'nt': - # we can't make this a raw unicode string as the \U within it causes much confusion - hKey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, u'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SQLite ODBC Driver') + # we can't make this a raw unicode string as the \U within it + # causes much confusion + hKey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, + u'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SQLite ODBC Driver') value, type = win32api.RegQueryValueEx (hKey, u'UninstallString') sqlitepath, temp = os.path.split(value) sqliteexe = os.path.join(sqlitepath, u'sqlite.exe') @@ -133,10 +136,8 @@ class Migration(object): if __name__ == u'__main__': mig = Migration() - songconfig = PluginConfig(u'Songs') - newsongpath = songconfig.get_data_path() - bibleconfig = PluginConfig(u'Bibles') - newbiblepath = bibleconfig.get_data_path() + newsongpath = AppLocation.get_section_data_path(u'songs') + newbiblepath = AppLocation.get_section_data_path(u'bibles') if os.name == u'nt': if not os.path.isdir(newsongpath): os.makedirs(newsongpath) diff --git a/resources/forms/alertdialog.ui b/resources/forms/alertdialog.ui index fd4cee5fc..725fb7c4e 100644 --- a/resources/forms/alertdialog.ui +++ b/resources/forms/alertdialog.ui @@ -98,7 +98,7 @@ &New - + :/general/general_new.png:/general/general_new.png @@ -112,29 +112,18 @@ &Save - + :/general/general_save.png:/general/general_save.png - - - - &Edit - - - - :/general/general_edit.png:/general/general_edit.png - - - &Delete - + :/general/general_delete.png:/general/general_delete.png @@ -180,7 +169,7 @@ Displ&ay - + :/general/general_live.png:/general/general_live.png @@ -191,7 +180,7 @@ Display && Cl&ose - + :/general/general_live.png:/general/general_live.png @@ -202,7 +191,7 @@ &Close - + :/system/system_close.png:/system/system_close.png @@ -217,15 +206,12 @@ AlertListWidget NewButton SaveButton - EditButton DeleteButton DisplayButton DisplayCloseButton CloseButton - - - + CloseButton diff --git a/resources/forms/displaytab.ui b/resources/forms/displaytab.ui new file mode 100644 index 000000000..7d2d78798 --- /dev/null +++ b/resources/forms/displaytab.ui @@ -0,0 +1,295 @@ + + + DisplaysDialog + + + + 0 + 0 + 620 + 716 + + + + Amend Display Settings + + + + + 0 + 40 + 241 + 79 + + + + + + + Default Settings + + + + + + + + X + + + Qt::AlignCenter + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + Y + + + Qt::AlignCenter + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + + 100 + 16777215 + + + + Height + + + Qt::AlignCenter + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + Width + + + Qt::AlignCenter + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + + + + 0 + 130 + 248 + 87 + + + + + 500 + 16777215 + + + + Amend Settings + + + + + + + + X + + + Qt::AlignCenter + + + + + + + + 50 + 16777215 + + + + 4 + + + + + + + + + + + Y + + + Qt::AlignCenter + + + + + + + + 50 + 16777215 + + + + 4 + + + + + + + + + + + Height + + + Qt::AlignCenter + + + + + + + + 50 + 16777215 + + + + 4 + + + + + + + + + QLayout::SetMinimumSize + + + + + + 100 + 16777215 + + + + Width + + + Qt::AlignCenter + + + + + + + + 60 + 16777215 + + + + + + + + layoutWidget + YAmendLabel + HeightAmendLabel + WidthAmendLabel + YAmendLabel + + + + + 0 + 10 + 191 + 23 + + + + Override Output Display + + + + + + diff --git a/resources/pyinstaller/hook-lxml.objectify.py b/resources/pyinstaller/hook-lxml.objectify.py index 071a0dca4..9d83432df 100644 --- a/resources/pyinstaller/hook-lxml.objectify.py +++ b/resources/pyinstaller/hook-lxml.objectify.py @@ -1 +1 @@ -hiddenimports = ['lxml.etree'] +hiddenimports = ['lxml.etree'] diff --git a/scripts/openlp-remoteclient.py b/scripts/openlp-remoteclient.py index de3099920..3ff7ccc05 100755 --- a/scripts/openlp-remoteclient.py +++ b/scripts/openlp-remoteclient.py @@ -24,34 +24,33 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -import socket +import urllib import sys from optparse import OptionParser -def sendData(options, message): - addr = (options.address, options.port) +def sendData(options): + addr = 'http://%s:%s/send/%s?q=%s' % (options.address, options.port, + options.event, options.message) try: - UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) - UDPSock.sendto(message, addr) - print u'message sent ', message, addr + urllib.urlopen(addr) + print u'Message sent ', addr except: - print u'Errow thrown ', sys.exc_info()[1] - -def format_message(options): - return u'%s:%s' % (u'alert', options.message) + print u'Error thrown ', sys.exc_info()[1] def main(): - usage = "usage: %prog [options] arg1 arg2" + usage = "usage: %prog [-a address] [-p port] [-e event] [-m message]" parser = OptionParser(usage=usage) - parser.add_option("-v", "--verbose", - action="store_true", dest="verbose", default=True, - help="make lots of noise [%default]") parser.add_option("-p", "--port", default=4316, help="IP Port number %default ") parser.add_option("-a", "--address", - help="Recipient address ") + help="Recipient address ", + default="localhost") + parser.add_option("-e", "--event", + help="Action to be performed", + default="alerts_text") parser.add_option("-m", "--message", - help="Message to be passed for the action") + help="Message to be passed for the action", + default="") (options, args) = parser.parse_args() if args: @@ -60,12 +59,8 @@ def main(): elif options.address is None: parser.print_help() parser.error("IP address missing") - elif options.message is None: - parser.print_help() - parser.error("No message passed") else: - text = format_message(options) - sendData(options, text) + sendData(options) if __name__ == u'__main__': main()