This commit is contained in:
rimach 2010-05-09 10:48:30 +02:00
commit 76a742f175
96 changed files with 3607 additions and 2023 deletions

View File

@ -14,3 +14,4 @@ dist
OpenLP.egg-info OpenLP.egg-info
build build
resources/innosetup/Output resources/innosetup/Output
_eric4project

View File

@ -18,12 +18,6 @@
.. autoclass:: openlp.core.lib.eventreceiver.EventReceiver .. autoclass:: openlp.core.lib.eventreceiver.EventReceiver
:members: :members:
:mod:`ListWithPreviews`
-----------------------
.. autoclass:: openlp.core.lib.listwithpreviews.ListWithPreviews
:members:
:mod:`MediaManagerItem` :mod:`MediaManagerItem`
----------------------- -----------------------
@ -36,12 +30,6 @@
.. autoclass:: openlp.core.lib.plugin.Plugin .. autoclass:: openlp.core.lib.plugin.Plugin
:members: :members:
:mod:`PluginConfig`
-------------------
.. autoclass:: openlp.core.lib.pluginconfig.PluginConfig
:members:
:mod:`PluginManager` :mod:`PluginManager`
-------------------- --------------------

View File

@ -0,0 +1,95 @@
.. _plugins-bibles:
:mod:`bibles` Plugin
====================
.. automodule:: openlp.plugins.bibles
:members:
:mod:`BiblePlugin` Class
-------------------------
.. autoclass:: openlp.plugins.bibles.bibleplugin.BiblePlugin
:members:
:mod:`forms` Submodule
----------------------
.. automodule:: openlp.plugins.bibles.forms
:members:
:mod:`BibleImportWizard`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.bibles.forms.bibleimportwizard.Ui_BibleImportWizard
:members:
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm
:members:
:mod:`lib` Submodule
--------------------
.. automodule:: openlp.plugins.bibles.lib
:members:
:mod:`db`
^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.db
:members:
.. autoclass:: openlp.plugins.bibles.lib.db.BibleDB
:members:
:mod:`csv`
^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.csvbible
:members:
.. autoclass:: openlp.plugins.bibles.lib.csvbible.CSVBible
:members:
:mod:`http`
^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.http
:members:
.. autoclass:: openlp.plugins.bibles.lib.http.HTTPBible
:members:
:mod:`bibleOSISimpl`
^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.osis
:members:
.. autoclass:: openlp.plugins.bibles.lib.osis.OSISBible
:members:
:mod:`biblestab`
^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.biblestab
:members:
:mod:`common`
^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.common
:members:
:mod:`manager`
^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.manager
:members:
:mod:`mediaitem`
^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.mediaitem
:members:

View File

@ -10,12 +10,7 @@
:maxdepth: 2 :maxdepth: 2
songs songs
bibles
:mod:`bibles` Plugin
--------------------
.. automodule:: openlp.plugins.bibles
:members:
:mod:`presentations` Plugin :mod:`presentations` Plugin
--------------------------- ---------------------------
@ -41,3 +36,8 @@
.. automodule:: openlp.plugins.custom .. automodule:: openlp.plugins.custom
:members: :members:
:mod:`songusage` Plugin
-----------------------
.. automodule:: openlp.plugins.songusage
:members:

View File

@ -34,10 +34,10 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger() 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.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen, ScreenList from openlp.core.ui import MainWindow, SplashScreen, ScreenList
from openlp.core.utils import AppLocation, ConfigHelper from openlp.core.utils import AppLocation
application_stylesheet = u""" application_stylesheet = u"""
QMainWindow::separator QMainWindow::separator
@ -110,20 +110,17 @@ class OpenLP(QtGui.QApplication):
finally: finally:
if fversion: if fversion:
fversion.close() 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. #provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(), 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.setApplicationName(u'OpenLP')
self.setApplicationVersion(app_version[u'version']) self.setApplicationVersion(app_version[u'version'])
if os.name == u'nt': if os.name == u'nt':
self.setStyleSheet(application_stylesheet) self.setStyleSheet(application_stylesheet)
show_splash = str_to_bool(ConfigHelper.get_registry().get_value( show_splash = QtCore.QSettings().value(
u'general', u'show splash', True)) u'general/show splash', QtCore.QVariant(True)).toBool()
if show_splash: if show_splash:
self.splash = SplashScreen(self.applicationVersion()) self.splash = SplashScreen(self.applicationVersion())
self.splash.show() self.splash.show()
@ -133,8 +130,8 @@ class OpenLP(QtGui.QApplication):
# Decide how many screens we have and their size # Decide how many screens we have and their size
for screen in xrange(0, self.desktop().numScreens()): for screen in xrange(0, self.desktop().numScreens()):
screens.add_screen({u'number': screen, screens.add_screen({u'number': screen,
u'size': self.desktop().availableGeometry(screen), u'size': self.desktop().availableGeometry(screen),
u'primary': (self.desktop().primaryScreen() == screen)}) u'primary': (self.desktop().primaryScreen() == screen)})
log.info(u'Screen %d found with resolution %s', log.info(u'Screen %d found with resolution %s',
screen, self.desktop().availableGeometry(screen)) screen, self.desktop().availableGeometry(screen))
# start the main app window # start the main app window

View File

@ -164,7 +164,6 @@ class ThemeLevel(object):
from eventreceiver import Receiver from eventreceiver import Receiver
from settingsmanager import SettingsManager from settingsmanager import SettingsManager
from pluginconfig import PluginConfig
from plugin import PluginStatus, Plugin from plugin import PluginStatus, Plugin
from pluginmanager import PluginManager from pluginmanager import PluginManager
from settingstab import SettingsTab from settingstab import SettingsTab

View File

@ -48,5 +48,4 @@ class BaseListWithDnD(QtGui.QListWidget):
mimeData = QtCore.QMimeData() mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData) drag.setMimeData(mimeData)
mimeData.setText(self.PluginName) mimeData.setText(self.PluginName)
dropAction = drag.start(QtCore.Qt.CopyAction) drag.start(QtCore.Qt.CopyAction)

View File

@ -43,8 +43,3 @@ class OpenLPDockWidget(QtGui.QDockWidget):
self.setObjectName(name) self.setObjectName(name)
self.setFloating(False) self.setFloating(False)
log.debug(u'Init done') log.debug(u'Init done')
def closeEvent(self, event):
self.parent.settingsmanager.setUIItemVisibility(
self.objectName(), False)
event.accept()

View File

@ -35,36 +35,118 @@ class EventReceiver(QtCore.QObject):
system. This is a private class and should not be used directly system. This is a private class and should not be used directly
but rather via the Receiver class. but rather via the Receiver class.
``stop_import`` ``openlp_process_events``
Stops the Bible Import
``pre_load_bibles``
Triggers the plugin to relaod the bible lists
``process_events``
Requests the Application to flush the events queue Requests the Application to flush the events queue
``{plugin}_add_service_item`` ``openlp_version_check``
ask the plugin to push the selected items to the service item 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 send out message with new themes
``update_global_theme`` ``theme_update_global``
Tell the components we have a new global theme 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`` ``{plugin}_start``
Requests a plugin to start a external program Requests a plugin to start a external program
Path and file provided in message Path and file provided in message
@ -81,39 +163,51 @@ class EventReceiver(QtCore.QObject):
``{plugin}_last`` ``{plugin}_last``
Requests a plugin to handle a last event Requests a plugin to handle a last event
``{plugin}_slide``
Requests a plugin to handle a go to specific slide event
``{plugin}_stop`` ``{plugin}_stop``
Requests a plugin to handle a stop event 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`` ``{plugin}_edit``
Requests a plugin edit a database item with the key as the payload Requests a plugin edit a database item with the key as the payload
``songusage_live`` ``{plugin}_edit_clear``
Sends live song audit requests to the audit component Editing has been completed
``audit_changed`` ``{plugin}_load_list``
Audit information may have changed Tells the the plugin to reload the media manager list
``config_updated`` ``{plugin}_preview``
Informs components the config has changed Tells the plugin it's item can be previewed
``preview_song`` ``{plugin}_add_service_item``
Tells the song plugin the edit has finished and the song can be previewed Ask the plugin to push the selected items to the service item
Only available if the edit was triggered by the Preview button.
``slidecontroller_change`` ``alerts_text``
Informs the slidecontroller that a slide change has occurred Displays an alert message
``remote_edit_clear`` ``bibles_nobook``
Informs all components that remote edit has been aborted. Attempt to find book resulted in no match
``presentation types`` ``bibles_showprogress``
Informs all components of the presentation types supported. Show progress of bible verse import
``blank_check`` ``bibles_hideprogress``
Check to see if th eblank display message is required Hide progress of bible verse import
``version_check`` ``bibles_stop_import``
Version has changed so pop up window. Stops the Bible Import
``remotes_poll_request``
Waits for openlp to do something "interesting" and sends a
remotes_poll_response signal when it does
""" """
def __init__(self): def __init__(self):
@ -170,4 +264,3 @@ class Receiver():
Get the global ``eventreceiver`` instance. Get the global ``eventreceiver`` instance.
""" """
return Receiver.eventreceiver return Receiver.eventreceiver

View File

@ -29,7 +29,8 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib.toolbar import * 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 from serviceitem import ServiceItem
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -69,11 +70,6 @@ class MediaManagerItem(QtGui.QWidget):
The user visible name for a plugin which should use a suitable The user visible name for a plugin which should use a suitable
translation function. 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`` ``self.OnNewPrompt``
Defaults to *'Select Image(s)'*. Defaults to *'Select Image(s)'*.
@ -102,6 +98,7 @@ class MediaManagerItem(QtGui.QWidget):
""" """
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
self.parent = parent self.parent = parent
self.settingsSection = title.lower()
if type(icon) is QtGui.QIcon: if type(icon) is QtGui.QIcon:
self.icon = icon self.icon = icon
elif type(icon) is types.StringType: elif type(icon) is types.StringType:
@ -334,18 +331,20 @@ class MediaManagerItem(QtGui.QWidget):
def onFileClick(self): def onFileClick(self):
files = QtGui.QFileDialog.getOpenFileNames( files = QtGui.QFileDialog.getOpenFileNames(
self, self.OnNewPrompt, 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)) log.info(u'New files(s) %s', unicode(files))
if files: if files:
self.loadList(files) self.loadList(files)
dir, filename = os.path.split(unicode(files[0])) dir = os.path.split(unicode(files[0]))[0]
self.parent.config.set_last_dir(dir) SettingsManager.set_last_dir(self.settingsSection, dir)
self.parent.config.set_list(self.ConfigSection, self.getFileList()) SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList())
def getFileList(self): def getFileList(self):
count = 0 count = 0
filelist = [] filelist = []
while count < self.ListView.count(): while count < self.ListView.count():
bitem = self.ListView.item(count) bitem = self.ListView.item(count)
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
filelist.append(filename) filelist.append(filename)
@ -357,11 +356,14 @@ class MediaManagerItem(QtGui.QWidget):
Validates to see if the file still exists or Validates to see if the file still exists or
thumbnail is up to date thumbnail is up to date
""" """
filedate = os.stat(file).st_mtime if os.path.exists(file):
thumbdate = os.stat(thumb).st_mtime filedate = os.stat(file).st_mtime
#if file updated rebuild icon thumbdate = os.stat(thumb).st_mtime
if filedate > thumbdate: #if file updated rebuild icon
self.IconFromFile(file, thumb) if filedate > thumbdate:
self.IconFromFile(file, thumb)
return True
return False
def IconFromFile(self, file, thumb): def IconFromFile(self, file, thumb):
icon = build_icon(unicode(file)) icon = build_icon(unicode(file))
@ -422,12 +424,13 @@ class MediaManagerItem(QtGui.QWidget):
else: else:
#Is it posssible to process multiple list items to generate multiple #Is it posssible to process multiple list items to generate multiple
#service items? #service items?
if self.singleServiceItem: if self.singleServiceItem or self.remoteTriggered:
log.debug(self.PluginNameShort + u' Add requested') log.debug(self.PluginNameShort + u' Add requested')
service_item = self.buildServiceItem() service_item = self.buildServiceItem()
if service_item: if service_item:
service_item.from_plugin = False service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item) self.parent.service_manager.addServiceItem(service_item,
replace=self.remoteTriggered)
else: else:
items = self.ListView.selectedIndexes() items = self.ListView.selectedIndexes()
for item in items: for item in items:
@ -447,16 +450,18 @@ class MediaManagerItem(QtGui.QWidget):
if not service_item: if not service_item:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
self.trUtf8('No Service Item Selected'), 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(): elif self.title.lower() == service_item.name.lower():
self.generateSlideData(service_item) self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item) self.parent.service_manager.addServiceItem(service_item,
replace=True)
else: else:
#Turn off the remote edit update message indicator #Turn off the remote edit update message indicator
self.parent.service_manager.remoteEditTriggered = False
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
self.trUtf8('Invalid Service Item'), 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): def buildServiceItem(self, item=None):
""" """

View File

@ -24,9 +24,10 @@
############################################################################### ###############################################################################
import logging import logging
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import PluginConfig, Receiver from openlp.core.lib import Receiver
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -50,13 +51,12 @@ class Plugin(QtCore.QObject):
``version`` ``version``
The version number of this iteration of the plugin. The version number of this iteration of the plugin.
``settingsSection``
The namespace to store settings for the plugin.
``icon`` ``icon``
An instance of QIcon, which holds an icon for this plugin. 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`` ``log``
A log object used to log debugging messages. This is pre-instantiated. 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. Add an item to the Export menu.
``get_settings_tab()`` ``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)`` ``add_to_menu(menubar)``
A method to add a menu item to anywhere in the menu, given the menu bar. 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 self.name = name
if version: if version:
self.version = version self.version = version
self.settingsSection = self.name.lower()
self.icon = None self.icon = None
self.config = PluginConfig(self.name)
self.weight = 0 self.weight = 0
self.status = PluginStatus.Inactive self.status = PluginStatus.Inactive
# Set up logging # Set up logging
@ -125,7 +126,7 @@ class Plugin(QtCore.QObject):
self.live_controller = plugin_helpers[u'live'] self.live_controller = plugin_helpers[u'live']
self.render_manager = plugin_helpers[u'render'] self.render_manager = plugin_helpers[u'render']
self.service_manager = plugin_helpers[u'service'] 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.mediadock = plugin_helpers[u'toolbox']
self.maindisplay = plugin_helpers[u'maindisplay'] self.maindisplay = plugin_helpers[u'maindisplay']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -145,15 +146,17 @@ class Plugin(QtCore.QObject):
""" """
Sets the status of the plugin Sets the status of the plugin
""" """
self.status = int(self.config.get_config(u'status', self.status = QtCore.QSettings().value(
PluginStatus.Inactive)) self.settingsSection + u'/status',
QtCore.QVariant(PluginStatus.Inactive)).toInt()[0]
def toggle_status(self, new_status): def toggle_status(self, new_status):
""" """
Changes the status of the plugin and remembers it Changes the status of the plugin and remembers it
""" """
self.status = new_status 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): def is_active(self):
""" """
@ -212,12 +215,16 @@ class Plugin(QtCore.QObject):
""" """
pass pass
def process_add_service_event(self): def process_add_service_event(self, replace=False):
""" """
Generic Drag and drop handler triggered from service_manager. Generic Drag and drop handler triggered from service_manager.
""" """
log.debug(u'process_add_service_event event called for plugin %s' % self.name) log.debug(u'process_add_service_event event called for plugin %s' %
self.media_item.onAddClick() self.name)
if replace:
self.media_item.onAddEditClick()
else:
self.media_item.onAddClick()
def about(self): def about(self):
""" """
@ -244,7 +251,7 @@ class Plugin(QtCore.QObject):
Called by the plugin to remove toolbar Called by the plugin to remove toolbar
""" """
self.mediadock.remove_dock(self.name) self.mediadock.remove_dock(self.name)
self.settings.removeTab(self.name) self.settings_form.removeTab(self.name)
def insert_toolbox_item(self): def insert_toolbox_item(self):
""" """
@ -253,7 +260,7 @@ class Plugin(QtCore.QObject):
if self.media_item: if self.media_item:
self.mediadock.insert_dock(self.media_item, self.icon, self.weight) self.mediadock.insert_dock(self.media_item, self.icon, self.weight)
if self.settings_tab: 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): def can_delete_theme(self, theme):
""" """

View File

@ -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)

View File

@ -48,8 +48,8 @@ class Renderer(object):
self.theme_name = None self.theme_name = None
self._theme = None self._theme = None
self._bg_image_filename = None self._bg_image_filename = None
self._frame = None self.frame = None
self._frameOp = None self.frame_opaque = None
self.bg_frame = None self.bg_frame = None
self.bg_image = None self.bg_image = None
@ -89,10 +89,10 @@ class Renderer(object):
""" """
log.debug(u'set bg image %s', filename) log.debug(u'set bg image %s', filename)
self._bg_image_filename = unicode(filename) self._bg_image_filename = unicode(filename)
if self._frame: if self.frame:
self.bg_image = resize_image(self._bg_image_filename, self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(), self.frame.width(),
self._frame.height()) self.frame.height())
def set_frame_dest(self, frame_width, frame_height, preview=False): def set_frame_dest(self, frame_width, frame_height, preview=False):
""" """
@ -111,14 +111,13 @@ class Renderer(object):
self.bg_frame = None self.bg_frame = None
log.debug(u'set frame dest (frame) w %d h %d', frame_width, log.debug(u'set frame dest (frame) w %d h %d', frame_width,
frame_height) frame_height)
self._frame = QtGui.QImage(frame_width, frame_height, self.frame = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied) 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) QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename and not self.bg_image: if self._bg_image_filename and not self.bg_image:
self.bg_image = resize_image(self._bg_image_filename, self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(), self.frame.width(), self.frame.height())
self._frame.height())
if self.bg_frame is None: if self.bg_frame is None:
self._generate_background_frame() self._generate_background_frame()
@ -223,7 +222,7 @@ class Renderer(object):
``rect_footer`` ``rect_footer``
The footer text block. 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 = rect_main
self._rect_footer = rect_footer self._rect_footer = rect_footer
@ -243,8 +242,9 @@ class Renderer(object):
if footer_lines: if footer_lines:
bbox1 = self._render_lines_unaligned(footer_lines, True) bbox1 = self._render_lines_unaligned(footer_lines, True)
# reset the frame. first time do not worry about what you paint on. # reset the frame. first time do not worry about what you paint on.
self._frame = QtGui.QImage(self.bg_frame) self.frame = QtGui.QImage(self.bg_frame)
self._frameOp = 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) x, y = self._correctAlignment(self._rect, bbox)
bbox = self._render_lines_unaligned(lines, False, (x, y), True) bbox = self._render_lines_unaligned(lines, False, (x, y), True)
if footer_lines: if footer_lines:
@ -252,9 +252,9 @@ class Renderer(object):
(self._rect_footer.left(), self._rect_footer.top()), True) (self._rect_footer.left(), self._rect_footer.top()), True)
log.debug(u'generate_frame_from_lines - Finish') log.debug(u'generate_frame_from_lines - Finish')
if self._theme.display_slideTransition: 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: else:
return {u'main':self._frame, u'trans':None} return {u'main':self.frame, u'trans':None}
def _generate_background_frame(self): def _generate_background_frame(self):
""" """
@ -264,36 +264,36 @@ class Renderer(object):
assert(self._theme) assert(self._theme)
if self._theme.background_mode == u'transparent': if self._theme.background_mode == u'transparent':
self.bg_frame = \ 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) self.bg_frame.fill(QtCore.Qt.transparent)
else: else:
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), self.bg_frame = QtGui.QImage(self.frame.width(),
QtGui.QImage.Format_ARGB32_Premultiplied) self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied)
log.debug(u'render background %s start', self._theme.background_type) log.debug(u'render background %s start', self._theme.background_type)
painter = QtGui.QPainter() painter = QtGui.QPainter()
painter.begin(self.bg_frame) painter.begin(self.bg_frame)
if self._theme.background_mode == u'transparent': if self._theme.background_mode == u'transparent':
painter.fillRect(self._frame.rect(), QtCore.Qt.transparent) painter.fillRect(self.frame.rect(), QtCore.Qt.transparent)
else: else:
if self._theme.background_type == u'solid': if self._theme.background_type == u'solid':
painter.fillRect(self._frame.rect(), painter.fillRect(self.frame.rect(),
QtGui.QColor(self._theme.background_color)) QtGui.QColor(self._theme.background_color))
elif self._theme.background_type == u'gradient': elif self._theme.background_type == u'gradient':
# gradient # gradient
gradient = None gradient = None
if self._theme.background_direction == u'horizontal': if self._theme.background_direction == u'horizontal':
w = int(self._frame.width()) / 2 w = int(self.frame.width()) / 2
# vertical # vertical
gradient = QtGui.QLinearGradient(w, 0, w, gradient = QtGui.QLinearGradient(w, 0, w,
self._frame.height()) self.frame.height())
elif self._theme.background_direction == u'vertical': elif self._theme.background_direction == u'vertical':
h = int(self._frame.height()) / 2 h = int(self.frame.height()) / 2
# Horizontal # Horizontal
gradient = QtGui.QLinearGradient(0, h, self._frame.width(), gradient = QtGui.QLinearGradient(0, h, self.frame.width(),
h) h)
else: else:
w = int(self._frame.width()) / 2 w = int(self.frame.width()) / 2
h = int(self._frame.height()) / 2 h = int(self.frame.height()) / 2
# Circular # Circular
gradient = QtGui.QRadialGradient(w, h, w) gradient = QtGui.QRadialGradient(w, h, w)
gradient.setColorAt(0, gradient.setColorAt(0,
@ -302,8 +302,8 @@ class Renderer(object):
QtGui.QColor(self._theme.background_endColor)) QtGui.QColor(self._theme.background_endColor))
painter.setBrush(QtGui.QBrush(gradient)) painter.setBrush(QtGui.QBrush(gradient))
rectPath = QtGui.QPainterPath() rectPath = QtGui.QPainterPath()
max_x = self._frame.width() max_x = self.frame.width()
max_y = self._frame.height() max_y = self.frame.height()
rectPath.moveTo(0, 0) rectPath.moveTo(0, 0)
rectPath.lineTo(0, max_y) rectPath.lineTo(0, max_y)
rectPath.lineTo(max_x, max_y) rectPath.lineTo(max_x, max_y)
@ -312,7 +312,7 @@ class Renderer(object):
painter.drawPath(rectPath) painter.drawPath(rectPath)
elif self._theme.background_type == u'image': elif self._theme.background_type == u'image':
# image # image
painter.fillRect(self._frame.rect(), QtCore.Qt.black) painter.fillRect(self.frame.rect(), QtCore.Qt.black)
if self.bg_image: if self.bg_image:
painter.drawImage(0, 0, self.bg_image) painter.drawImage(0, 0, self.bg_image)
painter.end() painter.end()
@ -378,7 +378,7 @@ class Renderer(object):
retval = QtCore.QRect(x, y, brx - x, bry - y) retval = QtCore.QRect(x, y, brx - x, bry - y)
if self._debug: if self._debug:
painter = QtGui.QPainter() painter = QtGui.QPainter()
painter.begin(self._frame) painter.begin(self.frame)
painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255))) painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255)))
painter.drawRect(retval) painter.drawRect(retval)
painter.end() painter.end()
@ -414,11 +414,11 @@ class Renderer(object):
starty = y starty = y
rightextent = None rightextent = None
self.painter = QtGui.QPainter() self.painter = QtGui.QPainter()
self.painter.begin(self._frame) self.painter.begin(self.frame)
self.painter.setRenderHint(QtGui.QPainter.Antialiasing) self.painter.setRenderHint(QtGui.QPainter.Antialiasing)
if self._theme.display_slideTransition: if self._theme.display_slideTransition:
self.painter2 = QtGui.QPainter() self.painter2 = QtGui.QPainter()
self.painter2.begin(self._frameOp) self.painter2.begin(self.frame_opaque)
self.painter2.setRenderHint(QtGui.QPainter.Antialiasing) self.painter2.setRenderHint(QtGui.QPainter.Antialiasing)
self.painter2.setOpacity(0.7) self.painter2.setOpacity(0.7)
# dont allow alignment messing with footers # dont allow alignment messing with footers
@ -463,10 +463,11 @@ class Renderer(object):
# now draw the text, and any outlines/shadows # now draw the text, and any outlines/shadows
if self._theme.display_shadow: if self._theme.display_shadow:
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
tlcorner=(x + display_shadow_size, y + display_shadow_size), tlcorner=(x + display_shadow_size,
draw=True, color = self._theme.display_shadow_color) y + display_shadow_size),
self._get_extent_and_render(line, footer, tlcorner=(x, y), draw=True, draw=True, color = self._theme.display_shadow_color)
outline_size=display_outline_size) self._get_extent_and_render(line, footer, tlcorner=(x, y),
draw=True, outline_size=display_outline_size)
y += h y += h
if linenum == 0: if linenum == 0:
self._first_line_right_extent = rightextent self._first_line_right_extent = rightextent
@ -532,7 +533,7 @@ class Renderer(object):
font = self.mainFont font = self.mainFont
metrics = QtGui.QFontMetrics(font) metrics = QtGui.QFontMetrics(font)
w = metrics.width(line) w = metrics.width(line)
h = metrics.height() h = metrics.height() + int(self._theme.font_main_line_adjustment)
if draw: if draw:
self.painter.setFont(font) self.painter.setFont(font)
if color is None: if color is None:
@ -543,27 +544,29 @@ class Renderer(object):
else: else:
pen = QtGui.QColor(color) pen = QtGui.QColor(color)
x, y = tlcorner x, y = tlcorner
rowpos = y + metrics.ascent()
if self._theme.display_outline and outline_size != 0 and not footer: if self._theme.display_outline and outline_size != 0 and not footer:
path = QtGui.QPainterPath() 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.setBrush(self.painter.pen().brush())
self.painter.setPen(QtGui.QPen( self.painter.setPen(QtGui.QPen(QtGui.QColor(
QtGui.QColor(self._theme.display_outline_color), outline_size)) self._theme.display_outline_color), outline_size))
self.painter.drawPath(path) self.painter.drawPath(path)
self.painter.setPen(pen) self.painter.setPen(pen)
self.painter.drawText(x, y + metrics.ascent(), line) self.painter.drawText(x, rowpos, line)
if self._theme.display_slideTransition: if self._theme.display_slideTransition:
# Print 2nd image with 70% weight # Print 2nd image with 70% weight
if self._theme.display_outline and outline_size != 0 and not footer: if self._theme.display_outline and outline_size != 0 and not footer:
path = QtGui.QPainterPath() 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.setBrush(self.painter2.pen().brush())
self.painter2.setPen(QtGui.QPen( 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.drawPath(path)
self.painter2.setFont(font) self.painter2.setFont(font)
self.painter2.setPen(pen) self.painter2.setPen(pen)
self.painter2.drawText(x, y + metrics.ascent(), line) self.painter2.drawText(x, rowpos, line)
return (w, h) return (w, h)
def snoop_Image(self, image, image2=None): def snoop_Image(self, image, image2=None):

View File

@ -30,7 +30,7 @@ import uuid
from PyQt4 import QtGui 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__) log = logging.getLogger(__name__)
@ -48,7 +48,7 @@ class ItemCapabilities(object):
AllowsMaintain = 3 AllowsMaintain = 3
RequiresMedia = 4 RequiresMedia = 4
AllowsLoop = 5 AllowsLoop = 5
AllowsAdditions = 6
class ServiceItem(object): class ServiceItem(object):
""" """
@ -81,6 +81,7 @@ class ServiceItem(object):
self.notes = u'' self.notes = u''
self.from_plugin = False self.from_plugin = False
self.capabilities = [] self.capabilities = []
self.isValid = True
def add_capability(self, capability): def add_capability(self, capability):
self.capabilities.append(capability) self.capabilities.append(capability)
@ -336,6 +337,3 @@ class ServiceItem(object):
""" """
return self._raw_frames[row][u'path'] return self._raw_frames[row][u'path']
def request_audit(self):
if self.audit:
Receiver.send_message(u'songusage_live', self.audit)

View File

@ -23,14 +23,16 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from openlp.core.lib import str_to_bool import os
from openlp.core.utils import ConfigHelper
from PyQt4 import QtCore
from openlp.core.utils import AppLocation
class SettingsManager(object): class SettingsManager(object):
""" """
Class to control the size of the UI components so they size correctly. Class to control the initial settings for the UI and provide helper
This class is created by the main window and then calculates the size of functions for the loading and saving of application settings.
individual components.
""" """
def __init__(self, screen): def __init__(self, screen):
self.screen = screen.current self.screen = screen.current
@ -50,26 +52,131 @@ class SettingsManager(object):
self.mainwindow_left + self.mainwindow_right) - 100 ) / 2 self.mainwindow_left + self.mainwindow_right) - 100 ) / 2
self.slidecontroller_image = self.slidecontroller - 50 self.slidecontroller_image = self.slidecontroller - 50
self.showMediaManager = str_to_bool(ConfigHelper.get_config( self.showPreviewPanel = QtCore.QSettings().value(
u'user interface', u'media manager', True)) u'user interface/preview panel', True).toBool()
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)
def togglePreviewPanel(self, isVisible): 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

View File

@ -25,35 +25,25 @@
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import PluginConfig
class SettingsTab(QtGui.QWidget): class SettingsTab(QtGui.QWidget):
""" """
SettingsTab is a helper widget for plugins to define Tabs for the settings SettingsTab is a helper widget for plugins to define Tabs for the settings
dialog. dialog.
""" """
def __init__(self, title, section=None): def __init__(self, title):
""" """
Constructor to create the Settings tab item. Constructor to create the Settings tab item.
``title`` ``title``
Defaults to *None*. The title of the tab, which is usually The title of the tab, which is usually displayed on the tab.
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.
""" """
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
self.tabTitle = title self.tabTitle = title
self.tabTitleVisible = None self.tabTitleVisible = None
self.settingsSection = self.tabTitle.lower()
self.setupUi() self.setupUi()
self.retranslateUi() self.retranslateUi()
self.initialise() self.initialise()
if section is None:
self.config = PluginConfig(title)
else:
self.config = PluginConfig(section)
self.preLoad() self.preLoad()
self.load() self.load()

View File

@ -53,6 +53,7 @@ blankthemexml=\
<weight>Normal</weight> <weight>Normal</weight>
<italics>False</italics> <italics>False</italics>
<indentation>0</indentation> <indentation>0</indentation>
<line_adjustment>0</line_adjustment>
<location override="False" x="10" y="10" width="1004" height="730"/> <location override="False" x="10" y="10" width="1004" height="730"/>
</font> </font>
<font type="footer"> <font type="footer">
@ -62,6 +63,7 @@ blankthemexml=\
<weight>Normal</weight> <weight>Normal</weight>
<italics>False</italics> <italics>False</italics>
<indentation>0</indentation> <indentation>0</indentation>
<line_adjustment>0</line_adjustment>
<location override="False" x="10" y="730" width="1004" height="38"/> <location override="False" x="10" y="730" width="1004" height="38"/>
</font> </font>
<display> <display>
@ -171,8 +173,8 @@ class ThemeXML(object):
self.child_element(background, u'filename', filename) self.child_element(background, u'filename', filename)
def add_font(self, name, color, proportion, override, fonttype=u'main', def add_font(self, name, color, proportion, override, fonttype=u'main',
weight=u'Normal', italics=u'False', indentation=0, xpos=0, ypos=0, weight=u'Normal', italics=u'False', indentation=0, line_adjustment=0,
width=0, height=0): xpos=0, ypos=0, width=0, height=0):
""" """
Add a Font. Add a Font.
@ -227,6 +229,8 @@ class ThemeXML(object):
self.child_element(background, u'italics', italics) self.child_element(background, u'italics', italics)
#Create indentation name element #Create indentation name element
self.child_element(background, u'indentation', unicode(indentation)) 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 #Create Location element
element = self.theme_xml.createElement(u'location') element = self.theme_xml.createElement(u'location')

View File

@ -23,15 +23,27 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # 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 slidecontroller import HideMode
from servicenoteform import ServiceNoteForm from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList from screen import ScreenList
from maindisplay import MainDisplay from maindisplay import MainDisplay
from maindisplay import VideoDisplay from maindisplay import VideoDisplay
from maindisplay import DisplayManager
from amendthemeform import AmendThemeForm from amendthemeform import AmendThemeForm
from slidecontroller import SlideController from slidecontroller import SlideController
from splashscreen import SplashScreen from splashscreen import SplashScreen
from displaytab import DisplayTab
from generaltab import GeneralTab from generaltab import GeneralTab
from themestab import ThemesTab from themestab import ThemesTab
from aboutform import AboutForm from aboutform import AboutForm

View File

@ -178,16 +178,22 @@ class Ui_AmendThemeDialog(object):
self.FontMainWeightLabel.setObjectName("FontMainWeightLabel") self.FontMainWeightLabel.setObjectName("FontMainWeightLabel")
self.MainFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.FontMainWeightLabel) self.MainFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.FontMainWeightLabel)
self.MainLeftLayout.addWidget(self.FontMainGroupBox) 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 = QtGui.QLabel(self.FontMainGroupBox)
self.FontMainWrapIndentationLabel.setObjectName("FontMainWrapIndentationLabel") 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 = QtGui.QSpinBox(self.FontMainGroupBox)
self.FontMainLineSpacingSpinBox.setObjectName("FontMainLineSpacingSpinBox") self.FontMainLineSpacingSpinBox.setObjectName("FontMainLineSpacingSpinBox")
self.FontMainLineSpacingSpinBox.setMaximum(10) 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 = QtGui.QLabel(self.FontMainGroupBox)
self.FontMainLinesPageLabel.setObjectName("FontMainLinesPageLabel") 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) spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.MainLeftLayout.addItem(spacerItem1) self.MainLeftLayout.addItem(spacerItem1)
self.FontMainLayout.addWidget(self.MainLeftWidget) self.FontMainLayout.addWidget(self.MainLeftWidget)
@ -620,6 +626,7 @@ class Ui_AmendThemeDialog(object):
self.FontMainSize.setText(self.trUtf8('Size:')) self.FontMainSize.setText(self.trUtf8('Size:'))
self.FontMainSizeSpinBox.setSuffix(self.trUtf8('pt')) self.FontMainSizeSpinBox.setSuffix(self.trUtf8('pt'))
self.FontMainWrapIndentationLabel.setText(self.trUtf8('Wrap Indentation')) 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(0, self.trUtf8('Normal'))
self.FontMainWeightComboBox.setItemText(1, self.trUtf8('Bold')) self.FontMainWeightComboBox.setItemText(1, self.trUtf8('Bold'))
self.FontMainWeightComboBox.setItemText(2, self.trUtf8('Italics')) self.FontMainWeightComboBox.setItemText(2, self.trUtf8('Italics'))

View File

@ -101,6 +101,9 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.FontMainHeightSpinBox, QtCore.QObject.connect(self.FontMainHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainHeightSpinBoxChanged) self.onFontMainHeightSpinBoxChanged)
QtCore.QObject.connect(self.FontMainLineAdjustmentSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineAdjustmentSpinBoxChanged)
QtCore.QObject.connect(self.FontMainLineSpacingSpinBox, QtCore.QObject.connect(self.FontMainLineSpacingSpinBox,
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineSpacingSpinBoxChanged) self.onFontMainLineSpacingSpinBoxChanged)
@ -130,7 +133,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onOutlineSpinBoxChanged) self.onOutlineSpinBoxChanged)
QtCore.QObject.connect(self.SlideTransitionCheckedBox, QtCore.QObject.connect(self.SlideTransitionCheckedBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckedBoxChanged) QtCore.SIGNAL(u'stateChanged(int)'),
self.onSlideTransitionCheckedBoxChanged)
def accept(self): def accept(self):
new_theme = ThemeXML() new_theme = ThemeXML()
@ -142,10 +146,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
new_theme.add_background_transparent() new_theme.add_background_transparent()
else: else:
if self.theme.background_type == u'solid': if self.theme.background_type == u'solid':
new_theme.add_background_solid( \ new_theme.add_background_solid(
unicode(self.theme.background_color)) unicode(self.theme.background_color))
elif self.theme.background_type == u'gradient': 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_startColor),
unicode(self.theme.background_endColor), unicode(self.theme.background_endColor),
self.theme.background_direction) self.theme.background_direction)
@ -155,7 +159,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
new_theme.add_background_image(filename) new_theme.add_background_image(filename)
save_to = os.path.join(self.path, theme_name, filename) save_to = os.path.join(self.path, theme_name, filename)
save_from = self.theme.background_filename save_from = self.theme.background_filename
new_theme.add_font(unicode(self.theme.font_main_name), new_theme.add_font(unicode(self.theme.font_main_name),
unicode(self.theme.font_main_color), unicode(self.theme.font_main_color),
unicode(self.theme.font_main_proportion), 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_weight),
unicode(self.theme.font_main_italics), unicode(self.theme.font_main_italics),
unicode(self.theme.font_main_indentation), unicode(self.theme.font_main_indentation),
unicode(self.theme.font_main_line_adjustment),
unicode(self.theme.font_main_x), unicode(self.theme.font_main_x),
unicode(self.theme.font_main_y), unicode(self.theme.font_main_y),
unicode(self.theme.font_main_width), 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_override), u'footer',
unicode(self.theme.font_footer_weight), unicode(self.theme.font_footer_weight),
unicode(self.theme.font_footer_italics), unicode(self.theme.font_footer_italics),
0, 0, # indentation
0, # line adjustment
unicode(self.theme.font_footer_x), unicode(self.theme.font_footer_x),
unicode(self.theme.font_footer_y), unicode(self.theme.font_footer_y),
unicode(self.theme.font_footer_width), 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), new_theme.add_display(unicode(self.theme.display_shadow),
unicode(self.theme.display_shadow_color), unicode(self.theme.display_shadow_color),
unicode(self.theme.display_outline), unicode(self.theme.display_outline),
@ -261,6 +266,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontMainYSpinBox.setValue(self.theme.font_main_y) self.FontMainYSpinBox.setValue(self.theme.font_main_y)
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width) self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.FontMainHeightSpinBox.setValue(self.theme.font_main_height) self.FontMainHeightSpinBox.setValue(self.theme.font_main_height)
self.FontMainLineAdjustmentSpinBox.setValue(
self.theme.font_main_line_adjustment)
self.FontMainLineSpacingSpinBox.setValue( self.FontMainLineSpacingSpinBox.setValue(
self.theme.font_main_indentation) self.theme.font_main_indentation)
self.stateChanging(self.theme) self.stateChanging(self.theme)
@ -281,6 +288,13 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.font_main_width = self.FontMainWidthSpinBox.value() self.theme.font_main_width = self.FontMainWidthSpinBox.value()
self.previewTheme() 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): def onFontMainLineSpacingSpinBoxChanged(self):
if self.theme.font_main_indentation != \ if self.theme.font_main_indentation != \
self.FontMainLineSpacingSpinBox.value(): self.FontMainLineSpacingSpinBox.value():
@ -687,7 +701,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
if self.allowPreview: if self.allowPreview:
#calculate main number of rows #calculate main number of rows
metrics = self._getThemeMetrics() metrics = self._getThemeMetrics()
line_height = metrics.height() line_height = metrics.height() \
+ int(self.theme.font_main_line_adjustment)
if self.theme.display_shadow: if self.theme.display_shadow:
line_height += int(self.theme.display_shadow_size) line_height += int(self.theme.display_shadow_size)
if self.theme.display_outline: if self.theme.display_outline:
@ -700,7 +715,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
page_length)) page_length))
page_length_text = unicode(self.trUtf8('Slide Height is %s rows')) page_length_text = unicode(self.trUtf8('Slide Height is %s rows'))
self.FontMainLinesPageLabel.setText(page_length_text % page_length) self.FontMainLinesPageLabel.setText(page_length_text % page_length)
#a=c
frame = self.thememanager.generateImage(self.theme) frame = self.thememanager.generateImage(self.theme)
self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))

View File

@ -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')

View File

@ -25,7 +25,7 @@
from PyQt4 import QtCore, QtGui 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): class GeneralTab(SettingsTab):
""" """
@ -41,12 +41,16 @@ class GeneralTab(SettingsTab):
values. values.
If not set before default to last screen. If not set before default to last screen.
""" """
self.MonitorNumber = int(self.config.get_config(u'monitor', settings = QtCore.QSettings()
self.screens.monitor_number)) settings.beginGroup(self.settingsSection)
self.MonitorNumber = settings.value(u'monitor',
QtCore.QVariant(self.screens.display_count - 1)).toInt()[0]
self.screens.set_current_display(self.MonitorNumber) self.screens.set_current_display(self.MonitorNumber)
self.screens.monitor_number = 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 self.screens.display = self.DisplayOnMonitor
settings.endGroup()
def setupUi(self): def setupUi(self):
self.setObjectName(u'GeneralTab') self.setObjectName(u'GeneralTab')
@ -151,15 +155,18 @@ class GeneralTab(SettingsTab):
QtCore.QObject.connect(self.MonitorComboBox, QtCore.QObject.connect(self.MonitorComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onMonitorComboBoxChanged) QtCore.SIGNAL(u'activated(int)'), self.onMonitorComboBoxChanged)
QtCore.QObject.connect(self.DisplayOnMonitorCheck, 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.QObject.connect(self.WarningCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onWarningCheckBoxChanged) QtCore.SIGNAL(u'stateChanged(int)'), self.onWarningCheckBoxChanged)
QtCore.QObject.connect(self.AutoOpenCheckBox, QtCore.QObject.connect(self.AutoOpenCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoOpenCheckBoxChanged) QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoOpenCheckBoxChanged)
QtCore.QObject.connect(self.ShowSplashCheckBox, 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.QObject.connect(self.SaveCheckServiceCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onSaveCheckServiceCheckBox) QtCore.SIGNAL(u'stateChanged(int)'),
self.onSaveCheckServiceCheckBox)
QtCore.QObject.connect(self.AutoPreviewCheckBox, QtCore.QObject.connect(self.AutoPreviewCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoPreviewCheckBox) QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoPreviewCheckBox)
QtCore.QObject.connect(self.NumberEdit, QtCore.QObject.connect(self.NumberEdit,
@ -171,15 +178,20 @@ class GeneralTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.MonitorGroupBox.setTitle(self.trUtf8('Monitors')) self.MonitorGroupBox.setTitle(self.trUtf8('Monitors'))
self.MonitorLabel.setText(self.trUtf8('Select monitor for output display:')) self.MonitorLabel.setText(
self.DisplayOnMonitorCheck.setText(self.trUtf8('Display if in single screen')) 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.StartupGroupBox.setTitle(self.trUtf8('Application Startup'))
self.WarningCheckBox.setText(self.trUtf8('Show blank screen warning')) 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.ShowSplashCheckBox.setText(self.trUtf8('Show the splash screen'))
self.SettingsGroupBox.setTitle(self.trUtf8('Application Settings')) self.SettingsGroupBox.setTitle(self.trUtf8('Application Settings'))
self.SaveCheckServiceCheckBox.setText(self.trUtf8('Prompt to save Service before starting New')) self.SaveCheckServiceCheckBox.setText(
self.AutoPreviewCheckBox.setText(self.trUtf8('Preview Next Song from Service Manager')) 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.CCLIGroupBox.setTitle(self.trUtf8('CCLI Details'))
self.NumberLabel.setText(self.trUtf8('CCLI Number:')) self.NumberLabel.setText(self.trUtf8('CCLI Number:'))
self.UsernameLabel.setText(self.trUtf8('SongSelect Username:')) self.UsernameLabel.setText(self.trUtf8('SongSelect Username:'))
@ -216,20 +228,32 @@ class GeneralTab(SettingsTab):
self.Password = self.PasswordEdit.displayText() self.Password = self.PasswordEdit.displayText()
def load(self): def load(self):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
for screen in self.screens.screen_list: 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']: if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary')) screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary'))
self.MonitorComboBox.addItem(screen_name) self.MonitorComboBox.addItem(screen_name)
# Get the configs # Get the configs
self.Warning = str_to_bool(self.config.get_config(u'blank warning', u'False')) self.Warning = settings.value(
self.AutoOpen = str_to_bool(self.config.get_config(u'auto open', u'False')) u'blank warning', QtCore.QVariant(False)).toBool()
self.ShowSplash = str_to_bool(self.config.get_config(u'show splash', u'True')) self.AutoOpen = settings.value(
self.PromptSaveService = str_to_bool(self.config.get_config(u'save prompt', u'False')) u'auto open', QtCore.QVariant(False)).toBool()
self.AutoPreview = str_to_bool(self.config.get_config(u'auto preview', u'False')) self.ShowSplash = settings.value(
self.CCLINumber = unicode(self.config.get_config(u'ccli number', u'')) u'show splash', QtCore.QVariant(True)).toBool()
self.Username = unicode(self.config.get_config(u'songselect username', u'')) self.PromptSaveService = settings.value(
self.Password = unicode(self.config.get_config(u'songselect password', u'')) 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) self.SaveCheckServiceCheckBox.setChecked(self.PromptSaveService)
# Set a few things up # Set a few things up
self.MonitorComboBox.setCurrentIndex(self.MonitorNumber) self.MonitorComboBox.setCurrentIndex(self.MonitorNumber)
@ -243,19 +267,27 @@ class GeneralTab(SettingsTab):
self.PasswordEdit.setText(self.Password) self.PasswordEdit.setText(self.Password)
def save(self): def save(self):
self.config.set_config(u'monitor', self.MonitorNumber) settings = QtCore.QSettings()
self.config.set_config(u'display on monitor', self.DisplayOnMonitor) settings.beginGroup(self.settingsSection)
self.config.set_config(u'blank warning', self.Warning) settings.setValue(u'monitor', QtCore.QVariant(self.MonitorNumber))
self.config.set_config(u'auto open', self.AutoOpen) settings.setValue(u'display on monitor',
self.config.set_config(u'show splash', self.ShowSplash) QtCore.QVariant(self.DisplayOnMonitor))
self.config.set_config(u'save prompt', self.PromptSaveService) settings.setValue(u'blank warning', QtCore.QVariant(self.Warning))
self.config.set_config(u'auto preview', self.AutoPreview) settings.setValue(u'auto open', QtCore.QVariant(self.AutoOpen))
self.config.set_config(u'ccli number', self.CCLINumber) settings.setValue(u'show splash', QtCore.QVariant(self.ShowSplash))
self.config.set_config(u'songselect username', self.Username) settings.setValue(u'save prompt',
self.config.set_config(u'songselect password', self.Password) 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 self.screens.display = self.DisplayOnMonitor
#Monitor Number has changed. #Monitor Number has changed.
if self.screens.monitor_number != self.MonitorNumber: if self.screens.monitor_number != self.MonitorNumber:
self.screens.monitor_number = self.MonitorNumber self.screens.monitor_number = self.MonitorNumber
self.screens.set_current_display(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')

View File

@ -34,6 +34,28 @@ from openlp.core.ui import HideMode
log = logging.getLogger(__name__) 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)
self.screens = screens
self.videoDisplay = VideoDisplay(self, screens)
self.mainDisplay = MainDisplay(self, screens)
def setup(self):
self.videoDisplay.setup()
self.mainDisplay.setup()
def close(self):
self.videoDisplay.close()
self.mainDisplay.close()
class DisplayWidget(QtGui.QWidget): class DisplayWidget(QtGui.QWidget):
""" """
Customised version of QTableWidget which can respond to keyboard Customised version of QTableWidget which can respond to keyboard
@ -42,28 +64,29 @@ class DisplayWidget(QtGui.QWidget):
log.info(u'MainDisplay loaded') log.info(u'MainDisplay loaded')
def __init__(self, parent=None, name=None): def __init__(self, parent=None, name=None):
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, None)
self.parent = parent self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', self.hotkey_map = {
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item', QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event): def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent: if type(event) == QtGui.QKeyEvent:
#here accept the event and do something #here accept the event and do something
if event.key() == QtCore.Qt.Key_Up: if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'live_slidecontroller_previous') Receiver.send_message(u'slidecontroller_live_previous')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_Down: elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'live_slidecontroller_next') Receiver.send_message(u'slidecontroller_live_next')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_PageUp: elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'live_slidecontroller_first') Receiver.send_message(u'slidecontroller_live_first')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_PageDown: elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'live_slidecontroller_last') Receiver.send_message(u'slidecontroller_live_last')
event.accept() event.accept()
elif event.key() in self.hotkey_map: elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()]) Receiver.send_message(self.hotkey_map[event.key()])
@ -91,12 +114,11 @@ class MainDisplay(DisplayWidget):
``screens`` ``screens``
The list of screens. The list of screens.
""" """
log.debug(u'Initilisation started') log.debug(u'Initialisation started')
DisplayWidget.__init__(self, None) DisplayWidget.__init__(self, parent)
self.parent = parent self.parent = parent
self.setWindowTitle(u'OpenLP Display') self.setWindowTitle(u'OpenLP Display')
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.screens = screens self.screens = screens
self.display_image = QtGui.QLabel(self) self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True) self.display_image.setScaledContents(True)
@ -108,31 +130,30 @@ class MainDisplay(DisplayWidget):
self.displayBlank = False self.displayBlank = False
self.blankFrame = None self.blankFrame = None
self.frame = None self.frame = None
self.firstTime = True
self.hasTransition = False
self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_start'), self.onMediaQueue) QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_background'), self.hideDisplayForVideo)
def setup(self): def setup(self):
""" """
Sets up the screen on a particular screen. Sets up the screen on a particular screen.
""" """
log.debug(u'Setup %s for %s ' %(self.screens, log.debug(u'Setup %s for %s ' % (
self.screens.monitor_number)) self.screens, self.screens.monitor_number))
self.setVisible(False) self.setVisible(False)
self.screen = self.screens.current self.screen = self.screens.current
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
self.display_alert.setGeometry(self.screen[u'size']) self.display_alert.setGeometry(self.screen[u'size'])
self.display_image.resize(self.screen[u'size'].width(), self.display_image.resize(
self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(), self.display_text.resize(
self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.setGeometry(self.screen[u'size'])
#Build a custom splash screen #Build a custom splash screen
self.InitialFrame = QtGui.QImage( self.InitialFrame = QtGui.QImage(
self.screen[u'size'].width(), self.screen[u'size'].width(),
@ -157,8 +178,8 @@ class MainDisplay(DisplayWidget):
painter.begin(self.blankFrame) painter.begin(self.blankFrame)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
#build a blank transparent image #build a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), self.transparent = QtGui.QPixmap(
self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent) self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent) self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent)
@ -173,31 +194,71 @@ class MainDisplay(DisplayWidget):
def resetDisplay(self): def resetDisplay(self):
log.debug(u'resetDisplay') log.debug(u'resetDisplay')
Receiver.send_message(u'stop_display_loop') Receiver.send_message(u'slidecontroller_live_stop_loop')
if self.primary: if self.primary:
self.setVisible(False) self.setVisible(False)
else: else:
self.showFullScreen() self.showFullScreen()
def hideDisplay(self): def hideDisplayForVideo(self):
log.debug(u'hideDisplay') """
self.display_image.setPixmap(self.transparent) 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_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent) self.display_text.setPixmap(self.transparent)
if mode == HideMode.Screen:
self.display_image.setPixmap(self.transparent)
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.show()
def showDisplay(self): 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') log.debug(u'showDisplay')
if not self.primary: if self.storeImage:
self.setVisible(True) self.display_image.setPixmap(self.storeImage)
self.showFullScreen() self.display_alert.setPixmap(self.transparent)
Receiver.send_message(u'flush_alert') 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): def addImageWithText(self, frame):
log.debug(u'addImageWithText') log.debug(u'addImageWithText')
frame = resize_image(frame, frame = resize_image(
self.screen[u'size'].width(), frame, self.screen[u'size'].width(), self.screen[u'size'].height())
self.screen[u'size'].height() )
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
self.moveToTop()
def setAlertSize(self, top, height): def setAlertSize(self, top, height):
log.debug(u'setAlertSize') log.debug(u'setAlertSize')
@ -211,6 +272,7 @@ class MainDisplay(DisplayWidget):
self.display_alert.setPixmap(self.transparent) self.display_alert.setPixmap(self.transparent)
else: else:
self.display_alert.setPixmap(frame) self.display_alert.setPixmap(frame)
self.moveToTop()
def frameView(self, frame, transition=False): def frameView(self, frame, transition=False):
""" """
@ -223,14 +285,17 @@ class MainDisplay(DisplayWidget):
if not self.displayBlank: if not self.displayBlank:
if transition: if transition:
if self.frame is not None: 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.repaint()
self.frame = None self.frame = None
if frame[u'trans'] is not 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.repaint()
self.frame = frame[u'trans'] 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.display_frame = frame[u'main']
self.repaint() self.repaint()
else: else:
@ -246,79 +311,14 @@ class MainDisplay(DisplayWidget):
self.waitingFrame = frame self.waitingFrame = frame
self.waitingFrameTrans = transition self.waitingFrameTrans = transition
def blankDisplay(self, blankType=HideMode.Blank, blanked=True): class VideoDisplay(Phonon.VideoWidget):
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)
def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message)
self.hideDisplay()
self.activateWindow()
class VideoWidget(QtGui.QWidget):
"""
Customised version of QTableWidget which can respond to keyboard
events.
"""
log.info(u'MainDisplay loaded')
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'}
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')
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'live_slidecontroller_next')
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'live_slidecontroller_first')
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'live_slidecontroller_last')
event.accept()
elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()])
event.accept()
elif event.key() == QtCore.Qt.Key_Escape:
self.resetDisplay()
event.accept()
event.ignore()
else:
event.ignore()
class VideoDisplay(VideoWidget):
""" """
This is the form that is used to display videos on the projector. This is the form that is used to display videos on the projector.
""" """
log.info(u'VideoDisplay Loaded') log.info(u'VideoDisplay Loaded')
def __init__(self, parent, screens): def __init__(self, parent, screens,
aspect=Phonon.VideoWidget.AspectRatioWidget):
""" """
The constructor for the display form. The constructor for the display form.
@ -328,74 +328,149 @@ class VideoDisplay(VideoWidget):
``screens`` ``screens``
The list of screens. The list of screens.
""" """
log.debug(u'VideoDisplay Initilisation started') log.debug(u'VideoDisplay Initialisation started')
VideoWidget.__init__(self, parent) Phonon.VideoWidget.__init__(self)
self.setWindowTitle(u'OpenLP Video Display') self.setWindowTitle(u'OpenLP Video Display')
self.parent = parent self.parent = parent
self.screens = screens self.screens = screens
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.hidden = False
self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.message = None
self.mediaObject = Phonon.MediaObject(self) self.mediaObject = Phonon.MediaObject()
self.video = Phonon.VideoWidget() self.setAspectRatio(aspect)
self.video.setVisible(False) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.audioObject)
Phonon.createPath(self.mediaObject, self.audio) self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint |
self.firstTime = True QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.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.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.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:
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Escape:
self.onMediaStop()
event.accept()
event.ignore()
else:
event.ignore()
def setup(self): def setup(self):
""" """
Sets up the screen on a particular screen. Sets up the screen on a particular screen.
""" """
log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens, log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens,
self.screens.monitor_number)) self.screens.monitor_number))
self.setVisible(False)
self.screen = self.screens.current self.screen = self.screens.current
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.video.setGeometry(self.screen[u'size']) # To display or not to display?
if not self.screen[u'primary'] and self.isVisible():
self.showFullScreen()
self.primary = False
else:
self.setVisible(False)
self.primary = True
def onMediaBackground(self, message=None):
"""
Play a video triggered from the video plugin with the
file name passed in on the event.
Also triggered from the Finish event so the video will loop
if it is triggered from the plugin
"""
log.debug(u'VideoDisplay Queue new media message %s' % message)
#If not file take the stored one
if not message:
message = self.message
# still no file name then stop as it was a normal video stopping
if message:
self.mediaObject.setCurrentSource(Phonon.MediaSource(message))
self.message = message
self._play()
def onMediaQueue(self, message): def onMediaQueue(self, message):
"""
Set up a video to play from the serviceitem.
"""
log.debug(u'VideoDisplay Queue new media message %s' % message) log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[1], message[2]) file = os.path.join(message[0].get_frame_path(),
if self.firstTime: message[0].get_frame_title())
source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.firstTime = False self._play()
else:
self.mediaObject.enqueue(Phonon.MediaSource(file))
self.onMediaPlay()
def onMediaPlay(self): def onMediaPlay(self):
log.debug(u'VideoDisplay Play the new media, Live ') """
self.firstTime = True Respond to the Play button on the slide controller unless the display
self.setWindowState(QtCore.Qt.WindowMinimized) has been hidden by the slidecontroller
self.video.setFullScreen(True) """
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.mediaObject.play()
self.setVisible(True) self.setVisible(True)
self.lower() self.showFullScreen()
def onMediaPause(self): def onMediaPause(self):
"""
Pause the video and refresh the screen
"""
log.debug(u'VideoDisplay Media paused by user') log.debug(u'VideoDisplay Media paused by user')
self.mediaObject.pause() self.mediaObject.pause()
self.show()
def onMediaStop(self): def onMediaStop(self):
"""
Stop the video and clean up
"""
log.debug(u'VideoDisplay Media stopped by user') log.debug(u'VideoDisplay Media stopped by user')
self.message = None
self.mediaObject.stop() self.mediaObject.stop()
self.onMediaFinish() self.onMediaFinish()
def onMediaFinish(self): def onMediaFinish(self):
"""
Clean up the Object queue
"""
log.debug(u'VideoDisplay Reached end of media playlist') log.debug(u'VideoDisplay Reached end of media playlist')
self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
self.video.setVisible(False)
self.setVisible(False) 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()

View File

@ -28,12 +28,11 @@ import time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ServiceManager, ThemeManager, MainDisplay, SlideController, \ ThemeManager, SlideController, PluginForm, MediaDockManager, DisplayManager
PluginForm, MediaDockManager, VideoDisplay from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
from openlp.core.lib import RenderManager, PluginConfig, build_icon, \ SettingsManager, PluginManager, Receiver
OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool from openlp.core.utils import check_latest_version, AppLocation, add_actions
from openlp.core.utils import check_latest_version, AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -57,23 +56,21 @@ class VersionThread(QtCore.QThread):
A special Qt thread class to fetch the version of OpenLP from the website. 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. 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) QtCore.QThread.__init__(self, parent)
self.parent = parent self.parent = parent
self.app_version = app_version self.app_version = app_version
self.generalConfig = generalConfig
def run(self): def run(self):
""" """
Run the thread. Run the thread.
""" """
time.sleep(1) time.sleep(1)
Receiver.send_message(u'blank_check') Receiver.send_message(u'maindisplay_blank_check')
version = check_latest_version(self.generalConfig, self.app_version) version = check_latest_version(self.app_version)
#new version has arrived #new version has arrived
if version != self.app_version[u'full']: 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): class Ui_MainWindow(object):
def setupUi(self, MainWindow): def setupUi(self, MainWindow):
@ -164,7 +161,6 @@ class Ui_MainWindow(object):
self.MediaManagerDock.setWidget(self.MediaManagerContents) self.MediaManagerDock.setWidget(self.MediaManagerContents)
MainWindow.addDockWidget( MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock) QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
self.MediaManagerDock.setVisible(self.settingsmanager.showMediaManager)
# Create the service manager # Create the service manager
self.ServiceManagerDock = OpenLPDockWidget(MainWindow) self.ServiceManagerDock = OpenLPDockWidget(MainWindow)
ServiceManagerIcon = build_icon(u':/system/system_servicemanager.png') ServiceManagerIcon = build_icon(u':/system/system_servicemanager.png')
@ -176,18 +172,17 @@ class Ui_MainWindow(object):
self.ServiceManagerDock.setWidget(self.ServiceManagerContents) self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
MainWindow.addDockWidget( MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock) QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock)
self.ServiceManagerDock.setVisible(
self.settingsmanager.showServiceManager)
# Create the theme manager # Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget(MainWindow) self.ThemeManagerDock = OpenLPDockWidget(MainWindow)
ThemeManagerIcon = build_icon(u':/system/system_thememanager.png') ThemeManagerIcon = build_icon(u':/system/system_thememanager.png')
self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon) self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon)
self.ThemeManagerDock.setObjectName(u'ThemeManagerDock') self.ThemeManagerDock.setObjectName(u'ThemeManagerDock')
self.ThemeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(self) self.ThemeManagerContents = ThemeManager(self)
self.ThemeManagerDock.setWidget(self.ThemeManagerContents) self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
MainWindow.addDockWidget( MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock) QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock)
self.ThemeManagerDock.setVisible(self.settingsmanager.showThemeManager)
# Create the menu items # Create the menu items
self.FileNewItem = QtGui.QAction(MainWindow) self.FileNewItem = QtGui.QAction(MainWindow)
self.FileNewItem.setIcon( self.FileNewItem.setIcon(
@ -226,20 +221,18 @@ class Ui_MainWindow(object):
self.OptionsSettingsItem.setObjectName(u'OptionsSettingsItem') self.OptionsSettingsItem.setObjectName(u'OptionsSettingsItem')
self.ViewMediaManagerItem = QtGui.QAction(MainWindow) self.ViewMediaManagerItem = QtGui.QAction(MainWindow)
self.ViewMediaManagerItem.setCheckable(True) self.ViewMediaManagerItem.setCheckable(True)
self.ViewMediaManagerItem.setChecked( self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible())
self.settingsmanager.showMediaManager)
self.ViewMediaManagerItem.setIcon(MediaManagerIcon) self.ViewMediaManagerItem.setIcon(MediaManagerIcon)
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem')
self.ViewThemeManagerItem = QtGui.QAction(MainWindow) self.ViewThemeManagerItem = QtGui.QAction(MainWindow)
self.ViewThemeManagerItem.setCheckable(True) self.ViewThemeManagerItem.setCheckable(True)
self.ViewThemeManagerItem.setChecked( self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
self.settingsmanager.showThemeManager)
self.ViewThemeManagerItem.setIcon(ThemeManagerIcon) self.ViewThemeManagerItem.setIcon(ThemeManagerIcon)
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem') self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
self.ViewServiceManagerItem = QtGui.QAction(MainWindow) self.ViewServiceManagerItem = QtGui.QAction(MainWindow)
self.ViewServiceManagerItem.setCheckable(True) self.ViewServiceManagerItem.setCheckable(True)
self.ViewServiceManagerItem.setChecked( self.ViewServiceManagerItem.setChecked(
self.settingsmanager.showServiceManager) self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon(ServiceManagerIcon) self.ViewServiceManagerItem.setIcon(ServiceManagerIcon)
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem') self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
self.PluginItem = QtGui.QAction(MainWindow) self.PluginItem = QtGui.QAction(MainWindow)
@ -249,12 +242,14 @@ class Ui_MainWindow(object):
ContentsIcon = build_icon(u':/system/system_help_contents.png') ContentsIcon = build_icon(u':/system/system_help_contents.png')
self.HelpDocumentationItem.setIcon(ContentsIcon) self.HelpDocumentationItem.setIcon(ContentsIcon)
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem') self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem.setEnabled(False)
self.HelpAboutItem = QtGui.QAction(MainWindow) self.HelpAboutItem = QtGui.QAction(MainWindow)
AboutIcon = build_icon(u':/system/system_about.png') AboutIcon = build_icon(u':/system/system_about.png')
self.HelpAboutItem.setIcon(AboutIcon) self.HelpAboutItem.setIcon(AboutIcon)
self.HelpAboutItem.setObjectName(u'HelpAboutItem') self.HelpAboutItem.setObjectName(u'HelpAboutItem')
self.HelpOnlineHelpItem = QtGui.QAction(MainWindow) self.HelpOnlineHelpItem = QtGui.QAction(MainWindow)
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem') self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False)
self.HelpWebSiteItem = QtGui.QAction(MainWindow) self.HelpWebSiteItem = QtGui.QAction(MainWindow)
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem') self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
self.LanguageTranslateItem = QtGui.QAction(MainWindow) self.LanguageTranslateItem = QtGui.QAction(MainWindow)
@ -274,50 +269,36 @@ class Ui_MainWindow(object):
self.settingsmanager.showPreviewPanel) self.settingsmanager.showPreviewPanel)
self.ModeLiveItem = QtGui.QAction(MainWindow) self.ModeLiveItem = QtGui.QAction(MainWindow)
self.ModeLiveItem.setObjectName(u'ModeLiveItem') self.ModeLiveItem.setObjectName(u'ModeLiveItem')
self.FileImportMenu.addAction(self.ImportThemeItem) add_actions(self.FileImportMenu,
self.FileImportMenu.addAction(self.ImportLanguageItem) (self.ImportThemeItem, self.ImportLanguageItem))
self.FileExportMenu.addAction(self.ExportThemeItem) add_actions(self.FileExportMenu,
self.FileExportMenu.addAction(self.ExportLanguageItem) (self.ExportThemeItem, self.ExportLanguageItem))
self.FileMenu.addAction(self.FileNewItem) self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
self.FileMenu.addAction(self.FileOpenItem) self.FileSaveItem, self.FileSaveAsItem, None,
self.FileMenu.addAction(self.FileSaveItem) self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(),
self.FileMenu.addAction(self.FileSaveAsItem) self.FileExitItem)
self.FileMenu.addSeparator() add_actions(self.ViewModeMenu, [self.ModeLiveItem])
self.FileMenu.addAction(self.FileImportMenu.menuAction()) add_actions(self.OptionsViewMenu, (self.ViewModeMenu.menuAction(),
self.FileMenu.addAction(self.FileExportMenu.menuAction()) None, self.ViewMediaManagerItem, self.ViewServiceManagerItem,
self.FileMenu.addSeparator() self.ViewThemeManagerItem, None, self.action_Preview_Panel))
self.FileMenu.addAction(self.FileExitItem) add_actions(self.OptionsLanguageMenu, (self.LanguageEnglishItem, None,
self.ViewModeMenu.addAction(self.ModeLiveItem) self.LanguageTranslateItem))
self.OptionsViewMenu.addAction(self.ViewModeMenu.menuAction()) add_actions(self.OptionsMenu, (self.OptionsLanguageMenu.menuAction(),
self.OptionsViewMenu.addSeparator() self.OptionsViewMenu.menuAction(), None, self.OptionsSettingsItem))
self.OptionsViewMenu.addAction(self.ViewMediaManagerItem) add_actions(self.ToolsMenu,
self.OptionsViewMenu.addAction(self.ViewServiceManagerItem) (self.PluginItem, None, self.ToolsAddToolItem))
self.OptionsViewMenu.addAction(self.ViewThemeManagerItem) add_actions(self.HelpMenu,
self.OptionsViewMenu.addSeparator() (self.HelpDocumentationItem, self.HelpOnlineHelpItem, None,
self.OptionsViewMenu.addAction(self.action_Preview_Panel) self.HelpWebSiteItem, self.HelpAboutItem))
self.OptionsLanguageMenu.addAction(self.LanguageEnglishItem) add_actions(self.MenuBar,
self.OptionsLanguageMenu.addSeparator() (self.FileMenu.menuAction(), self.OptionsMenu.menuAction(),
self.OptionsLanguageMenu.addAction(self.LanguageTranslateItem) self.ToolsMenu.menuAction(), self.HelpMenu.menuAction()))
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())
# Initialise the translation # Initialise the translation
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
self.MediaToolBox.setCurrentIndex(0) self.MediaToolBox.setCurrentIndex(0)
# Connect up some signals and slots # Connect up some signals and slots
QtCore.QObject.connect(self.FileMenu,
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
QtCore.QObject.connect(self.FileExitItem, QtCore.QObject.connect(self.FileExitItem,
QtCore.SIGNAL(u'triggered()'), MainWindow.close) QtCore.SIGNAL(u'triggered()'), MainWindow.close)
QtCore.QObject.connect(self.ControlSplitter, QtCore.QObject.connect(self.ControlSplitter,
@ -383,12 +364,14 @@ class Ui_MainWindow(object):
self.actionLook_Feel.setText(self.trUtf8('Look && &Feel')) self.actionLook_Feel.setText(self.trUtf8('Look && &Feel'))
self.OptionsSettingsItem.setText(self.trUtf8('&Settings')) self.OptionsSettingsItem.setText(self.trUtf8('&Settings'))
self.ViewMediaManagerItem.setText(self.trUtf8('&Media Manager')) 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.ViewMediaManagerItem.setStatusTip(
self.trUtf8('Toggle the visibility of the Media Manager')) self.trUtf8('Toggle the visibility of the Media Manager'))
self.ViewMediaManagerItem.setShortcut(self.trUtf8('F8')) self.ViewMediaManagerItem.setShortcut(self.trUtf8('F8'))
self.ViewThemeManagerItem.setText(self.trUtf8('&Theme Manager')) 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.ViewThemeManagerItem.setStatusTip(
self.trUtf8('Toggle the visibility of the Theme Manager')) self.trUtf8('Toggle the visibility of the Theme Manager'))
self.ViewThemeManagerItem.setShortcut(self.trUtf8('F10')) self.ViewThemeManagerItem.setShortcut(self.trUtf8('F10'))
@ -399,7 +382,8 @@ class Ui_MainWindow(object):
self.trUtf8('Toggle the visibility of the Service Manager')) self.trUtf8('Toggle the visibility of the Service Manager'))
self.ViewServiceManagerItem.setShortcut(self.trUtf8('F9')) self.ViewServiceManagerItem.setShortcut(self.trUtf8('F9'))
self.action_Preview_Panel.setText(self.trUtf8('&Preview Panel')) 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.action_Preview_Panel.setStatusTip(
self.trUtf8('Toggle the visibility of the Preview Panel')) self.trUtf8('Toggle the visibility of the Preview Panel'))
self.action_Preview_Panel.setShortcut(self.trUtf8('F11')) self.action_Preview_Panel.setShortcut(self.trUtf8('F11'))
@ -440,19 +424,28 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMainWindow.__init__(self) QtGui.QMainWindow.__init__(self)
self.screens = screens self.screens = screens
self.applicationVersion = applicationVersion 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.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens) self.settingsmanager = SettingsManager(screens)
self.generalConfig = PluginConfig(u'General') self.displayManager = DisplayManager(screens)
self.videoDisplay = VideoDisplay(self, screens)
self.mainDisplay = MainDisplay(self, screens)
self.aboutForm = AboutForm(self, applicationVersion) self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self) self.settingsForm = SettingsForm(self.screens, self, self)
self.recentFiles = []
# Set up the path with plugins # Set up the path with plugins
pluginpath = AppLocation.get_directory(AppLocation.PluginsDir) pluginpath = AppLocation.get_directory(AppLocation.PluginsDir)
self.plugin_manager = PluginManager(pluginpath) self.plugin_manager = PluginManager(pluginpath)
self.plugin_helpers = {} self.plugin_helpers = {}
# Set up the interface # Set up the interface
self.setupUi(self) 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) self.pluginForm = PluginForm(self)
# Set up signals and slots # Set up signals and slots
QtCore.QObject.connect(self.ImportThemeItem, QtCore.QObject.connect(self.ImportThemeItem,
@ -485,6 +478,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.PreviewController.Panel, QtCore.QObject.connect(self.PreviewController.Panel,
QtCore.SIGNAL(u'visibilityChanged(bool)'), QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.action_Preview_Panel.setChecked) self.action_Preview_Panel.setChecked)
QtCore.QObject.connect(self.HelpWebSiteItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpAboutItem, QtCore.QObject.connect(self.HelpAboutItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked) QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.PluginItem, QtCore.QObject.connect(self.PluginItem,
@ -492,13 +487,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.OptionsSettingsItem, QtCore.QObject.connect(self.OptionsSettingsItem,
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked) QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.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.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'maindisplay_status_text'), self.showStatusMessage)
QtCore.QObject.connect(self.FileNewItem, QtCore.QObject.connect(self.FileNewItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService) self.ServiceManagerContents.onNewService)
@ -514,8 +511,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
#warning cyclic dependency #warning cyclic dependency
#RenderManager needs to call ThemeManager and #RenderManager needs to call ThemeManager and
#ThemeManager needs to call RenderManager #ThemeManager needs to call RenderManager
self.RenderManager = RenderManager(self.ThemeManagerContents, self.RenderManager = RenderManager(
self.screens) self.ThemeManagerContents, self.screens)
self.displayManager.renderManager = self.RenderManager
#Define the media Dock Manager #Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox) self.mediaDockManager = MediaDockManager(self.MediaToolBox)
log.info(u'Load Plugins') log.info(u'Load Plugins')
@ -524,9 +522,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_helpers[u'live'] = self.LiveController self.plugin_helpers[u'live'] = self.LiveController
self.plugin_helpers[u'render'] = self.RenderManager self.plugin_helpers[u'render'] = self.RenderManager
self.plugin_helpers[u'service'] = self.ServiceManagerContents 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'toolbox'] = self.mediaDockManager
self.plugin_helpers[u'maindisplay'] = self.mainDisplay self.plugin_helpers[u'maindisplay'] = self.displayManager.mainDisplay
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers) self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
# hook methods have to happen after find_plugins. Find plugins needs # hook methods have to happen after find_plugins. Find plugins needs
# the controllers hence the hooks have moved from setupUI() to here # the controllers hence the hooks have moved from setupUI() to here
@ -555,6 +553,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def versionCheck(self, version): def versionCheck(self, version):
""" """
Checks the version of the Application called from openlp.pyw Checks the version of the Application called from openlp.pyw
Triggered by delay thread.
""" """
app_version = self.applicationVersion[u'full'] app_version = self.applicationVersion[u'full']
version_text = unicode(self.trUtf8('Version %s of OpenLP is now ' version_text = unicode(self.trUtf8('Version %s of OpenLP is now '
@ -570,32 +569,48 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
Show the main form, as well as the display form Show the main form, as well as the display form
""" """
self.showMaximized() QtGui.QWidget.show(self)
#screen_number = self.getMonitorNumber() #screen_number = self.getMonitorNumber()
self.mainDisplay.setup() self.displayManager.setup()
self.videoDisplay.setup() if self.displayManager.mainDisplay.isVisible():
if self.mainDisplay.isVisible(): self.displayManager.mainDisplay.setFocus()
self.mainDisplay.setFocus()
self.activateWindow() 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) self.ServiceManagerContents.onLoadService(True)
self.videoDisplay.lower()
self.mainDisplay.raise_()
def blankCheck(self): def blankCheck(self):
if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ """
and str_to_bool(self.generalConfig.get_config(u'blank warning', False)): Check and display message if screen blank on setup.
Triggered by delay thread.
"""
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) self.LiveController.onBlankDisplay(True)
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
self.trUtf8('OpenLP Main Display Blanked'), self.trUtf8('OpenLP Main Display Blanked'),
self.trUtf8('The Main Display has been blanked out'), self.trUtf8('The Main Display has been blanked out'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
settings.endGroup()
def versionThread(self): def versionThread(self):
vT = VersionThread(self, self.applicationVersion, self.generalConfig) """
Start an initial setup thread to delay notifications
"""
vT = VersionThread(self, self.applicationVersion)
vT.start() vT.start()
def onHelpWebSiteClicked(self):
"""
Load the OpenLP website
"""
import webbrowser
webbrowser.open_new(u'http://openlp.org/')
def onHelpAboutItemClicked(self): def onHelpAboutItemClicked(self):
""" """
Show the About form Show the About form
@ -617,8 +632,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.settingsForm.exec_() self.settingsForm.exec_()
def screenChanged(self): def screenChanged(self):
"""
The screen has changed to so tell the displays to update_display
their locations
"""
self.RenderManager.update_display() self.RenderManager.update_display()
self.mainDisplay.setup() self.displayManager.setup()
self.setFocus()
self.activateWindow() self.activateWindow()
def closeEvent(self, event): def closeEvent(self, event):
@ -628,7 +648,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if self.serviceNotSaved: if self.serviceNotSaved:
ret = QtGui.QMessageBox.question(self, ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'), 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.StandardButtons(
QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Discard | QtGui.QMessageBox.Discard |
@ -636,20 +657,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.Save) QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save: if ret == QtGui.QMessageBox.Save:
self.ServiceManagerContents.onSaveService() self.ServiceManagerContents.onSaveService()
self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()
elif ret == QtGui.QMessageBox.Discard: elif ret == QtGui.QMessageBox.Discard:
self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()
else: else:
event.ignore() event.ignore()
else: else:
self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()
@ -662,6 +677,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Call the cleanup method to shutdown plugins. # Call the cleanup method to shutdown plugins.
log.info(u'cleanup plugins') log.info(u'cleanup plugins')
self.plugin_manager.finalise_plugins() self.plugin_manager.finalise_plugins()
# Save settings
self.saveSettings()
#Close down the displays
self.displayManager.close()
def serviceChanged(self, reset=False, serviceName=None): def serviceChanged(self, reset=False, serviceName=None):
""" """
@ -685,6 +704,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
title = u'%s - %s*' % (self.mainTitle, service_name) title = u'%s - %s*' % (self.mainTitle, service_name)
self.setWindowTitle(title) self.setWindowTitle(title)
def showStatusMessage(self, message):
self.StatusBar.showMessage(message)
def defaultThemeChanged(self, theme): def defaultThemeChanged(self, theme):
self.DefaultThemeLabel.setText( self.DefaultThemeLabel.setText(
u'%s %s' % (self.defaultThemeText, theme)) u'%s %s' % (self.defaultThemeText, theme))
@ -692,22 +714,75 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def toggleMediaManager(self, visible): def toggleMediaManager(self, visible):
if self.MediaManagerDock.isVisible() != visible: if self.MediaManagerDock.isVisible() != visible:
self.MediaManagerDock.setVisible(visible) self.MediaManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.MediaManagerDock.objectName(), visible)
def toggleServiceManager(self, visible): def toggleServiceManager(self, visible):
if self.ServiceManagerDock.isVisible() != visible: if self.ServiceManagerDock.isVisible() != visible:
self.ServiceManagerDock.setVisible(visible) self.ServiceManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.ServiceManagerDock.objectName(), visible)
def toggleThemeManager(self, visible): def toggleThemeManager(self, visible):
if self.ThemeManagerDock.isVisible() != visible: if self.ThemeManagerDock.isVisible() != visible:
self.ThemeManagerDock.setVisible(visible) self.ThemeManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.ThemeManagerDock.objectName(), visible)
def togglePreviewPanel(self): def togglePreviewPanel(self):
previewBool = self.PreviewController.Panel.isVisible() previewBool = self.PreviewController.Panel.isVisible()
self.PreviewController.Panel.setVisible(not previewBool) self.PreviewController.Panel.setVisible(not previewBool)
self.settingsmanager.togglePreviewPanel(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()

View File

@ -45,17 +45,17 @@ class MediaDockManager(object):
log.debug(u'Inserting %s dock' % media_item.title) log.debug(u'Inserting %s dock' % media_item.title)
match = False match = False
for dock_index in range(0, self.media_dock.count()): for dock_index in range(0, self.media_dock.count()):
if self.media_dock.widget(dock_index).ConfigSection == media_item.title.lower(): if self.media_dock.widget(dock_index).settingsSection == \
media_item.title.lower():
match = True match = True
break break
if not match: if not match:
self.media_dock.addItem(media_item, icon, media_item.title) self.media_dock.addItem(media_item, icon, media_item.title)
def remove_dock(self, name): def remove_dock(self, name):
log.debug(u'remove %s dock' % name) log.debug(u'remove %s dock' % name)
for dock_index in range(0, self.media_dock.count()): for dock_index in range(0, self.media_dock.count()):
if self.media_dock.widget(dock_index): if self.media_dock.widget(dock_index):
if self.media_dock.widget(dock_index).ConfigSection == name: if self.media_dock.widget(dock_index).settingsSection == name:
self.media_dock.widget(dock_index).hide() self.media_dock.widget(dock_index).hide()
self.media_dock.removeItem(dock_index) self.media_dock.removeItem(dock_index)

View File

@ -24,6 +24,7 @@
############################################################################### ###############################################################################
import logging import logging
import copy
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -36,6 +37,7 @@ class ScreenList(object):
def __init__(self): def __init__(self):
self.preview = None self.preview = None
self.current = None self.current = None
self.override = None
self.screen_list = [] self.screen_list = []
self.display_count = 0 self.display_count = 0
#actual display number #actual display number
@ -59,12 +61,31 @@ class ScreenList(object):
""" """
Set up the current screen dimensions Set up the current screen dimensions
""" """
log.debug(u'set_override_display %s', number, )
if number + 1 > self.display_count: if number + 1 > self.display_count:
self.current = self.screen_list[0] self.current = self.screen_list[0]
self.current_display = 0 self.current_display = 0
else: else:
self.current = self.screen_list[number] 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 self.current_display = number
if self.display_count == 1: if self.display_count == 1:
self.preview = self.screen_list[0] 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)

View File

@ -32,14 +32,15 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \ from openlp.core.lib import OpenLPToolbar, ServiceItem, contextMenuAction, \
contextMenuAction, Receiver, str_to_bool, build_icon, ItemCapabilities Receiver, build_icon, ItemCapabilities, SettingsManager
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
from openlp.core.utils import AppLocation
class ServiceManagerList(QtGui.QTreeWidget): class ServiceManagerList(QtGui.QTreeWidget):
def __init__(self, parent=None, name=None): def __init__(self, parent=None, name=None):
QtGui.QTreeWidget.__init__(self,parent) QtGui.QTreeWidget.__init__(self, parent)
self.parent = parent self.parent = parent
def keyPressEvent(self, event): def keyPressEvent(self, event):
@ -83,7 +84,7 @@ class ServiceManagerList(QtGui.QTreeWidget):
mimeData = QtCore.QMimeData() mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData) drag.setMimeData(mimeData)
mimeData.setText(u'ServiceManager') mimeData.setText(u'ServiceManager')
dropAction = drag.start(QtCore.Qt.CopyAction) drag.start(QtCore.Qt.CopyAction)
class ServiceManager(QtGui.QWidget): class ServiceManager(QtGui.QWidget):
""" """
@ -100,12 +101,10 @@ class ServiceManager(QtGui.QWidget):
self.parent = parent self.parent = parent
self.serviceItems = [] self.serviceItems = []
self.serviceName = u'' self.serviceName = u''
self.suffixes = []
self.droppos = 0 self.droppos = 0
#is a new service and has not been saved #is a new service and has not been saved
self.isNew = True 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.serviceNoteForm = ServiceNoteForm()
self.serviceItemEditForm = ServiceItemEditForm() self.serviceItemEditForm = ServiceItemEditForm()
#start with the layout #start with the layout
@ -186,29 +185,38 @@ class ServiceManager(QtGui.QWidget):
QtCore.QObject.connect(self.ServiceManagerList, QtCore.QObject.connect(self.ServiceManagerList,
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), 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.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) 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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems) QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
# Last little bits of setting up # Last little bits of setting up
self.config = PluginConfig(u'ServiceManager') self.service_theme = unicode(QtCore.QSettings().value(
self.servicePath = self.config.get_data_path() self.parent.serviceSettingsSection + u'/service theme',
self.service_theme = unicode( QtCore.QVariant(u'')).toString())
self.config.get_config(u'service theme', u'')) 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 #build the context menu
self.menu = QtGui.QMenu() self.menu = QtGui.QMenu()
self.editAction = self.menu.addAction(self.trUtf8('&Edit Item')) self.editAction = self.menu.addAction(self.trUtf8('&Edit Item'))
self.editAction.setIcon(build_icon(u':/general/general_edit.png')) self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item')) 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 = self.menu.addAction(self.trUtf8('&Notes'))
self.notesAction.setIcon(build_icon(u':/services/service_notes.png')) 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.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
self.sep1 = self.menu.addAction(u'') self.sep1 = self.menu.addAction(u'')
self.sep1.setSeparator(True) self.sep1.setSeparator(True)
@ -221,6 +229,9 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu = QtGui.QMenu(self.trUtf8(u'&Change Item Theme')) self.themeMenu = QtGui.QMenu(self.trUtf8(u'&Change Item Theme'))
self.menu.addMenu(self.themeMenu) self.menu.addMenu(self.themeMenu)
def supportedSuffixes(self, suffix):
self.suffixes.append(suffix)
def contextMenu(self, point): def contextMenu(self, point):
item = self.ServiceManagerList.itemAt(point) item = self.ServiceManagerList.itemAt(point)
if item is None: if item is None:
@ -257,9 +268,6 @@ class ServiceManager(QtGui.QWidget):
if action == self.liveAction: if action == self.liveAction:
self.makeLive() self.makeLive()
def onPresentationTypes(self, presentation_types):
self.presentation_types = presentation_types
def onServiceItemNoteForm(self): def onServiceItemNoteForm(self):
item, count = self.findServiceItem() item, count = self.findServiceItem()
self.serviceNoteForm.textEdit.setPlainText( self.serviceNoteForm.textEdit.setPlainText(
@ -297,6 +305,41 @@ class ServiceManager(QtGui.QWidget):
lookFor = 1 lookFor = 1
serviceIterator += 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): def onMoveSelectionUp(self):
""" """
Moves the selection up the window Moves the selection up the window
@ -411,13 +454,13 @@ class ServiceManager(QtGui.QWidget):
""" """
Clear the list to create a new service Clear the list to create a new service
""" """
if self.parent.serviceNotSaved and \ if self.parent.serviceNotSaved and QtCore.QSettings().value(
str_to_bool(PluginConfig(u'General'). self.parent.generalSettingsSection + u'/save prompt',
get_config(u'save prompt', u'False')): QtCore.QVariant(False)).toBool():
ret = QtGui.QMessageBox.question(self, ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'), self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your service is unsaved, do you want to save those ' self.trUtf8('Your service is unsaved, do you want to save '
'changes before creating a new one ?'), 'those changes before creating a new one?'),
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Save), QtGui.QMessageBox.Save),
@ -456,19 +499,22 @@ class ServiceManager(QtGui.QWidget):
for itemcount, item in enumerate(self.serviceItems): for itemcount, item in enumerate(self.serviceItems):
serviceitem = item[u'service_item'] serviceitem = item[u'service_item']
treewidgetitem = QtGui.QTreeWidgetItem(self.ServiceManagerList) treewidgetitem = QtGui.QTreeWidgetItem(self.ServiceManagerList)
if serviceitem.notes: if serviceitem.isValid:
icon = QtGui.QImage(serviceitem.icon) if serviceitem.notes:
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, icon = QtGui.QImage(serviceitem.icon)
QtCore.Qt.SmoothTransformation) icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
overlay = QtGui.QImage(':/services/service_item_notes.png') QtCore.Qt.SmoothTransformation)
overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio, overlay = QtGui.QImage(':/services/service_item_notes.png')
QtCore.Qt.SmoothTransformation) overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
painter = QtGui.QPainter(icon) QtCore.Qt.SmoothTransformation)
painter.drawImage(0, 0, overlay) painter = QtGui.QPainter(icon)
painter.end() painter.drawImage(0, 0, overlay)
treewidgetitem.setIcon(0, build_icon(icon)) painter.end()
treewidgetitem.setIcon(0, build_icon(icon))
else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation)
else: else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation) treewidgetitem.setIcon(0, build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.title) treewidgetitem.setText(0, serviceitem.title)
treewidgetitem.setToolTip(0, serviceitem.notes) treewidgetitem.setToolTip(0, serviceitem.notes)
treewidgetitem.setData(0, QtCore.Qt.UserRole, treewidgetitem.setData(0, QtCore.Qt.UserRole,
@ -496,17 +542,21 @@ class ServiceManager(QtGui.QWidget):
log.debug(u'onSaveService') log.debug(u'onSaveService')
if not quick or self.isNew: if not quick or self.isNew:
filename = QtGui.QFileDialog.getSaveFileName(self, 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)')) self.trUtf8(u'OpenLP Service Files (*.osz)'))
else: else:
filename = self.config.get_last_dir() filename = SettingsManager.get_last_dir(
self.parent.serviceSettingsSection)
if filename: if filename:
splittedFile = filename.split(u'.') splittedFile = filename.split(u'.')
if splittedFile[-1] != u'osz': if splittedFile[-1] != u'osz':
filename = filename + u'.osz' filename = filename + u'.osz'
filename = unicode(filename) filename = unicode(filename)
self.isNew = False self.isNew = False
self.config.set_last_dir(filename) SettingsManager.set_last_dir(
self.parent.serviceSettingsSection,
os.path.split(filename)[0])
service = [] service = []
servicefile = filename + u'.osd' servicefile = filename + u'.osd'
zip = None zip = None
@ -514,7 +564,8 @@ class ServiceManager(QtGui.QWidget):
try: try:
zip = zipfile.ZipFile(unicode(filename), 'w') zip = zipfile.ZipFile(unicode(filename), 'w')
for item in self.serviceItems: 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(): if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames(): for frame in item[u'service_item'].get_frames():
path_from = unicode(os.path.join( path_from = unicode(os.path.join(
@ -538,27 +589,52 @@ class ServiceManager(QtGui.QWidget):
pass #if not present do not worry pass #if not present do not worry
name = filename.split(os.path.sep) name = filename.split(os.path.sep)
self.serviceName = name[-1] self.serviceName = name[-1]
self.parent.addRecentFile(filename)
self.parent.serviceChanged(True, self.serviceName) self.parent.serviceChanged(True, self.serviceName)
def onQuickSaveService(self): def onQuickSaveService(self):
self.onSaveService(True) self.onSaveService(True)
def onLoadService(self, lastService=False): 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 Load an existing service from disk and rebuild the serviceitems. All
files retrieved from the zip file are placed in a temporary directory files retrieved from the zip file are placed in a temporary directory
and will only be used for this service. and will only be used for this service.
""" """
if lastService: if self.parent.serviceNotSaved:
filename = self.config.get_last_dir() ret = QtGui.QMessageBox.question(self,
else: self.trUtf8('Save Changes to Service?'),
filename = QtGui.QFileDialog.getOpenFileName( self.trUtf8('Your current service is unsaved, do you want to '
self, self.trUtf8('Open Service'), 'save the changes before opening a new one?'),
self.config.get_last_dir(), u'Services (*.osz)') 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) filename = unicode(filename)
name = filename.split(os.path.sep) name = filename.split(os.path.sep)
if filename: if filename:
self.config.set_last_dir(filename) SettingsManager.set_last_dir(
self.parent.serviceSettingsSection,
os.path.split(filename)[0])
zip = None zip = None
f = None f = None
try: try:
@ -582,8 +658,8 @@ class ServiceManager(QtGui.QWidget):
serviceitem = ServiceItem() serviceitem = ServiceItem()
serviceitem.RenderManager = self.parent.RenderManager serviceitem.RenderManager = self.parent.RenderManager
serviceitem.set_from_service(item, self.servicePath) serviceitem.set_from_service(item, self.servicePath)
if self.validateItem(serviceitem): self.validateItem(serviceitem)
self.addServiceItem(serviceitem) self.addServiceItem(serviceitem)
try: try:
if os.path.isfile(p_file): if os.path.isfile(p_file):
os.remove(p_file) os.remove(p_file)
@ -598,15 +674,18 @@ class ServiceManager(QtGui.QWidget):
zip.close() zip.close()
self.isNew = False self.isNew = False
self.serviceName = name[len(name) - 1] self.serviceName = name[len(name) - 1]
self.parent.addRecentFile(filename)
self.parent.serviceChanged(True, self.serviceName) self.parent.serviceChanged(True, self.serviceName)
def validateItem(self, serviceItem): def validateItem(self, serviceItem):
# print "---" """
# print serviceItem.name Validates the service item and if the suffix matches an accepted
# print serviceItem.title one it allows the item to be displayed
# print serviceItem.service_item_path """
# print serviceItem.service_item_type if serviceItem.is_command():
return True type = serviceItem._raw_frames[0][u'title'].split(u'.')[1]
if type not in self.suffixes:
serviceItem.isValid = False
def cleanUp(self): def cleanUp(self):
""" """
@ -626,7 +705,9 @@ class ServiceManager(QtGui.QWidget):
""" """
self.service_theme = unicode(self.ThemeComboBox.currentText()) self.service_theme = unicode(self.ThemeComboBox.currentText())
self.parent.RenderManager.set_service_theme(self.service_theme) 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() self.regenerateServiceItems()
def regenerateServiceItems(self): def regenerateServiceItems(self):
@ -638,12 +719,13 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems = [] self.serviceItems = []
self.isNew = True self.isNew = True
for item in tempServiceItems: 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 #Set to False as items may have changed rendering
#does not impact the saved song so True may also be valid #does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName) 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 Add a Service item to the list
@ -653,10 +735,9 @@ class ServiceManager(QtGui.QWidget):
""" """
sitem, count = self.findServiceItem() sitem, count = self.findServiceItem()
item.render() item.render()
if self.remoteEditTriggered: if replace:
item.merge(self.serviceItems[sitem][u'service_item']) item.merge(self.serviceItems[sitem][u'service_item'])
self.serviceItems[sitem][u'service_item'] = item self.serviceItems[sitem][u'service_item'] = item
self.remoteEditTriggered = False
self.repaintServiceList(sitem + 1, 0) self.repaintServiceList(sitem + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(item) self.parent.LiveController.replaceServiceManagerItem(item)
else: else:
@ -688,8 +769,17 @@ class ServiceManager(QtGui.QWidget):
Send the current item to the Preview slide controller Send the current item to the Preview slide controller
""" """
item, count = self.findServiceItem() item, count = self.findServiceItem()
self.parent.PreviewController.addServiceManagerItem( if self.serviceItems[item][u'service_item'].isValid:
self.serviceItems[item][u'service_item'], count) self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count)
else:
QtGui.QMessageBox.critical(self,
self.trUtf8('Missing Display Handler'),
self.trUtf8('Your item cannot be displayed as '
'there is no handler to display it'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
def getServiceItem(self): def getServiceItem(self):
""" """
@ -699,8 +789,6 @@ class ServiceManager(QtGui.QWidget):
if item == -1: if item == -1:
return False return False
else: else:
#Switch on remote edit update functionality.
self.remoteEditTriggered = True
return self.serviceItems[item][u'service_item'] return self.serviceItems[item][u'service_item']
def makeLive(self): def makeLive(self):
@ -708,15 +796,26 @@ class ServiceManager(QtGui.QWidget):
Send the current item to the Live slide controller Send the current item to the Live slide controller
""" """
item, count = self.findServiceItem() item, count = self.findServiceItem()
self.parent.LiveController.addServiceManagerItem( if self.serviceItems[item][u'service_item'].isValid:
self.serviceItems[item][u'service_item'], count) self.parent.LiveController.addServiceManagerItem(
if str_to_bool(PluginConfig(u'General'). self.serviceItems[item][u'service_item'], count)
get_config(u'auto preview', u'False')): if QtCore.QSettings().value(
item += 1 self.parent.generalSettingsSection + u'/auto preview',
if self.serviceItems and item < len(self.serviceItems) and \ QtCore.QVariant(False)).toBool():
self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.AllowsPreview): item += 1
self.parent.PreviewController.addServiceManagerItem( if self.serviceItems and item < len(self.serviceItems) and \
self.serviceItems[item][u'service_item'], 0) self.serviceItems[item][u'service_item'].is_capable(
ItemCapabilities.AllowsPreview):
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], 0)
else:
QtGui.QMessageBox.critical(self,
self.trUtf8('Missing Display Handler'),
self.trUtf8('Your item cannot be displayed as '
'there is no handler to display it'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
def remoteEdit(self): def remoteEdit(self):
""" """
@ -725,14 +824,10 @@ class ServiceManager(QtGui.QWidget):
item, count = self.findServiceItem() item, count = self.findServiceItem()
if self.serviceItems[item][u'service_item']\ if self.serviceItems[item][u'service_item']\
.is_capable(ItemCapabilities.AllowsEdit): .is_capable(ItemCapabilities.AllowsEdit):
self.remoteEditTriggered = True
Receiver.send_message(u'%s_edit' % 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 ) self.serviceItems[item][u'service_item'].editId )
def onRemoteEditClear(self):
self.remoteEditTriggered = False
def findServiceItem(self): def findServiceItem(self):
""" """
Finds a ServiceItem in the list Finds a ServiceItem in the list
@ -774,8 +869,9 @@ class ServiceManager(QtGui.QWidget):
if link.hasText(): if link.hasText():
plugin = event.mimeData().text() plugin = event.mimeData().text()
item = self.ServiceManagerList.itemAt(event.pos()) item = self.ServiceManagerList.itemAt(event.pos())
#ServiceManager started the drag and drop
if plugin == u'ServiceManager': if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem() startpos, startCount = self.findServiceItem()
if item is None: if item is None:
endpos = len(self.serviceItems) endpos = len(self.serviceItems)
else: else:
@ -789,11 +885,28 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems.insert(newpos, serviceItem) self.serviceItems.insert(newpos, serviceItem)
self.repaintServiceList(endpos, startCount) self.repaintServiceList(endpos, startCount)
else: else:
#we are not over anything so drop
replace = False
if item == None: if item == None:
self.droppos = len(self.serviceItems) self.droppos = len(self.serviceItems)
else: else:
self.droppos = self._getParentItemData(item) #we are over somthing so lets investigate
Receiver.send_message(u'%s_add_service_item' % plugin) 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): def updateThemeList(self, theme_list):
""" """
@ -834,3 +947,20 @@ class ServiceManager(QtGui.QWidget):
return item.data(0, QtCore.Qt.UserRole).toInt()[0] return item.data(0, QtCore.Qt.UserRole).toInt()[0]
else: else:
return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] 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)

View File

@ -27,7 +27,7 @@ import logging
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.ui import GeneralTab, ThemesTab from openlp.core.ui import GeneralTab, ThemesTab, DisplayTab
from settingsdialog import Ui_SettingsDialog from settingsdialog import Ui_SettingsDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -43,6 +43,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
# Themes tab # Themes tab
self.ThemesTab = ThemesTab(mainWindow) self.ThemesTab = ThemesTab(mainWindow)
self.addTab(u'Themes', self.ThemesTab) self.addTab(u'Themes', self.ThemesTab)
# Display tab
self.DisplayTab = DisplayTab(screens)
self.addTab(u'Display', self.DisplayTab)
def addTab(self, name, tab): def addTab(self, name, tab):
log.info(u'Adding %s tab' % tab.tabTitle) log.info(u'Adding %s tab' % tab.tabTitle)

View File

@ -30,19 +30,9 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import ItemCapabilities from openlp.core.ui import HideMode
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
class HideMode(object): ItemCapabilities
"""
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
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -54,11 +44,12 @@ class SlideList(QtGui.QTableWidget):
def __init__(self, parent=None, name=None): def __init__(self, parent=None, name=None):
QtGui.QTableWidget.__init__(self, parent.Controller) QtGui.QTableWidget.__init__(self, parent.Controller)
self.parent = parent self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', self.hotkey_map = {
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item', QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event): def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent: if type(event) == QtGui.QKeyEvent:
@ -95,7 +86,7 @@ class SlideController(QtGui.QWidget):
self.settingsmanager = settingsmanager self.settingsmanager = settingsmanager
self.isLive = isLive self.isLive = isLive
self.parent = parent self.parent = parent
self.songsconfig = PluginConfig(u'Songs') self.mainDisplay = self.parent.displayManager.mainDisplay
self.loop_list = [ self.loop_list = [
u'Start Loop', u'Start Loop',
u'Stop Loop', u'Stop Loop',
@ -124,11 +115,11 @@ class SlideController(QtGui.QWidget):
if self.isLive: if self.isLive:
self.TypeLabel.setText(self.trUtf8('Live')) self.TypeLabel.setText(self.trUtf8('Live'))
self.split = 1 self.split = 1
prefix = u'live_slidecontroller' self.type_prefix = u'live'
else: else:
self.TypeLabel.setText(self.trUtf8('Preview')) self.TypeLabel.setText(self.trUtf8('Preview'))
self.split = 0 self.split = 0
prefix = u'preview_slidecontroller' self.type_prefix = u'preview'
self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;') self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter) self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.PanelLayout.addWidget(self.TypeLabel) self.PanelLayout.addWidget(self.TypeLabel)
@ -152,13 +143,15 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.horizontalHeader().setVisible(False) self.PreviewListWidget.horizontalHeader().setVisible(False)
self.PreviewListWidget.verticalHeader().setVisible(False) self.PreviewListWidget.verticalHeader().setVisible(False)
self.PreviewListWidget.setColumnWidth(1, self.labelWidth) 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.isLive = self.isLive
self.PreviewListWidget.setObjectName(u'PreviewListWidget') self.PreviewListWidget.setObjectName(u'PreviewListWidget')
self.PreviewListWidget.setSelectionBehavior(1) self.PreviewListWidget.setSelectionBehavior(1)
self.PreviewListWidget.setEditTriggers( self.PreviewListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers) QtGui.QAbstractItemView.NoEditTriggers)
self.PreviewListWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.PreviewListWidget.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff)
self.PreviewListWidget.setAlternatingRowColors(True) self.PreviewListWidget.setAlternatingRowColors(True)
self.ControllerLayout.addWidget(self.PreviewListWidget) self.ControllerLayout.addWidget(self.PreviewListWidget)
# Build the full toolbar # Build the full toolbar
@ -195,8 +188,6 @@ class SlideController(QtGui.QWidget):
self.hideButton = self.Toolbar.addToolbarButton( self.hideButton = self.Toolbar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png', u'Hide screen', u':/slides/slide_desktop.png',
self.trUtf8('Hide Screen'), self.onHideDisplay, True) 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: if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton( self.Toolbar.addToolbarButton(
@ -209,7 +200,7 @@ class SlideController(QtGui.QWidget):
if isLive: if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Separator') self.Toolbar.addToolbarSeparator(u'Loop Separator')
self.Toolbar.addToolbarButton( 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.trUtf8('Start continuous loop'), self.onStartLoop)
self.Toolbar.addToolbarButton( self.Toolbar.addToolbarButton(
u'Stop Loop', u':/media/media_stop.png', u'Stop Loop', u':/media/media_stop.png',
@ -220,19 +211,30 @@ class SlideController(QtGui.QWidget):
self.Toolbar.addToolbarWidget( self.Toolbar.addToolbarWidget(
u'Image SpinBox', self.DelaySpinBox) u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(self.trUtf8('s')) 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) self.ControllerLayout.addWidget(self.Toolbar)
#Build a Media ToolBar #Build a Media ToolBar
self.Mediabar = OpenLPToolbar(self) self.Mediabar = OpenLPToolbar(self)
self.Mediabar.addToolbarButton( 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.trUtf8('Start playing media'), self.onMediaPlay)
self.Mediabar.addToolbarButton( 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.trUtf8('Start playing media'), self.onMediaPause)
self.Mediabar.addToolbarButton( 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) 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: if not self.isLive:
self.seekSlider = Phonon.SeekSlider() self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
@ -251,13 +253,15 @@ class SlideController(QtGui.QWidget):
self.SongMenu.setText(self.trUtf8('Go to Verse')) self.SongMenu.setText(self.trUtf8('Go to Verse'))
self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup) self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu) 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']) self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
# Screen preview area # Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame = QtGui.QFrame(self.Splitter)
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225)) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy( 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.setFrameShape(QtGui.QFrame.StyledPanel)
self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken) self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken)
self.PreviewFrame.setObjectName(u'PreviewFrame') self.PreviewFrame.setObjectName(u'PreviewFrame')
@ -302,30 +306,50 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
if isLive: if isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
Receiver.send_message(u'request_spin_delay') self.receiveSpinDelay)
if isLive: if isLive:
self.Toolbar.makeWidgetsInvisible(self.loop_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
else: else:
self.Toolbar.makeWidgetsInvisible(self.song_edit_list) self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
self.Mediabar.setVisible(False) self.Mediabar.setVisible(False)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.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.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.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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_previous_noloop' % prefix), QtCore.SIGNAL(u'slidecontroller_%s_previous_noloop' %
self.type_prefix),
self.onSlideSelectedPreviousNoloop) self.onSlideSelectedPreviousNoloop)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.QObject.connect(self.Splitter,
QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter) QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -383,8 +407,9 @@ class SlideController(QtGui.QWidget):
self.Toolbar.makeWidgetsInvisible(self.loop_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
if item.is_text(): if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.loop_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \ if QtCore.QSettings().value(
and len(self.slideList) > 0: self.parent.songsSettingsSection + u'/show songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
self.Toolbar.makeWidgetsVisible([u'Song Menu']) self.Toolbar.makeWidgetsVisible([u'Song Menu'])
if item.is_capable(ItemCapabilities.AllowsLoop) and \ if item.is_capable(ItemCapabilities.AllowsLoop) and \
len(item.get_frames()) > 1: len(item.get_frames()) > 1:
@ -392,7 +417,7 @@ class SlideController(QtGui.QWidget):
if item.is_media(): if item.is_media():
self.Toolbar.setVisible(False) self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True) self.Mediabar.setVisible(True)
#self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) #self.volumeSlider.setAudioOutput(self.mainDisplay.videoDisplay.audio)
def enablePreviewToolBar(self, item): def enablePreviewToolBar(self, item):
""" """
@ -460,20 +485,19 @@ class SlideController(QtGui.QWidget):
Loads a ServiceItem into the system from ServiceManager Loads a ServiceItem into the system from ServiceManager
Display the slide number passed Display the slide number passed
""" """
log.debug(u'processsManagerItem') log.debug(u'processManagerItem')
self.onStopLoop()
#If old item was a command tell it to stop #If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command(): if self.serviceItem and self.serviceItem.is_command():
self.onMediaStop() self.onMediaStop()
if serviceItem.is_media(): if serviceItem.is_media():
self.onMediaStart(serviceItem) self.onMediaStart(serviceItem)
elif serviceItem.is_command(): if self.isLive:
if self.isLive: blanked = self.blankButton.isChecked()
blanked = self.blankButton.isChecked() else:
else: blanked = False
blanked = False Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), \ [serviceItem, self.isLive, blanked, slideno])
[serviceItem.title, serviceItem.get_frame_path(),
serviceItem.get_frame_title(), slideno, self.isLive, blanked])
self.slideList = {} self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at #Set pointing cursor when we have somthing to point at
@ -537,7 +561,7 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.resizeRowsToContents() self.PreviewListWidget.resizeRowsToContents()
self.PreviewListWidget.setColumnWidth(0, self.labelWidth) self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, self.PreviewListWidget.setColumnWidth(1,
self.PreviewListWidget.viewport().size().width() - self.labelWidth ) self.PreviewListWidget.viewport().size().width() - self.labelWidth)
if slideno > self.PreviewListWidget.rowCount(): if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
else: else:
@ -545,9 +569,29 @@ class SlideController(QtGui.QWidget):
self.enableToolBar(serviceItem) self.enableToolBar(serviceItem)
self.onSlideSelected() self.onSlideSelected()
self.PreviewListWidget.setFocus() 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)) 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 #Screen event methods
def onSlideSelectedFirst(self): def onSlideSelectedFirst(self):
@ -556,60 +600,113 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_first' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_first'% \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
self.PreviewListWidget.selectRow(0) self.PreviewListWidget.selectRow(0)
self.onSlideSelected() 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 Handle the blank screen button
""" """
log.debug(u'onBlankDisplay %d' % force) log.debug(u'onBlankDisplay %d' % checked)
if force: self.hideButton.setChecked(False)
self.blankButton.setChecked(True) self.themeButton.setChecked(False)
self.blankScreen(HideMode.Blank, self.blankButton.isChecked()) QtCore.QSettings().setValue(
self.parent.generalConfig.set_config(u'screen blank', self.parent.generalSettingsSection + u'/screen blank',
self.blankButton.isChecked()) 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 Handle the Theme screen button
""" """
log.debug(u'onThemeDisplay %d' % force) log.debug(u'onThemeDisplay %d' % checked)
if force: self.blankButton.setChecked(False)
self.themeButton.setChecked(True) self.hideButton.setChecked(False)
self.blankScreen(HideMode.Theme, self.themeButton.isChecked()) 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 Handle the Hide screen button
""" """
log.debug(u'onHideDisplay %d' % force) log.debug(u'onHideDisplay %d' % checked)
if force: self.blankButton.setChecked(False)
self.hideButton.setChecked(True) self.themeButton.setChecked(False)
if self.hideButton.isChecked(): if checked:
self.parent.mainDisplay.hideDisplay() Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.hidePlugin(True)
else: else:
self.parent.mainDisplay.showDisplay() Receiver.send_message(u'maindisplay_show')
self.hidePlugin(False)
def blankScreen(self, blankType, blanked=False): def blankPlugin(self, blank):
""" """
Blank the display screen. Blank the display screen.
""" """
if self.serviceItem is not None: if self.serviceItem is not None:
if self.serviceItem.is_command(): if blank:
if blanked: Receiver.send_message(u'%s_blank'
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) % self.serviceItem.name.lower(),
else: [self.serviceItem, self.isLive])
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
else: else:
self.parent.mainDisplay.blankDisplay(blankType, blanked) Receiver.send_message(u'%s_unblank'
else: % self.serviceItem.name.lower(),
self.parent.mainDisplay.blankDisplay(blankType, blanked) [self.serviceItem, self.isLive])
def hidePlugin(self, hide):
"""
Blank the display screen.
"""
if self.serviceItem is not None:
if hide:
Receiver.send_message(u'%s_hide'
% self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
else:
Receiver.send_message(u'%s_unblank'
% self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
def onSlideSelected(self): def onSlideSelected(self):
""" """
@ -619,9 +716,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow() row = self.PreviewListWidget.currentRow()
self.selectedRow = 0 self.selectedRow = 0
if row > -1 and row < self.PreviewListWidget.rowCount(): 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: 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() self.updatePreview()
else: else:
before = time.time() before = time.time()
@ -630,13 +727,18 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
else: else:
if isinstance(frame[u'main'], basestring): if isinstance(frame[u'main'], basestring):
self.SlidePreview.setPixmap(QtGui.QPixmap(frame[u'main'])) self.SlidePreview.setPixmap(
QtGui.QPixmap(frame[u'main']))
else: else:
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) self.SlidePreview.setPixmap(
log.log(15, u'Slide Rendering took %4s' % (time.time() - before)) QtGui.QPixmap.fromImage(frame[u'main']))
log.log(
15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive: if self.isLive:
self.parent.mainDisplay.frameView(frame, True) self.mainDisplay.frameView(frame, True)
self.selectedRow = row self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix,
row)
def onSlideChange(self, row): def onSlideChange(self, row):
""" """
@ -644,6 +746,8 @@ class SlideController(QtGui.QWidget):
""" """
self.PreviewListWidget.selectRow(row) self.PreviewListWidget.selectRow(row)
self.updatePreview() self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix,
row)
def updatePreview(self): def updatePreview(self):
rm = self.parent.RenderManager rm = self.parent.RenderManager
@ -673,9 +777,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_next' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() + 1 row = self.PreviewListWidget.currentRow() + 1
@ -697,9 +801,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(
u'%s_previous'% self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() - 1 row = self.PreviewListWidget.currentRow() - 1
@ -717,9 +821,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_last' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_last' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
self.PreviewListWidget.selectRow( self.PreviewListWidget.selectRow(
@ -738,7 +842,9 @@ class SlideController(QtGui.QWidget):
""" """
Stop the timer loop running Stop the timer loop running
""" """
self.killTimer(self.timer_id) if self.timer_id != 0:
self.killTimer(self.timer_id)
self.timer_id = 0
def timerEvent(self, event): def timerEvent(self, event):
""" """
@ -748,9 +854,12 @@ class SlideController(QtGui.QWidget):
self.onSlideSelectedNext() self.onSlideSelectedNext()
def onEditSong(self): def onEditSong(self):
"""
From the preview display requires the service Item to be editied
"""
self.songEdit = True self.songEdit = True
Receiver.send_message(u'%s_edit' % self.serviceItem.name, u'P:%s' % Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
self.serviceItem.editId ) u'P:%s' % self.serviceItem.editId)
def onGoLive(self): def onGoLive(self):
""" """
@ -762,10 +871,13 @@ class SlideController(QtGui.QWidget):
self.serviceItem, row) self.serviceItem, row)
def onMediaStart(self, item): def onMediaStart(self, item):
"""
Respond to the arrival of a media service item
"""
log.debug(u'SlideController onMediaStart')
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \ Receiver.send_message(u'videodisplay_start',
[item.title, item.get_frame_path(), [item, self.blankButton.isChecked()])
item.get_frame_title(), self.isLive, self.blankButton.isChecked()])
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
@ -776,22 +888,34 @@ class SlideController(QtGui.QWidget):
self.onMediaPlay() self.onMediaPlay()
def onMediaPause(self): def onMediaPause(self):
"""
Respond to the Pause from the media Toolbar
"""
log.debug(u'SlideController onMediaPause')
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_pause'% self.serviceItem.name.lower()) Receiver.send_message(u'videodisplay_pause')
else: else:
self.mediaObject.pause() self.mediaObject.pause()
def onMediaPlay(self): def onMediaPlay(self):
"""
Respond to the Play from the media Toolbar
"""
log.debug(u'SlideController onMediaPlay')
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_play'% self.serviceItem.name.lower(), self.isLive) Receiver.send_message(u'videodisplay_play')
else: else:
self.SlidePreview.hide() self.SlidePreview.hide()
self.video.show() self.video.show()
self.mediaObject.play() self.mediaObject.play()
def onMediaStop(self): def onMediaStop(self):
"""
Respond to the Stop from the media Toolbar
"""
log.debug(u'SlideController onMediaStop')
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive) Receiver.send_message(u'videodisplay_stop')
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.video.hide() self.video.hide()

View File

@ -33,10 +33,10 @@ from PyQt4 import QtCore, QtGui
from openlp.core.ui import AmendThemeForm from openlp.core.ui import AmendThemeForm
from openlp.core.theme import Theme 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, \ ThemeXML, str_to_bool, get_text_file_string, build_icon, Receiver, \
contextMenuSeparator contextMenuSeparator, SettingsManager
from openlp.core.utils import ConfigHelper from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -47,6 +47,7 @@ class ThemeManager(QtGui.QWidget):
def __init__(self, parent): def __init__(self, parent):
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
self.parent = parent self.parent = parent
self.settingsSection = u'themes'
self.Layout = QtGui.QVBoxLayout(self) self.Layout = QtGui.QVBoxLayout(self)
self.Layout.setSpacing(0) self.Layout.setSpacing(0)
self.Layout.setMargin(0) self.Layout.setMargin(0)
@ -102,19 +103,18 @@ class ThemeManager(QtGui.QWidget):
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.changeGlobalFromScreen) self.changeGlobalFromScreen)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab) QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
#Variables #Variables
self.themelist = [] 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.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.checkThemesExists(self.thumbPath)
self.amendThemeForm.path = self.path self.amendThemeForm.path = self.path
# Last little bits of setting up # Last little bits of setting up
self.config = PluginConfig(u'themes') self.global_theme = unicode(QtCore.QSettings().value(
self.servicePath = self.config.get_data_path() self.settingsSection + u'/global theme',
self.global_theme = unicode( QtCore.QVariant(u'')).toString())
self.config.get_config(u'global theme', u''))
def changeGlobalFromTab(self, themeName): def changeGlobalFromTab(self, themeName):
log.debug(u'changeGlobalFromTab %s', themeName) log.debug(u'changeGlobalFromTab %s', themeName)
@ -146,9 +146,10 @@ class ThemeManager(QtGui.QWidget):
self.ThemeListWidget.item(count).text()) self.ThemeListWidget.item(count).text())
name = u'%s (%s)' % (self.global_theme, self.trUtf8('default')) name = u'%s (%s)' % (self.global_theme, self.trUtf8('default'))
self.ThemeListWidget.item(count).setText(name) self.ThemeListWidget.item(count).setText(name)
self.config.set_config(u'global theme', self.global_theme) QtCore.QSettings().setValue(
Receiver.send_message( self.settingsSection + u'/global theme',
u'update_global_theme', self.global_theme) QtCore.QVariant(self.global_theme))
Receiver.send_message(u'theme_update_global', self.global_theme)
self.pushThemes() self.pushThemes()
def onAddTheme(self): def onAddTheme(self):
@ -168,8 +169,9 @@ class ThemeManager(QtGui.QWidget):
self.amendThemeForm.exec_() self.amendThemeForm.exec_()
def onDeleteTheme(self): def onDeleteTheme(self):
self.global_theme = unicode( self.global_theme = unicode(QtCore.QSettings().value(
self.config.get_config(u'global theme', u'')) self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
item = self.ThemeListWidget.currentItem() item = self.ThemeListWidget.currentItem()
if item: if item:
theme = unicode(item.text()) theme = unicode(item.text())
@ -222,10 +224,10 @@ class ThemeManager(QtGui.QWidget):
theme = unicode(item.data(QtCore.Qt.UserRole).toString()) theme = unicode(item.data(QtCore.Qt.UserRole).toString())
path = QtGui.QFileDialog.getExistingDirectory(self, path = QtGui.QFileDialog.getExistingDirectory(self,
unicode(self.trUtf8('Save Theme - (%s)')) % theme, unicode(self.trUtf8('Save Theme - (%s)')) % theme,
self.config.get_last_dir(1) ) SettingsManager.get_last_dir(self.settingsSection, 1))
path = unicode(path) path = unicode(path)
if 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') themePath = os.path.join(path, theme + u'.theme')
zip = None zip = None
try: try:
@ -234,7 +236,8 @@ class ThemeManager(QtGui.QWidget):
for root, dirs, files in os.walk(source): for root, dirs, files in os.walk(source):
for name in files: for name in files:
zip.write( zip.write(
os.path.join(source, name), os.path.join(theme, name)) os.path.join(source, name),
os.path.join(theme, name))
except: except:
log.exception(u'Export Theme Failed') log.exception(u'Export Theme Failed')
finally: finally:
@ -244,11 +247,12 @@ class ThemeManager(QtGui.QWidget):
def onImportTheme(self): def onImportTheme(self):
files = QtGui.QFileDialog.getOpenFileNames( files = QtGui.QFileDialog.getOpenFileNames(
self, self.trUtf8('Select Theme Import File'), 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)) log.info(u'New Themes %s', unicode(files))
if files: if files:
for file in 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.unzipTheme(file, self.path)
self.loadThemes() self.loadThemes()
@ -291,7 +295,7 @@ class ThemeManager(QtGui.QWidget):
self.pushThemes() self.pushThemes()
def pushThemes(self): def pushThemes(self):
Receiver.send_message(u'update_themes', self.getThemes() ) Receiver.send_message(u'theme_update_list', self.getThemes())
def getThemes(self): def getThemes(self):
return self.themelist return self.themelist

View File

@ -103,7 +103,7 @@ class ThemesTab(SettingsTab):
QtCore.QObject.connect(self.DefaultComboBox, QtCore.QObject.connect(self.DefaultComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onDefaultComboBoxChanged) QtCore.SIGNAL(u'activated(int)'), self.onDefaultComboBoxChanged)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self): def retranslateUi(self):
self.GlobalGroupBox.setTitle(self.trUtf8('Global theme')) self.GlobalGroupBox.setTitle(self.trUtf8('Global theme'))
@ -123,9 +123,13 @@ class ThemesTab(SettingsTab):
'songs.')) 'songs.'))
def load(self): def load(self):
self.theme_level = int(self.config.get_config(u'theme level', settings = QtCore.QSettings()
ThemeLevel.Global)) settings.beginGroup(self.settingsSection)
self.global_theme = self.config.get_config(u'global theme', u'') 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: if self.theme_level == ThemeLevel.Global:
self.GlobalLevelRadioButton.setChecked(True) self.GlobalLevelRadioButton.setChecked(True)
elif self.theme_level == ThemeLevel.Service: elif self.theme_level == ThemeLevel.Service:
@ -134,14 +138,19 @@ class ThemesTab(SettingsTab):
self.SongLevelRadioButton.setChecked(True) self.SongLevelRadioButton.setChecked(True)
def save(self): def save(self):
self.config.set_config(u'theme level', self.theme_level) settings = QtCore.QSettings()
self.config.set_config(u'global theme',self.global_theme) settings.beginGroup(self.settingsSection)
Receiver.send_message(u'update_global_theme', self.global_theme) 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.parent.RenderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
def postSetUp(self): 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): def onSongLevelButtonPressed(self):
self.theme_level = ThemeLevel.Song self.theme_level = ThemeLevel.Song
@ -169,7 +178,9 @@ class ThemesTab(SettingsTab):
Called from ThemeManager when the Themes have changed Called from ThemeManager when the Themes have changed
""" """
#reload as may have been triggered by the ThemeManager #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() self.DefaultComboBox.clear()
for theme in theme_list: for theme in theme_list:
self.DefaultComboBox.addItem(theme) self.DefaultComboBox.addItem(theme)

View File

@ -67,7 +67,8 @@ class AppLocation(object):
else: else:
try: try:
from xdg import BaseDirectory 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: except ImportError:
path = os.path.join(os.getenv(u'HOME'), u'.openlp') path = os.path.join(os.getenv(u'HOME'), u'.openlp')
return path return path
@ -103,27 +104,44 @@ class AppLocation(object):
plugin_path = os.path.split(openlp.__file__)[0] plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path 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 Check the latest version of OpenLP against the version file on the OpenLP
site. site.
``config``
The OpenLP config object.
``current_version`` ``current_version``
The current version of OpenLP. The current version of OpenLP.
""" """
version_string = current_version[u'full'] version_string = current_version[u'full']
#set to prod in the distribution confif file. #set to prod in the distribution config file.
last_test = config.get_config(u'last version test', datetime.now().date()) 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()) 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: if last_test != this_test:
version_string = u'' version_string = u''
if current_version[u'build']: 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: else:
req = urllib2.Request(u'http://www.openlp.org/files/version.txt') req = urllib2.Request(u'http://www.openlp.org/files/version.txt')
req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full']) req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full'])
@ -155,7 +173,21 @@ def variant_to_unicode(variant):
string = string_to_unicode(string) string = string_to_unicode(string)
return string return string
from registry import Registry def add_actions(target, actions):
from confighelper import ConfigHelper """
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']

View File

@ -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__

View File

@ -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()

View File

@ -31,7 +31,8 @@ from sqlalchemy import *
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper 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 * from openlp.plugins.bibles.lib.models import *
class BaseModel(object): class BaseModel(object):
@ -111,9 +112,8 @@ def init_models(url):
class MigrateBibles(): class MigrateBibles():
def __init__(self, display): def __init__(self, display):
self.display = display self.display = display
self.config = PluginConfig(u'Bibles') self.data_path = AppLocation.get_section_data_path(u'bibles')
self.data_path = self.config.get_data_path() self.database_files = SettingsManager.get_files(u'bibles', u'.sqlite')
self.database_files = self.config.get_files(u'sqlite')
print self.database_files print self.database_files
def progress(self, text): def progress(self, text):

View File

@ -23,7 +23,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from openlp.core.utils import ConfigHelper from openlp.core.utils import AppLocation
class MigrateFiles(): class MigrateFiles():
def __init__(self, display): def __init__(self, display):
@ -36,14 +36,19 @@ class MigrateFiles():
def _initial_setup(self): def _initial_setup(self):
self.display.output(u'Initial Setup started') 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') 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') self.display.sub_output(u'Config created')
ConfigHelper.get_config(u'videos', u'data path') # Media doesn't use a directory like the other plugins.
self.display.sub_output(u'videos created') #media_path = AppLocation.get_section_data_path(u'media')
ConfigHelper.get_config(u'images', u'data path') #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') 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.sub_output(u'presentations created')
self.display.output(u'Initial Setup finished') self.display.output(u'Initial Setup finished')

View File

@ -31,7 +31,8 @@ from sqlalchemy import *
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation 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, \ from openlp.plugins.songs.lib.models import metadata, songs_table, Song, \
Author, Topic, Book Author, Topic, Book
from openlp.plugins.songs.lib.tables import * from openlp.plugins.songs.lib.tables import *
@ -46,7 +47,7 @@ def init_models(url):
mapper(TAuthor, temp_authors_table) mapper(TAuthor, temp_authors_table)
mapper(Book, song_books_table) mapper(Book, song_books_table)
mapper(Song, songs_table, mapper(Song, songs_table,
properties={'authors': relation(Author, backref='songs', properties={'authors': relation(Author, backref='songs',
secondary=authors_songs_table), secondary=authors_songs_table),
'book': relation(Book, backref='songs'), 'book': relation(Book, backref='songs'),
'topics': relation(Topic, backref='songs', 'topics': relation(Topic, backref='songs',
@ -111,9 +112,8 @@ class TSongAuthor(BaseModel):
class MigrateSongs(): class MigrateSongs():
def __init__(self, display): def __init__(self, display):
self.display = display self.display = display
self.config = PluginConfig(u'Songs') self.data_path = AppLocation.get_section_data_path(u'songs')
self.data_path = self.config.get_data_path() self.database_files = SettingsManager.get_files(u'songs', u'.sqlite')
self.database_files = self.config.get_files(u'sqlite')
print self.database_files print self.database_files
def process(self): def process(self):
@ -156,13 +156,13 @@ class MigrateSongs():
print songs_temp.songtitle print songs_temp.songtitle
aa = self.session.execute( aa = self.session.execute(
u'select * from songauthors_temp where songid =' + \ u'select * from songauthors_temp where songid =' + \
unicode(songs_temp.songid) ) unicode(songs_temp.songid))
for row in aa: for row in aa:
a = row['authorid'] a = row['authorid']
authors_temp = self.session.query(TAuthor).get(a) authors_temp = self.session.query(TAuthor).get(a)
bb = self.session.execute( bb = self.session.execute(
u'select * from authors where display_name = \"%s\"' % \ u'select * from authors where display_name = \"%s\"' % \
unicode(authors_temp.authorname) ).fetchone() unicode(authors_temp.authorname)).fetchone()
if bb is None: if bb is None:
author = Author() author = Author()
author.display_name = authors_temp.authorname author.display_name = authors_temp.authorname

View File

@ -28,8 +28,8 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus from openlp.core.lib import Plugin, build_icon, PluginStatus
from openlp.plugins.alerts.lib import AlertsManager, DBManager from openlp.plugins.alerts.lib import AlertsManager, AlertsTab, DBManager
from openlp.plugins.alerts.forms import AlertsTab, AlertForm from openlp.plugins.alerts.forms import AlertForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -41,7 +41,7 @@ class alertsPlugin(Plugin):
self.weight = -3 self.weight = -3
self.icon = build_icon(u':/media/media_image.png') self.icon = build_icon(u':/media/media_image.png')
self.alertsmanager = AlertsManager(self) self.alertsmanager = AlertsManager(self)
self.manager = DBManager(self.config) self.manager = DBManager()
self.alertForm = AlertForm(self.manager, self) self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active self.status = PluginStatus.Active
@ -83,7 +83,9 @@ class alertsPlugin(Plugin):
def togglealertsState(self): def togglealertsState(self):
self.alertsActive = not self.alertsActive 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): def onAlertsTrigger(self):
self.alertForm.loadList() self.alertForm.loadList()

View File

@ -23,5 +23,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from alertstab import AlertsTab
from alertform import AlertForm from alertform import AlertForm

View File

@ -26,62 +26,120 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class Ui_AlertDialog(object): class Ui_AlertDialog(object):
def setupUi(self, AlertForm): def setupUi(self, AlertDialog):
AlertForm.setObjectName(u'AlertDialog') AlertDialog.setObjectName(u'AlertDialog')
AlertForm.resize(430, 320) AlertDialog.resize(567, 440)
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/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)
AlertForm.setWindowIcon(icon) AlertDialog.setWindowIcon(icon)
self.AlertFormLayout = QtGui.QVBoxLayout(AlertForm) self.AlertFormLayout = QtGui.QVBoxLayout(AlertDialog)
self.AlertFormLayout.setSpacing(8) self.AlertFormLayout.setSpacing(8)
self.AlertFormLayout.setMargin(8) self.AlertFormLayout.setMargin(8)
self.AlertFormLayout.setObjectName(u'AlertFormLayout') self.AlertFormLayout.setObjectName(u'AlertFormLayout')
self.AlertEntryWidget = QtGui.QWidget(AlertForm) self.AlertTextLayout = QtGui.QFormLayout()
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) self.AlertTextLayout.setContentsMargins(0, 0, -1, -1)
sizePolicy.setHorizontalStretch(0) self.AlertTextLayout.setSpacing(8)
sizePolicy.setVerticalStretch(0) self.AlertTextLayout.setObjectName(u'AlertTextLayout')
sizePolicy.setHeightForWidth(self.AlertEntryWidget.sizePolicy().hasHeightForWidth()) self.AlertEntryLabel = QtGui.QLabel(AlertDialog)
self.AlertEntryWidget.setSizePolicy(sizePolicy)
self.AlertEntryWidget.setObjectName(u'AlertEntryWidget')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.AlertEntryWidget)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.AlertEntryLabel = QtGui.QLabel(self.AlertEntryWidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.AlertEntryLabel.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.AlertEntryLabel.sizePolicy().hasHeightForWidth())
self.AlertEntryLabel.setSizePolicy(sizePolicy) self.AlertEntryLabel.setSizePolicy(sizePolicy)
self.AlertEntryLabel.setObjectName(u'AlertEntryLabel') self.AlertEntryLabel.setObjectName(u'AlertEntryLabel')
self.verticalLayout.addWidget(self.AlertEntryLabel) self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.AlertEntryLabel)
self.AlertEntryEditItem = QtGui.QLineEdit(self.AlertEntryWidget) self.AlertParameter = QtGui.QLabel(AlertDialog)
self.AlertEntryEditItem.setObjectName(u'AlertEntryEditItem') self.AlertParameter.setObjectName(u'AlertParameter')
self.verticalLayout.addWidget(self.AlertEntryEditItem) self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.AlertParameter)
self.AlertListWidget = QtGui.QListWidget(self.AlertEntryWidget) self.ParameterEdit = QtGui.QLineEdit(AlertDialog)
self.ParameterEdit.setObjectName(u'ParameterEdit')
self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.ParameterEdit)
self.AlertTextEdit = QtGui.QLineEdit(AlertDialog)
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(u'ManagementLayout')
self.AlertListWidget = QtGui.QListWidget(AlertDialog)
self.AlertListWidget.setAlternatingRowColors(True) self.AlertListWidget.setAlternatingRowColors(True)
self.AlertListWidget.setObjectName(u'AlertListWidget') self.AlertListWidget.setObjectName(u'AlertListWidget')
self.verticalLayout.addWidget(self.AlertListWidget) self.ManagementLayout.addWidget(self.AlertListWidget)
self.verticalLayout_2.addLayout(self.verticalLayout) self.ManageButtonLayout = QtGui.QVBoxLayout()
self.horizontalLayout = QtGui.QHBoxLayout() self.ManageButtonLayout.setSpacing(8)
self.horizontalLayout.setObjectName(u'horizontalLayout') self.ManageButtonLayout.setObjectName(u'ManageButtonLayout')
spacerItem = QtGui.QSpacerItem(181, 38, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.NewButton = QtGui.QPushButton(AlertDialog)
self.horizontalLayout.addItem(spacerItem) icon1 = QtGui.QIcon()
self.DisplayButton = QtGui.QPushButton(self.AlertEntryWidget) icon1.addPixmap(QtGui.QPixmap(u':/general/general_new.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.NewButton.setIcon(icon1)
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(u':/general/general_save.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.SaveButton.setIcon(icon2)
self.SaveButton.setObjectName(u'SaveButton')
self.ManageButtonLayout.addWidget(self.SaveButton)
self.DeleteButton = QtGui.QPushButton(AlertDialog)
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)
self.ManagementLayout.addLayout(self.ManageButtonLayout)
self.AlertFormLayout.addLayout(self.ManagementLayout)
self.AlertButtonLayout = QtGui.QHBoxLayout()
self.AlertButtonLayout.setSpacing(8)
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)
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.DisplayButton.setObjectName(u'DisplayButton')
self.horizontalLayout.addWidget(self.DisplayButton) self.AlertButtonLayout.addWidget(self.DisplayButton)
self.CancelButton = QtGui.QPushButton(self.AlertEntryWidget) self.DisplayCloseButton = QtGui.QPushButton(AlertDialog)
self.CancelButton.setObjectName(u'CancelButton') self.DisplayCloseButton.setIcon(icon4)
self.horizontalLayout.addWidget(self.CancelButton) self.DisplayCloseButton.setObjectName(u'DisplayCloseButton')
self.verticalLayout_2.addLayout(self.horizontalLayout) self.AlertButtonLayout.addWidget(self.DisplayCloseButton)
self.AlertFormLayout.addWidget(self.AlertEntryWidget) self.CloseButton = QtGui.QPushButton(AlertDialog)
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(AlertForm) self.retranslateUi(AlertDialog)
QtCore.QObject.connect(self.CancelButton, QtCore.SIGNAL(u'clicked()'), self.close) QtCore.QObject.connect(self.CloseButton, QtCore.SIGNAL(u'clicked()'), AlertDialog.close)
QtCore.QMetaObject.connectSlotsByName(AlertForm) 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.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(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'))
def retranslateUi(self, AlertForm):
AlertForm.setWindowTitle(self.trUtf8('Alert Message'))
self.AlertEntryLabel.setText(self.trUtf8('Alert Text:'))
self.DisplayButton.setText(self.trUtf8('Display'))
self.CancelButton.setText(self.trUtf8('Cancel'))

View File

@ -39,15 +39,27 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
""" """
self.manager = manager self.manager = manager
self.parent = parent self.parent = parent
self.history_required = True self.item_id = None
QtGui.QDialog.__init__(self, None) QtGui.QDialog.__init__(self, None)
self.setupUi(self) self.setupUi(self)
QtCore.QObject.connect(self.DisplayButton, QtCore.QObject.connect(self.DisplayButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onDisplayClicked) self.onDisplayClicked)
QtCore.QObject.connect(self.AlertEntryEditItem, QtCore.QObject.connect(self.DisplayCloseButton,
QtCore.SIGNAL(u'clicked()'),
self.onDisplayCloseClicked)
QtCore.QObject.connect(self.AlertTextEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'), QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onTextChanged) self.onTextChanged)
QtCore.QObject.connect(self.NewButton,
QtCore.SIGNAL(u'clicked()'),
self.onNewClick)
QtCore.QObject.connect(self.DeleteButton,
QtCore.SIGNAL(u'clicked()'),
self.onDeleteClick)
QtCore.QObject.connect(self.SaveButton,
QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.AlertListWidget, QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onDoubleClick) self.onDoubleClick)
@ -60,20 +72,57 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
alerts = self.manager.get_all_alerts() alerts = self.manager.get_all_alerts()
for alert in alerts: for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.AlertListWidget.addItem(item_name) self.AlertListWidget.addItem(item_name)
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
def onDisplayClicked(self): def onDisplayClicked(self):
self.triggerAlert(unicode(self.AlertEntryEditItem.text())) if self.triggerAlert(unicode(self.AlertTextEdit.text())):
if self.parent.alertsTab.save_history and self.history_required: self.loadList()
def onDisplayCloseClicked(self):
if self.triggerAlert(unicode(self.AlertTextEdit.text())):
self.close()
def onDeleteClick(self):
item = self.AlertListWidget.currentItem()
if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id)
row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'')
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
def onNewClick(self):
if len(self.AlertTextEdit.text()) == 0:
QtGui.QMessageBox.information(self,
self.trUtf8('Item selected to Add'),
self.trUtf8('Missing data'))
else:
alert = AlertItem() alert = AlertItem()
alert.text = unicode(self.AlertEntryEditItem.text()) alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert) self.manager.save_alert(alert)
self.history_required = False self.AlertTextEdit.setText(u'')
self.loadList() self.loadList()
def onSaveClick(self):
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): def onTextChanged(self):
#Data has changed by editing it so potential storage #Data has changed by editing it so potential storage required
self.history_required = True self.SaveButton.setEnabled(True)
def onDoubleClick(self): def onDoubleClick(self):
""" """
@ -83,7 +132,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
for item in items: for item in items:
bitem = self.AlertListWidget.item(item.row()) bitem = self.AlertListWidget.item(item.row())
self.triggerAlert(bitem.text()) 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): def onSingleClick(self):
""" """
@ -93,8 +145,14 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
items = self.AlertListWidget.selectedIndexes() items = self.AlertListWidget.selectedIndexes()
for item in items: for item in items:
bitem = self.AlertListWidget.item(item.row()) bitem = self.AlertListWidget.item(item.row())
self.AlertEntryEditItem.setText(bitem.text()) self.AlertTextEdit.setText(bitem.text())
self.history_required = False self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(True)
def triggerAlert(self, text): def triggerAlert(self, text):
self.parent.alertsmanager.displayAlert(text) if text:
text = text.replace(u'<>', unicode(self.ParameterEdit.text()))
self.parent.alertsmanager.displayAlert(text)
return True
return False

View File

@ -24,4 +24,5 @@
############################################################################### ###############################################################################
from alertsmanager import AlertsManager from alertsmanager import AlertsManager
from alertstab import AlertsTab
from manager import DBManager from manager import DBManager

View File

@ -44,13 +44,11 @@ class AlertsManager(QtCore.QObject):
self.timer_id = 0 self.timer_id = 0
self.alertList = [] self.alertList = []
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.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'config_updated'), self.screenChanged)
def screenChanged(self): def screenChanged(self):
log.debug(u'screen changed') log.debug(u'screen changed')
@ -65,9 +63,22 @@ class AlertsManager(QtCore.QObject):
if self.alertTab.location == 0: if self.alertTab.location == 0:
self.alertScreenPosition = 0 self.alertScreenPosition = 0
else: else:
self.alertScreenPosition = self.screen[u'size'].height() - self.alertHeight self.alertScreenPosition = self.screen[u'size'].height() \
self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition - self.alertHeight
self.parent.maindisplay.setAlertSize(self.alertScreenPosition, self.alertHeight) self.alertHeight = self.screen[u'size'].height() \
- self.alertScreenPosition
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''): def displayAlert(self, text=u''):
""" """
@ -79,12 +90,12 @@ class AlertsManager(QtCore.QObject):
log.debug(u'display alert called %s' % text) log.debug(u'display alert called %s' % text)
if not self.screen: if not self.screen:
self.screenChanged() self.screenChanged()
self.parent.maindisplay.parent.StatusBar.showMessage(u'')
self.alertList.append(text) self.alertList.append(text)
if self.timer_id != 0: if self.timer_id != 0:
self.parent.maindisplay.parent.StatusBar.showMessage(\ Receiver.send_message(u'maindisplay_status_text',
self.trUtf8(u'Alert message created and delayed')) self.trUtf8(u'Alert message created and delayed'))
return return
Receiver.send_message(u'maindisplay_status_text', u'')
self.generateAlert() self.generateAlert()
def generateAlert(self): def generateAlert(self):
@ -116,6 +127,7 @@ class AlertsManager(QtCore.QObject):
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event): def timerEvent(self, event):
log.debug(u'timer event')
if event.timerId() == self.timer_id: if event.timerId() == self.timer_id:
self.parent.maindisplay.addAlertImage(None, True) self.parent.maindisplay.addAlertImage(None, True)
self.killTimer(self.timer_id) self.killTimer(self.timer_id)

View File

@ -25,18 +25,16 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool from openlp.core.lib import SettingsTab
from openlp.plugins.alerts.lib.models import AlertItem
class AlertsTab(SettingsTab): class AlertsTab(SettingsTab):
""" """
AlertsTab is the alerts settings tab in the settings dialog. AlertsTab is the alerts settings tab in the settings dialog.
""" """
def __init__(self, parent, section=None): def __init__(self, parent):
self.parent = parent self.parent = parent
self.manager = parent.manager self.manager = parent.manager
self.alertsmanager = parent.alertsmanager SettingsTab.__init__(self, parent.name)
SettingsTab.__init__(self, parent.name, section)
def setupUi(self): def setupUi(self):
self.setObjectName(u'AlertsTab') self.setObjectName(u'AlertsTab')
@ -136,22 +134,6 @@ class AlertsTab(SettingsTab):
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.LocationLayout.addItem(self.LocationSpacer) self.LocationLayout.addItem(self.LocationSpacer)
self.FontLayout.addWidget(self.LocationWidget) 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.SlideLeftLayout.addWidget(self.FontGroupBox)
self.SlideLeftSpacer = QtGui.QSpacerItem(20, 94, self.SlideLeftSpacer = QtGui.QSpacerItem(20, 94,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
@ -188,48 +170,8 @@ class AlertsTab(SettingsTab):
self.SlideRightSpacer = QtGui.QSpacerItem(20, 40, self.SlideRightSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.SlideRightLayout.addItem(self.SlideRightSpacer) self.SlideRightLayout.addItem(self.SlideRightSpacer)
self.layoutWidget = QtGui.QWidget(self)
self.layoutWidget.setGeometry(QtCore.QRect(20, 10, 361, 251))
self.layoutWidget.setObjectName(u'layoutWidget')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
self.AlertLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.AlertLineEdit.setObjectName(u'AlertLineEdit')
self.horizontalLayout_2.addWidget(self.AlertLineEdit)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.AlertListWidget = QtGui.QListWidget(self.layoutWidget)
self.AlertListWidget.setAlternatingRowColors(True)
self.AlertListWidget.setObjectName(u'AlertListWidget')
self.horizontalLayout.addWidget(self.AlertListWidget)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.SaveButton = QtGui.QPushButton(self.layoutWidget)
self.SaveButton.setObjectName(u'SaveButton')
self.verticalLayout.addWidget(self.SaveButton)
self.ClearButton = QtGui.QPushButton(self.layoutWidget)
self.ClearButton.setObjectName(u'ClearButton')
self.verticalLayout.addWidget(self.ClearButton)
self.AddButton = QtGui.QPushButton(self.layoutWidget)
self.AddButton.setObjectName(u'AddButton')
self.verticalLayout.addWidget(self.AddButton)
self.EditButton = QtGui.QPushButton(self.layoutWidget)
self.EditButton.setObjectName(u'EditButton')
self.verticalLayout.addWidget(self.EditButton)
self.DeleteButton = QtGui.QPushButton(self.layoutWidget)
self.DeleteButton.setObjectName(u'DeleteButton')
self.verticalLayout.addWidget(self.DeleteButton)
self.horizontalLayout.addLayout(self.verticalLayout)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.SlideRightLayout.addWidget(self.layoutWidget)
self.AlertsLayout.addWidget(self.AlertRightColumn) self.AlertsLayout.addWidget(self.AlertRightColumn)
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.HistoryCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onHistoryCheckBoxChanged)
QtCore.QObject.connect(self.BackgroundColorButton, QtCore.QObject.connect(self.BackgroundColorButton,
QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked) QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
QtCore.QObject.connect(self.FontColorButton, QtCore.QObject.connect(self.FontColorButton,
@ -242,27 +184,6 @@ class AlertsTab(SettingsTab):
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
QtCore.QObject.connect(self.FontSizeSpinBox, QtCore.QObject.connect(self.FontSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
QtCore.QObject.connect(self.DeleteButton,
QtCore.SIGNAL(u'clicked()'),
self.onDeleteClick)
QtCore.QObject.connect(self.ClearButton,
QtCore.SIGNAL(u'clicked()'),
self.onClearClick)
QtCore.QObject.connect(self.EditButton,
QtCore.SIGNAL(u'clicked()'),
self.onEditClick)
QtCore.QObject.connect(self.AddButton,
QtCore.SIGNAL(u'clicked()'),
self.onAddClick)
QtCore.QObject.connect(self.SaveButton,
QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onItemSelected)
QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'),
self.onItemSelected)
def retranslateUi(self): def retranslateUi(self):
self.FontGroupBox.setTitle(self.trUtf8('Font')) self.FontGroupBox.setTitle(self.trUtf8('Font'))
@ -274,16 +195,10 @@ class AlertsTab(SettingsTab):
self.TimeoutLabel.setText(self.trUtf8('Alert timeout:')) self.TimeoutLabel.setText(self.trUtf8('Alert timeout:'))
self.TimeoutSpinBox.setSuffix(self.trUtf8('s')) self.TimeoutSpinBox.setSuffix(self.trUtf8('s'))
self.LocationLabel.setText(self.trUtf8('Location:')) self.LocationLabel.setText(self.trUtf8('Location:'))
self.HistoryLabel.setText(self.trUtf8('Keep History:'))
self.PreviewGroupBox.setTitle(self.trUtf8('Preview')) self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))
self.FontPreview.setText(self.trUtf8('openlp.org')) self.FontPreview.setText(self.trUtf8('openlp.org'))
self.LocationComboBox.setItemText(0, self.trUtf8('Top')) self.LocationComboBox.setItemText(0, self.trUtf8('Top'))
self.LocationComboBox.setItemText(1, self.trUtf8('Bottom')) self.LocationComboBox.setItemText(1, self.trUtf8('Bottom'))
self.SaveButton.setText(self.trUtf8('Save'))
self.ClearButton.setText(self.trUtf8('Clear'))
self.AddButton.setText(self.trUtf8('Add'))
self.EditButton.setText(self.trUtf8('Edit'))
self.DeleteButton.setText(self.trUtf8('Delete'))
def onBackgroundColorButtonClicked(self): def onBackgroundColorButtonClicked(self):
self.bg_color = QtGui.QColorDialog.getColor( self.bg_color = QtGui.QColorDialog.getColor(
@ -298,12 +213,6 @@ class AlertsTab(SettingsTab):
def onLocationComboBoxClicked(self, location): def onLocationComboBoxClicked(self, location):
self.location = 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): def onFontColorButtonClicked(self):
self.font_color = QtGui.QColorDialog.getColor( self.font_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.font_color), self).name() QtGui.QColor(self.font_color), self).name()
@ -319,17 +228,20 @@ class AlertsTab(SettingsTab):
self.updateDisplay() self.updateDisplay()
def load(self): def load(self):
self.timeout = int(self.config.get_config(u'timeout', 5)) settings = QtCore.QSettings()
self.font_color = unicode( settings.beginGroup(self.settingsSection)
self.config.get_config(u'font color', u'#ffffff')) self.timeout = settings.value(u'timeout', QtCore.QVariant(5)).toInt()[0]
self.font_size = int(self.config.get_config(u'font size', 40)) self.font_color = unicode(settings.value(
self.bg_color = unicode( u'font color', QtCore.QVariant(u'#ffffff')).toString())
self.config.get_config(u'background color', u'#660000')) self.font_size = settings.value(
self.font_face = unicode( u'font size', QtCore.QVariant(40)).toInt()[0]
self.config.get_config(u'font face', QtGui.QFont().family())) self.bg_color = unicode(settings.value(
self.location = int(self.config.get_config(u'location', 0)) u'background color', QtCore.QVariant(u'#660000')).toString())
self.save_history = str_to_bool( self.font_face = unicode(settings.value(
self.config.get_config(u'save history', u'False')) 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.FontSizeSpinBox.setValue(self.font_size)
self.TimeoutSpinBox.setValue(self.timeout) self.TimeoutSpinBox.setValue(self.timeout)
self.FontColorButton.setStyleSheet( self.FontColorButton.setStyleSheet(
@ -337,91 +249,27 @@ class AlertsTab(SettingsTab):
self.BackgroundColorButton.setStyleSheet( self.BackgroundColorButton.setStyleSheet(
u'background-color: %s' % self.bg_color) u'background-color: %s' % self.bg_color)
self.LocationComboBox.setCurrentIndex(self.location) self.LocationComboBox.setCurrentIndex(self.location)
self.HistoryCheckBox.setChecked(self.save_history)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(self.font_face) font.setFamily(self.font_face)
self.FontComboBox.setCurrentFont(font) self.FontComboBox.setCurrentFont(font)
self.updateDisplay() self.updateDisplay()
self.loadList()
def loadList(self):
self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts()
for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.AlertListWidget.addItem(item_name)
self.AddButton.setEnabled(True)
self.ClearButton.setEnabled(False)
self.SaveButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
def onItemSelected(self): def onItemSelected(self):
self.EditButton.setEnabled(True) self.EditButton.setEnabled(True)
self.DeleteButton.setEnabled(True) self.DeleteButton.setEnabled(True)
def onDeleteClick(self):
item = self.AlertListWidget.currentItem()
if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id)
row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row)
self.AddButton.setEnabled(True)
self.SaveButton.setEnabled(False)
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.AlertLineEdit.setText(unicode(item.text()))
self.AddButton.setEnabled(True)
self.ClearButton.setEnabled(True)
self.SaveButton.setEnabled(True)
self.DeleteButton.setEnabled(True)
self.EditButton.setEnabled(False)
def onClearClick(self):
self.AlertLineEdit.setText(u'')
self.AddButton.setEnabled(False)
self.ClearButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
def onAddClick(self):
if len(self.AlertLineEdit.text()) == 0:
QtGui.QMessageBox.information(self,
self.trUtf8('Item selected to Add'),
self.trUtf8('Missing data'))
else:
alert = AlertItem()
alert.text = unicode(self.AlertLineEdit.text())
self.manager.save_alert(alert)
self.onClearClick()
self.loadList()
def onSaveClick(self):
alert = self.manager.get_alert(self.item_id)
alert.text = unicode(self.AlertLineEdit.text())
self.manager.save_alert(alert)
self.onClearClick()
self.loadList()
def save(self): def save(self):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
self.font_face = self.FontComboBox.currentFont().family() self.font_face = self.FontComboBox.currentFont().family()
self.config.set_config(u'background color', unicode(self.bg_color)) settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
self.config.set_config(u'font color', unicode(self.font_color)) settings.setValue(u'font color', QtCore.QVariant(self.font_color))
self.config.set_config(u'font size', unicode(self.font_size)) settings.setValue(u'font size', QtCore.QVariant(self.font_size))
self.config.set_config(u'font face', unicode(self.font_face)) settings.setValue(u'font face', QtCore.QVariant(self.font_face))
self.config.set_config(u'timeout', unicode(self.timeout)) settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
self.config.set_config(u'location', settings.setValue(u'location',
unicode(self.LocationComboBox.currentIndex())) QtCore.QVariant(self.LocationComboBox.currentIndex()))
self.config.set_config(u'save history', unicode(self.save_history)) settings.endGroup()
def updateDisplay(self): def updateDisplay(self):
font = QtGui.QFont() font = QtGui.QFont()

View File

@ -25,6 +25,9 @@
import logging import logging
from PyQt4 import QtCore
from openlp.core.utils import AppLocation
from openlp.plugins.alerts.lib.models import init_models, metadata, AlertItem from openlp.plugins.alerts.lib.models import init_models, metadata, AlertItem
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -36,27 +39,29 @@ class DBManager():
""" """
log.info(u'Alerts DB loaded') 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 Creates the connection to the database, and creates the tables if they
don't exist. don't exist.
""" """
self.config = config
log.debug(u'Alerts Initialising') log.debug(u'Alerts Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'alerts')
self.db_url = u'' 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': if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/alerts.sqlite' % \ self.db_url = u'sqlite:///%s/alerts.sqlite' % \
self.config.get_data_path() AppLocation.get_section_data_path(u'alerts')
else: else:
self.db_url = u'%s://%s:%s@%s/%s' % \ self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
(db_type, self.config.get_config(u'db username'), unicode(settings.value(u'db username').toString()),
self.config.get_config(u'db password'), unicode(settings.value(u'db password').toString()),
self.config.get_config(u'db hostname'), unicode(settings.value(u'db hostname').toString()),
self.config.get_config(u'db database')) unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_models(self.db_url) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)
log.debug(u'Alerts Initialised') log.debug(u'Alerts Initialised')
def get_all_alerts(self): def get_all_alerts(self):

View File

@ -46,7 +46,7 @@ class BiblePlugin(Plugin):
def initialise(self): def initialise(self):
log.info(u'bibles Initialising') log.info(u'bibles Initialising')
if self.manager is None: if self.manager is None:
self.manager = BibleManager(self, self.config) self.manager = BibleManager(self)
Plugin.initialise(self) Plugin.initialise(self)
self.insert_toolbox_item() self.insert_toolbox_item()
self.ImportBibleItem.setVisible(True) self.ImportBibleItem.setVisible(True)

View File

@ -31,7 +31,7 @@ import os.path
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from bibleimportwizard import Ui_BibleImportWizard 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.core.utils import AppLocation, variant_to_unicode
from openlp.plugins.bibles.lib.manager import BibleFormat from openlp.plugins.bibles.lib.manager import BibleFormat
@ -59,16 +59,13 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
""" """
log.info(u'BibleImportForm loaded') 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. Instantiate the wizard, and run any extra setup we need to.
``parent`` ``parent``
The QWidget-derived parent of the wizard. The QWidget-derived parent of the wizard.
``config``
The configuration object for storing and retrieving settings.
``manager`` ``manager``
The Bible manager. The Bible manager.
@ -81,7 +78,6 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.finishButton = self.button(QtGui.QWizard.FinishButton) self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton) self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.manager = manager self.manager = manager
self.config = config
self.bibleplugin = bibleplugin self.bibleplugin = bibleplugin
self.manager.set_process_dialog(self) self.manager.set_process_dialog(self)
self.web_bible_list = {} self.web_bible_list = {}
@ -240,7 +236,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
""" """
log.debug('Cancel button pressed!') log.debug('Cancel button pressed!')
if self.currentId() == 3: if self.currentId() == 3:
Receiver.send_message(u'openlpstopimport') Receiver.send_message(u'bibles_stop_import')
def onCurrentIdChanged(self, id): def onCurrentIdChanged(self, id):
if id == 3: if id == 3:
@ -277,6 +273,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
u'license_permission', self.PermissionEdit) u'license_permission', self.PermissionEdit)
def setDefaults(self): def setDefaults(self):
settings = QtCore.QSettings()
settings.beginGroup(self.bibleplugin.settingsSection)
self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'source_format', QtCore.QVariant(0))
self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'osis_location', QtCore.QVariant(''))
self.setField(u'csv_booksfile', 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_location', QtCore.QVariant(WebDownload.Crosswalk))
self.setField(u'web_biblename', QtCore.QVariant(self.BibleComboBox)) self.setField(u'web_biblename', QtCore.QVariant(self.BibleComboBox))
self.setField(u'proxy_server', 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', 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', 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_version', QtCore.QVariant(self.VersionNameEdit))
self.setField(u'license_copyright', QtCore.QVariant(self.CopyrightEdit)) 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) self.onLocationComboBoxChanged(WebDownload.Crosswalk)
settings.endGroup()
def loadWebBibles(self): def loadWebBibles(self):
""" """
@ -302,10 +302,10 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
#Load and store Crosswalk Bibles #Load and store Crosswalk Bibles
filepath = AppLocation.get_directory(AppLocation.PluginsDir) filepath = AppLocation.get_directory(AppLocation.PluginsDir)
filepath = os.path.join(filepath, u'bibles', u'resources') filepath = os.path.join(filepath, u'bibles', u'resources')
fbibles = None
try: try:
self.web_bible_list[WebDownload.Crosswalk] = {} 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)) dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0) books_file.seek(0)
books_reader = csv.reader(books_file, dialect) books_reader = csv.reader(books_file, dialect)
@ -345,16 +345,17 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
def getFileName(self, title, editbox): def getFileName(self, title, editbox):
filename = QtGui.QFileDialog.getOpenFileName(self, title, filename = QtGui.QFileDialog.getOpenFileName(self, title,
self.config.get_last_dir(1)) SettingsManager.get_last_dir(self.bibleplugin.settingsSection, 1))
if filename: if filename:
editbox.setText(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): def incrementProgressBar(self, status_text):
log.debug(u'IncrementBar %s', status_text) log.debug(u'IncrementBar %s', status_text)
self.ImportProgressLabel.setText(status_text) self.ImportProgressLabel.setText(status_text)
self.ImportProgressBar.setValue(self.ImportProgressBar.value() + 1) self.ImportProgressBar.setValue(self.ImportProgressBar.value() + 1)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
def preImport(self): def preImport(self):
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
@ -362,13 +363,14 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setMaximum(1188)
self.ImportProgressBar.setValue(0) self.ImportProgressBar.setValue(0)
self.ImportProgressLabel.setText(self.trUtf8('Starting import...')) self.ImportProgressLabel.setText(self.trUtf8('Starting import...'))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performImport(self):
bible_type = self.field(u'source_format').toInt()[0] bible_type = self.field(u'source_format').toInt()[0]
license_version = variant_to_unicode(self.field(u'license_version')) license_version = variant_to_unicode(self.field(u'license_version'))
license_copyright = variant_to_unicode(self.field(u'license_copyright')) 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 importer = None
if bible_type == BibleFormat.OSIS: if bible_type == BibleFormat.OSIS:
# Import an OSIS bible # Import an OSIS bible
@ -424,4 +426,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum()) self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
self.finishButton.setVisible(True) self.finishButton.setVisible(True)
self.cancelButton.setVisible(False) self.cancelButton.setVisible(False)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')

View File

@ -27,7 +27,7 @@ import logging
from PyQt4 import QtCore, QtGui 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__) log = logging.getLogger(__name__)
@ -37,11 +37,11 @@ class BiblesTab(SettingsTab):
""" """
log.info(u'Bible Tab loaded') log.info(u'Bible Tab loaded')
def __init__(self, title, section=None): def __init__(self, title):
self.paragraph_style = True self.paragraph_style = True
self.show_new_chapters = False self.show_new_chapters = False
self.display_style = 0 self.display_style = 0
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'BiblesTab') self.setObjectName(u'BiblesTab')
@ -146,11 +146,12 @@ class BiblesTab(SettingsTab):
self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleDualCheckBox) self.onBibleDualCheckBox)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self): def retranslateUi(self):
self.VerseDisplayGroupBox.setTitle(self.trUtf8('Verse Display')) 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.LayoutStyleLabel.setText(self.trUtf8('Layout Style:'))
self.DisplayStyleLabel.setText(self.trUtf8('Display Style:')) self.DisplayStyleLabel.setText(self.trUtf8('Display Style:'))
self.BibleThemeLabel.setText(self.trUtf8('Bible Theme:')) self.BibleThemeLabel.setText(self.trUtf8('Bible Theme:'))
@ -161,8 +162,8 @@ class BiblesTab(SettingsTab):
self.DisplayStyleComboBox.setItemText(1, self.trUtf8('( and )')) self.DisplayStyleComboBox.setItemText(1, self.trUtf8('( and )'))
self.DisplayStyleComboBox.setItemText(2, self.trUtf8('{ and }')) self.DisplayStyleComboBox.setItemText(2, self.trUtf8('{ and }'))
self.DisplayStyleComboBox.setItemText(3, self.trUtf8('[ and ]')) self.DisplayStyleComboBox.setItemText(3, self.trUtf8('[ and ]'))
self.ChangeNoteLabel.setText( self.ChangeNoteLabel.setText(self.trUtf8(
self.trUtf8('Note:\nChanges don\'t affect verses already in the service')) 'Note:\nChanges don\'t affect verses already in the service'))
self.BibleDualCheckBox.setText(self.trUtf8('Display Dual Bible Verses')) self.BibleDualCheckBox.setText(self.trUtf8('Display Dual Bible Verses'))
def onBibleThemeComboBoxChanged(self): def onBibleThemeComboBoxChanged(self):
@ -187,29 +188,36 @@ class BiblesTab(SettingsTab):
self.duel_bibles = True self.duel_bibles = True
def load(self): def load(self):
self.show_new_chapters = str_to_bool( settings = QtCore.QSettings()
self.config.get_config(u'display new chapter', u'False')) settings.beginGroup(self.settingsSection)
self.display_style = int( self.show_new_chapters = settings.value(
self.config.get_config(u'display brackets', u'0')) u'display new chapter', QtCore.QVariant(False)).toBool()
self.layout_style = int( self.display_style = settings.value(
self.config.get_config(u'verse layout style', u'0')) u'display brackets', QtCore.QVariant(0)).toInt()[0]
self.bible_theme = self.config.get_config(u'bible theme', u'0') self.layout_style = settings.value(
self.duel_bibles = str_to_bool( u'verse layout style', QtCore.QVariant(0)).toInt()[0]
self.config.get_config(u'dual bibles', u'True')) 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.NewChaptersCheckBox.setChecked(self.show_new_chapters)
self.DisplayStyleComboBox.setCurrentIndex(self.display_style) self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
self.LayoutStyleComboBox.setCurrentIndex(self.layout_style) self.LayoutStyleComboBox.setCurrentIndex(self.layout_style)
self.BibleDualCheckBox.setChecked(self.duel_bibles) self.BibleDualCheckBox.setChecked(self.duel_bibles)
settings.endGroup()
def save(self): def save(self):
self.config.set_config( settings = QtCore.QSettings()
u'display new chapter', unicode(self.show_new_chapters)) settings.beginGroup(self.settingsSection)
self.config.set_config( settings.setValue(u'display new chapter',
u'display brackets', unicode(self.display_style)) QtCore.QVariant(self.show_new_chapters))
self.config.set_config( settings.setValue(u'display brackets',
u'verse layout style', unicode(self.layout_style)) QtCore.QVariant(self.display_style))
self.config.set_config(u'dual bibles', unicode(self.duel_bibles)) settings.setValue(u'verse layout style',
self.config.set_config(u'bible theme', unicode(self.bible_theme)) 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): def updateThemeList(self, theme_list):
""" """

View File

@ -52,7 +52,7 @@ class CSVBible(BibleDB):
raise KeyError(u'You have to supply a file to import verses from.') raise KeyError(u'You have to supply a file to import verses from.')
self.versesfile = kwargs[u'versesfile'] self.versesfile = kwargs[u'versesfile']
QtCore.QObject.connect(Receiver.get_receiver(), 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): def stop_import(self):
""" """
@ -77,7 +77,7 @@ class CSVBible(BibleDB):
details = chardet.detect(line[1]) details = chardet.detect(line[1])
self.create_book(unicode(line[1], details['encoding']), self.create_book(unicode(line[1], details['encoding']),
line[2], int(line[0])) line[2], int(line[0]))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
except: except:
log.exception(u'Loading books from file failed') log.exception(u'Loading books from file failed')
success = False success = False
@ -105,7 +105,7 @@ class CSVBible(BibleDB):
self.commit() self.commit()
self.create_verse(book.id, line[1], line[2], self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding'])) unicode(line[3], details['encoding']))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.commit()
except: except:
log.exception(u'Loading verses from file failed') log.exception(u'Loading verses from file failed')
@ -118,4 +118,3 @@ class CSVBible(BibleDB):
return False return False
else: else:
return success return success

View File

@ -56,20 +56,14 @@ class BibleDB(QtCore.QObject):
``name`` ``name``
The name of the database. This is also used as the file name for The name of the database. This is also used as the file name for
SQLite databases. SQLite databases.
``config``
The configuration object, passed in from the plugin.
""" """
log.info(u'BibleDB loaded') log.info(u'BibleDB loaded')
QtCore.QObject.__init__(self) QtCore.QObject.__init__(self)
if u'path' not in kwargs: if u'path' not in kwargs:
raise KeyError(u'Missing keyword argument "path".') 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: if u'name' not in kwargs and u'file' not in kwargs:
raise KeyError(u'Missing keyword argument "name" or "file".') raise KeyError(u'Missing keyword argument "name" or "file".')
self.stop_import_flag = False self.stop_import_flag = False
self.config = kwargs[u'config']
if u'name' in kwargs: if u'name' in kwargs:
self.name = kwargs[u'name'] self.name = kwargs[u'name']
if not isinstance(self.name, unicode): if not isinstance(self.name, unicode):
@ -79,16 +73,20 @@ class BibleDB(QtCore.QObject):
self.file = kwargs[u'file'] self.file = kwargs[u'file']
self.db_file = os.path.join(kwargs[u'path'], self.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) 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'' db_url = u''
if db_type == u'sqlite': if db_type == u'sqlite':
db_url = u'sqlite:///' + self.db_file db_url = u'sqlite:///' + self.db_file
else: else:
db_url = u'%s://%s:%s@%s/%s' % \ db_url = u'%s://%s:%s@%s/%s' % (db_type,
(db_type, self.config.get_config(u'db username'), unicode(settings.value(u'db username').toString()),
self.config.get_config(u'db password'), unicode(settings.value(u'db password').toString()),
self.config.get_config(u'db hostname'), unicode(settings.value(u'db hostname').toString()),
self.config.get_config(u'db database')) unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.metadata, self.session = init_models(db_url) self.metadata, self.session = init_models(db_url)
self.metadata.create_all(checkfirst=True) self.metadata.create_all(checkfirst=True)
if u'file' in kwargs: if u'file' in kwargs:
@ -113,7 +111,7 @@ class BibleDB(QtCore.QObject):
``old_filename`` ``old_filename``
The "dirty" file name or version name. 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 = unicode(old_filename, u'utf-8')
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
return old_filename + u'.sqlite' return old_filename + u'.sqlite'

View File

@ -203,9 +203,9 @@ class BGExtract(BibleCommon):
# Let's get the page, and then open it in BeautifulSoup, so as to # Let's get the page, and then open it in BeautifulSoup, so as to
# attempt to make "easy" work of bad HTML. # attempt to make "easy" work of bad HTML.
page = urllib2.urlopen(urlstring) page = urllib2.urlopen(urlstring)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
soup = BeautifulSoup(page) 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') verses = soup.find(u'div', u'result-text-style-normal')
verse_number = 0 verse_number = 0
verse_list = {0: u''} verse_list = {0: u''}
@ -213,7 +213,7 @@ class BGExtract(BibleCommon):
# This is a PERFECT example of opening the Cthulu tag! # This is a PERFECT example of opening the Cthulu tag!
# O Bible Gateway, why doth ye such horrific HTML produce? # O Bible Gateway, why doth ye such horrific HTML produce?
for verse in verses: 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': if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes':
break break
if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum': 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 continue
if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents: if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents:
for item in 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'): if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'):
continue continue
if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum': 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 continue
if isinstance(item, Tag) and item.name == u'font': if isinstance(item, Tag) and item.name == u'font':
for subitem in item.contents: 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': if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum':
continue continue
if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents: if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents:
@ -294,37 +294,37 @@ class CWExtract(BibleCommon):
(version, urlbookname.lower(), chapter) (version, urlbookname.lower(), chapter)
log.debug(u'URL: %s', chapter_url) log.debug(u'URL: %s', chapter_url)
page = urllib2.urlopen(chapter_url) page = urllib2.urlopen(chapter_url)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if not page: if not page:
return None return None
soup = BeautifulSoup(page) soup = BeautifulSoup(page)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
htmlverses = soup.findAll(u'span', u'versetext') htmlverses = soup.findAll(u'span', u'versetext')
verses = {} verses = {}
reduce_spaces = re.compile(r'[ ]{2,}') reduce_spaces = re.compile(r'[ ]{2,}')
fix_punctuation = re.compile(r'[ ]+([.,;])') fix_punctuation = re.compile(r'[ ]+([.,;])')
for verse in htmlverses: for verse in htmlverses:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
versenumber = int(verse.contents[0].contents[0]) versenumber = int(verse.contents[0].contents[0])
versetext = u'' versetext = u''
for part in verse.contents: for part in verse.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(part, NavigableString): if isinstance(part, NavigableString):
versetext = versetext + part versetext = versetext + part
elif part and part.attrMap and \ elif part and part.attrMap and \
(part.attrMap[u'class'] == u'WordsOfChrist' or \ (part.attrMap[u'class'] == u'WordsOfChrist' or \
part.attrMap[u'class'] == u'strongs'): part.attrMap[u'class'] == u'strongs'):
for subpart in part.contents: for subpart in part.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(subpart, NavigableString): if isinstance(subpart, NavigableString):
versetext = versetext + subpart versetext = versetext + subpart
elif subpart and subpart.attrMap and \ elif subpart and subpart.attrMap and \
subpart.attrMap[u'class'] == u'strongs': subpart.attrMap[u'class'] == u'strongs':
for subsub in subpart.contents: for subsub in subpart.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(subsub, NavigableString): if isinstance(subsub, NavigableString):
versetext = versetext + subsub 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 # Fix up leading and trailing spaces, multiple spaces, and spaces
# between text and , and . # between text and , and .
versetext = versetext.strip(u'\n\r\t ') versetext = versetext.strip(u'\n\r\t ')
@ -415,14 +415,14 @@ class HTTPBible(BibleDB):
if not db_book: if not db_book:
book_details = self.lookup_book(book) book_details = self.lookup_book(book)
if not book_details: if not book_details:
Receiver.send_message(u'bible_nobook') Receiver.send_message(u'bibles_nobook')
return [] return []
db_book = self.create_book(book_details[u'name'], db_book = self.create_book(book_details[u'name'],
book_details[u'abbreviation'], book_details[u'testament_id']) book_details[u'abbreviation'], book_details[u'testament_id'])
book = db_book.name book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0: if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'bible_showprogress') Receiver.send_message(u'bibles_showprogress')
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(self.name, book, reference[1]) search_results = self.get_chapter(self.name, book, reference[1])
if search_results and search_results.has_verselist(): if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see ## 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 ## we get a correct book. For example it is possible
## to request ac and get Acts back. ## to request ac and get Acts back.
bookname = search_results.get_book() 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 # check to see if book/chapter exists
db_book = self.get_book(bookname) db_book = self.get_book(bookname)
self.create_chapter(db_book.id, search_results.get_chapter(), self.create_chapter(db_book.id, search_results.get_chapter(),
search_results.get_verselist()) search_results.get_verselist())
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
Receiver.send_message(u'bible_hideprogress') Receiver.send_message(u'bibles_hideprogress')
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
return BibleDB.get_verses(self, reference_list) return BibleDB.get_verses(self, reference_list)
def get_chapter(self, version, book, chapter): def get_chapter(self, version, book, chapter):
@ -496,4 +496,3 @@ class HTTPBible(BibleDB):
The hostname or IP address of the proxy server. The hostname or IP address of the proxy server.
""" """
self.proxy_server = server self.proxy_server = server

View File

@ -25,6 +25,11 @@
import logging import logging
from PyQt4 import QtCore
from openlp.core.lib import SettingsManager
from openlp.core.utils import AppLocation
from common import parse_reference from common import parse_reference
from opensong import OpenSongBible from opensong import OpenSongBible
from osis import OSISBible from osis import OSISBible
@ -94,25 +99,24 @@ class BibleManager(object):
""" """
log.info(u'Bible manager loaded') 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 Finds all the bibles defined for the system and creates an interface
object for each bible containing connection information. Throws object for each bible containing connection information. Throws
Exception if no Bibles are found. Exception if no Bibles are found.
Init confirms the bible exists and stores the database path. Init confirms the bible exists and stores the database path.
``config``
The plugin's configuration object.
""" """
log.debug(u'Bible Initialising') log.debug(u'Bible Initialising')
self.config = config
self.parent = parent self.parent = parent
self.settingsSection = u'bibles'
self.web = u'Web' self.web = u'Web'
self.db_cache = None self.db_cache = None
self.path = self.config.get_data_path() self.path = AppLocation.get_section_data_path(self.settingsSection)
self.proxy_name = self.config.get_config(u'proxy name') self.proxy_name = unicode(
self.suffix = u'sqlite' QtCore.QSettings().value(self.settingsSection + u'/proxy name',
QtCore.QVariant(u'')).toString())
self.suffix = u'.sqlite'
self.import_wizard = None self.import_wizard = None
self.reload_bibles() self.reload_bibles()
self.media = None self.media = None
@ -124,23 +128,23 @@ class BibleManager(object):
BibleDB class. BibleDB class.
""" """
log.debug(u'Reload bibles') 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) log.debug(u'Bible Files %s', files)
self.db_cache = {} self.db_cache = {}
for filename in files: for filename in files:
bible = BibleDB(self.parent, path=self.path, file=filename, bible = BibleDB(self.parent, path=self.path, file=filename)
config=self.config)
name = bible.get_name() name = bible.get_name()
log.debug(u'Bible Name: "%s"', name) log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible self.db_cache[name] = bible
# look to see if lazy load bible exists and get create getter. # look to see if lazy load bible exists and get create getter.
source = self.db_cache[name].get_meta(u'download source') source = self.db_cache[name].get_meta(u'download source')
if 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') meta_proxy = self.db_cache[name].get_meta(u'proxy url')
web_bible = HTTPBible(self.parent, path=self.path, web_bible = HTTPBible(self.parent, path=self.path,
file=filename, config=self.config, file=filename, download_source=source.value,
download_source=source.value, download_name=download_name) download_name=download_name)
if meta_proxy: if meta_proxy:
web_bible.set_proxy_server(meta_proxy.value) web_bible.set_proxy_server(meta_proxy.value)
self.db_cache[name] = web_bible self.db_cache[name] = web_bible
@ -167,7 +171,6 @@ class BibleManager(object):
""" """
class_ = BibleFormat.get_class(type) class_ = BibleFormat.get_class(type)
kwargs['path'] = self.path kwargs['path'] = self.path
kwargs['config'] = self.config
importer = class_(self.parent, **kwargs) importer = class_(self.parent, **kwargs)
name = importer.register(self.import_wizard) name = importer.register(self.import_wizard)
self.db_cache[name] = importer self.db_cache[name] = importer
@ -208,7 +211,8 @@ class BibleManager(object):
Returns all the number of verses for a given Returns all the number of verses for a given
book and chapterMaxBibleBookVerses 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) return self.db_cache[bible].get_verse_count(book, chapter)
def get_verses(self, bible, versetext): def get_verses(self, bible, versetext):
@ -260,4 +264,3 @@ class BibleManager(object):
if bible == name: if bible == name:
return True return True
return False return False

View File

@ -28,15 +28,15 @@ import time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, str_to_bool, \ from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
BaseListWithDnD, ItemCapabilities ItemCapabilities
from openlp.plugins.bibles.forms import ImportWizardForm from openlp.plugins.bibles.forms import ImportWizardForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class BibleListView(BaseListWithDnD): class BibleListView(BaseListWithDnD):
""" """
Drag and drop capable list for Bibles. Custom list view descendant, required for drag and drop.
""" """
def __init__(self, parent=None): def __init__(self, parent=None):
self.PluginName = u'Bibles' self.PluginName = u'Bibles'
@ -54,7 +54,6 @@ class BibleMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title): def __init__(self, parent, icon, title):
self.PluginNameShort = u'Bible' self.PluginNameShort = u'Bible'
self.ConfigSection = title
self.IconPath = u'songs/song' self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView self.ListViewWithDnD_class = BibleListView
self.lastReference = [] self.lastReference = []
@ -63,7 +62,7 @@ class BibleMediaItem(MediaManagerItem):
# place to store the search results # place to store the search results
self.search_results = {} self.search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(), 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): def _decodeQtObject(self, listobj, key):
obj = listobj[QtCore.QString(key)] obj = listobj[QtCore.QString(key)]
@ -257,11 +256,11 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(self.QuickSearchEdit, QtCore.QObject.connect(self.QuickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_nobook'), self.onNoBookFound) QtCore.SIGNAL(u'bibles_nobook'), self.onNoBookFound)
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
@ -276,8 +275,8 @@ class BibleMediaItem(MediaManagerItem):
self.SearchProgress.setObjectName(u'SearchProgress') self.SearchProgress.setObjectName(u'SearchProgress')
def configUpdated(self): def configUpdated(self):
if str_to_bool( if QtCore.QSettings().value(self.settingsSection + u'/dual bibles',
self.parent.config.get_config(u'dual bibles', u'False')): QtCore.QVariant(False)).toBool():
self.AdvancedSecondBibleLabel.setVisible(True) self.AdvancedSecondBibleLabel.setVisible(True)
self.AdvancedSecondBibleComboBox.setVisible(True) self.AdvancedSecondBibleComboBox.setVisible(True)
self.QuickSecondVersionLabel.setVisible(True) self.QuickSecondVersionLabel.setVisible(True)
@ -322,7 +321,7 @@ class BibleMediaItem(MediaManagerItem):
def setQuickMessage(self, text): def setQuickMessage(self, text):
self.QuickMessage.setText(text) self.QuickMessage.setText(text)
self.AdvancedMessage.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 #minor delay to get the events processed
time.sleep(0.1) time.sleep(0.1)
@ -353,7 +352,7 @@ class BibleMediaItem(MediaManagerItem):
def onSearchProgressShow(self): def onSearchProgressShow(self):
self.SearchProgress.setVisible(True) self.SearchProgress.setVisible(True)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
#self.SearchProgress.setMinimum(0) #self.SearchProgress.setMinimum(0)
#self.SearchProgress.setMaximum(2) #self.SearchProgress.setMaximum(2)
#self.SearchProgress.setValue(1) #self.SearchProgress.setValue(1)
@ -381,7 +380,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedBookComboBox.itemData(item).toInt()[0]) self.AdvancedBookComboBox.itemData(item).toInt()[0])
def onImportClick(self): def onImportClick(self):
self.bibleimportform = ImportWizardForm(self, self.parent.config, self.bibleimportform = ImportWizardForm(self,
self.parent.manager, self.parent) self.parent.manager, self.parent)
self.bibleimportform.exec_() self.bibleimportform.exec_()
self.reloadBibles() self.reloadBibles()
@ -450,6 +449,7 @@ class BibleMediaItem(MediaManagerItem):
bible_text = u'' bible_text = u''
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions)
#If we want to use a 2nd translation / version #If we want to use a 2nd translation / version
bible2 = u'' bible2 = u''
if self.SearchTabWidget.currentIndex() == 0: if self.SearchTabWidget.currentIndex() == 0:

View File

@ -49,7 +49,7 @@ class OpenSongBible(BibleDB):
raise KeyError(u'You have to supply a file name to import from.') raise KeyError(u'You have to supply a file name to import from.')
self.filename = kwargs['filename'] self.filename = kwargs['filename']
QtCore.QObject.connect(Receiver.get_receiver(), 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): def stop_import(self):
""" """
@ -92,7 +92,7 @@ class OpenSongBible(BibleDB):
int(verse.attrib[u'n']), int(verse.attrib[u'n']),
unicode(verse.text) unicode(verse.text)
) )
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar( self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\ QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\
db_book.name, chapter.attrib[u'n']))) db_book.name, chapter.attrib[u'n'])))

View File

@ -84,7 +84,7 @@ class OSISBible(BibleDB):
if fbibles: if fbibles:
fbibles.close() fbibles.close()
QtCore.QObject.connect(Receiver.get_receiver(), 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): def stop_import(self):
""" """
@ -98,7 +98,8 @@ class OSISBible(BibleDB):
Loads a Bible from file. Loads a Bible from file.
""" """
log.debug(u'Starting OSIS import from "%s"' % self.filename) 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 detect_file = None
try: try:
detect_file = open(self.filename, u'r') detect_file = open(self.filename, u'r')
@ -164,10 +165,10 @@ class OSISBible(BibleDB):
verse_text = verse_text.replace(u'</lb>', u'')\ verse_text = verse_text.replace(u'</lb>', u'')\
.replace(u'</l>', u'').replace(u'<lg>', u'')\ .replace(u'</l>', u'').replace(u'<lg>', u'')\
.replace(u'</lg>', u'').replace(u'</q>', u'')\ .replace(u'</lg>', u'').replace(u'</q>', u'')\
.replace(u'</div>', u'').replace(u'</w>', u'') .replace(u'</div>', u'').replace(u'</w>', u'')
verse_text = self.spaces_regex.sub(u' ', verse_text) verse_text = self.spaces_regex.sub(u' ', verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text) self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.commit()
self.wizard.incrementProgressBar(u'Finishing import...') self.wizard.incrementProgressBar(u'Finishing import...')
if match_count == 0: if match_count == 0:

View File

@ -45,7 +45,7 @@ class CustomPlugin(Plugin):
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Custom', u'1.9.1', plugin_helpers)
self.weight = -5 self.weight = -5
self.custommanager = CustomManager(self.config) self.custommanager = CustomManager()
self.edit_custom_form = EditCustomForm(self.custommanager) self.edit_custom_form = EditCustomForm(self.custommanager)
self.icon = build_icon(u':/media/media_custom.png') self.icon = build_icon(u':/media/media_custom.png')
self.status = PluginStatus.Active self.status = PluginStatus.Active

View File

@ -77,7 +77,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onVerseListViewPressed) self.onVerseListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(), 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 # Create other objects and forms
self.custommanager = custommanager self.custommanager = custommanager
self.initialise() self.initialise()
@ -86,7 +86,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == unicode(self.trUtf8('Save && Preview')) \ if button.text() == unicode(self.trUtf8('Save && Preview')) \
and self.saveCustom(): and self.saveCustom():
Receiver.send_message(u'preview_custom') Receiver.send_message(u'custom_preview')
def initialise(self): def initialise(self):
self.editAll = False self.editAll = False
@ -135,13 +135,13 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.previewButton.setVisible(True) self.previewButton.setVisible(True)
def closePressed(self): def closePressed(self):
Receiver.send_message(u'remote_edit_clear') Receiver.send_message(u'custom_edit_clear')
self.close() self.close()
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveCustom(): if self.saveCustom():
Receiver.send_message(u'load_custom_list') Receiver.send_message(u'custom_load_list')
self.close() self.close()
def saveCustom(self): def saveCustom(self):
@ -271,4 +271,4 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
if self.VerseTextEdit.toPlainText(): if self.VerseTextEdit.toPlainText():
self.VerseTextEdit.setFocus() self.VerseTextEdit.setFocus()
return False, self.trUtf8('You have unsaved data, please save or clear') return False, self.trUtf8('You have unsaved data, please save or clear')
return True, u'' return True, u''

View File

@ -25,14 +25,14 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool from openlp.core.lib import SettingsTab
class CustomTab(SettingsTab): class CustomTab(SettingsTab):
""" """
CustomTab is the Custom settings tab in the settings dialog. CustomTab is the Custom settings tab in the settings dialog.
""" """
def __init__(self, title, section=None): def __init__(self, title):
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'CustomTab') self.setObjectName(u'CustomTab')
@ -57,7 +57,7 @@ class CustomTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.CustomModeGroupBox.setTitle(self.trUtf8('Custom Display')) self.CustomModeGroupBox.setTitle(self.trUtf8('Custom Display'))
self.DisplayFooterCheckBox.setText( self.DisplayFooterCheckBox.setText(
self.trUtf8('Display Footer:')) self.trUtf8('Display Footer'))
def onDisplayFooterCheckBoxChanged(self, check_state): def onDisplayFooterCheckBoxChanged(self, check_state):
self.displayFooter = False self.displayFooter = False
@ -66,9 +66,11 @@ class CustomTab(SettingsTab):
self.displayFooter = True self.displayFooter = True
def load(self): def load(self):
self.displayFooter = str_to_bool( self.displayFooter = QtCore.QSettings().value(
self.config.get_config(u'display footer', True)) self.settingsSection + u'/display footer',
QtCore.QVariant(True)).toBool()
self.DisplayFooterCheckBox.setChecked(self.displayFooter) self.DisplayFooterCheckBox.setChecked(self.displayFooter)
def save(self): 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))

View File

@ -25,6 +25,9 @@
import logging import logging
from PyQt4 import QtCore
from openlp.core.utils import AppLocation
from openlp.plugins.custom.lib.models import init_models, metadata, CustomSlide from openlp.plugins.custom.lib.models import init_models, metadata, CustomSlide
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -36,27 +39,29 @@ class CustomManager():
""" """
log.info(u'Custom manager loaded') 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 Creates the connection to the database, and creates the tables if they
don't exist. don't exist.
""" """
self.config = config
log.debug(u'Custom Initialising') log.debug(u'Custom Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'custom')
self.db_url = u'' 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': if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/custom.sqlite' % \ self.db_url = u'sqlite:///%s/custom.sqlite' % \
self.config.get_data_path() AppLocation.get_section_data_path(u'custom')
else: else:
self.db_url = u'%s://%s:%s@%s/%s' % \ self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
(db_type, self.config.get_config(u'db username'), unicode(settings.value(u'db username').toString()),
self.config.get_config(u'db password'), unicode(settings.value(u'db password').toString()),
self.config.get_config(u'db hostname'), unicode(settings.value(u'db hostname').toString()),
self.config.get_config(u'db database')) unicode(settings.value(u'db database').toString()))
self.session = init_models(self.db_url) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)
settings.endGroup()
log.debug(u'Custom Initialised') log.debug(u'Custom Initialised')
def get_all_slides(self): def get_all_slides(self):
@ -107,4 +112,5 @@ class CustomManager():
return True return True
def get_customs_for_theme(self, theme): 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()

View File

@ -27,8 +27,8 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD,\ from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
Receiver, str_to_bool, ItemCapabilities Receiver, ItemCapabilities
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -45,7 +45,6 @@ class CustomMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title): def __init__(self, parent, icon, title):
self.PluginNameShort = u'Custom' self.PluginNameShort = u'Custom'
self.ConfigSection = title
self.IconPath = u'custom/custom' self.IconPath = u'custom/custom'
# this next is a class, not an instance of a class - it will # this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem # be instanced by the base MediaManagerItem
@ -58,13 +57,13 @@ class CustomMediaItem(MediaManagerItem):
def addEndHeaderBar(self): def addEndHeaderBar(self):
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'preview_custom'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def initPluginNameVisible(self): def initPluginNameVisible(self):
self.PluginNameVisible = self.trUtf8('Custom') self.PluginNameVisible = self.trUtf8('Custom')
@ -133,7 +132,7 @@ class CustomMediaItem(MediaManagerItem):
self.ListView.takeItem(row) self.ListView.takeItem(row)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
raw_slides =[] raw_slides = []
raw_footer = [] raw_footer = []
slide = None slide = None
theme = None theme = None
@ -164,8 +163,8 @@ class CustomMediaItem(MediaManagerItem):
service_item.title = title service_item.title = title
for slide in raw_slides: for slide in raw_slides:
service_item.add_from_text(slide[:30], slide) service_item.add_from_text(slide[:30], slide)
if str_to_bool(self.parent.config.get_config(u'display footer', True)) \ if QtCore.QSettings().value(self.settingsSection + u'/display footer',
or credit: QtCore.QVariant(True)).toBool() or credit:
raw_footer.append(title + u' ' + credit) raw_footer.append(title + u' ' + credit)
else: else:
raw_footer.append(u'') raw_footer.append(u'')

View File

@ -31,8 +31,8 @@ class ImageTab(SettingsTab):
""" """
ImageTab is the Image settings tab in the settings dialog. ImageTab is the Image settings tab in the settings dialog.
""" """
def __init__(self, title, section=None): def __init__(self, title):
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'ImageTab') self.setObjectName(u'ImageTab')
@ -71,12 +71,17 @@ class ImageTab(SettingsTab):
self.loop_delay = self.TimeoutSpinBox.value() self.loop_delay = self.TimeoutSpinBox.value()
def load(self): 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) self.TimeoutSpinBox.setValue(self.loop_delay)
def save(self): def save(self):
self.config.set_config(u'loop delay', self.loop_delay) QtCore.QSettings().setValue(self.settingsSection + u'/loop delay',
Receiver.send_message(u'update_spin_delay', self.loop_delay) QtCore.QVariant(self.loop_delay))
Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)
def postSetUp(self): def postSetUp(self):
Receiver.send_message(u'update_spin_delay', self.loop_delay) Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)

View File

@ -27,8 +27,10 @@ import logging
import os import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
contextMenuAction, ItemCapabilities contextMenuAction, ItemCapabilities, SettingsManager
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -47,7 +49,6 @@ class ImageMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title): def __init__(self, parent, icon, title):
self.PluginNameShort = u'Image' self.PluginNameShort = u'Image'
self.ConfigSection = title
self.IconPath = u'images/image' self.IconPath = u'images/image'
# this next is a class, not an instance of a class - it will # this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem # be instanced by the base MediaManagerItem
@ -59,8 +60,8 @@ class ImageMediaItem(MediaManagerItem):
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = self.trUtf8('Select Image(s)') self.OnNewPrompt = self.trUtf8('Select Image(s)')
self.OnNewFileMasks = \ self.OnNewFileMasks = self.trUtf8(
self.trUtf8('Images (*.jpg *.jpeg *.gif *.png *.bmp);; All files (*)') 'Images (*.jpg *.jpeg *.gif *.png *.bmp);; All files (*)')
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -76,10 +77,12 @@ class ImageMediaItem(MediaManagerItem):
QtGui.QAbstractItemView.ExtendedSelection) QtGui.QAbstractItemView.ExtendedSelection)
self.ListView.setIconSize(QtCore.QSize(88,50)) self.ListView.setIconSize(QtCore.QSize(88,50))
self.servicePath = os.path.join( 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): if not os.path.exists(self.servicePath):
os.mkdir(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): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
@ -112,20 +115,24 @@ class ImageMediaItem(MediaManagerItem):
for item in items: for item in items:
text = self.ListView.item(item.row()) text = self.ListView.item(item.row())
try: try:
os.remove(os.path.join(self.servicePath, unicode(text.text()))) os.remove(
os.path.join(self.servicePath, unicode(text.text())))
except: except:
#if not present do not worry #if not present do not worry
pass pass
self.ListView.takeItem(item.row()) 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): def loadList(self, list):
for file in list: for file in list:
(path, filename) = os.path.split(unicode(file)) (path, filename) = os.path.split(unicode(file))
thumb = os.path.join(self.servicePath, filename) thumb = os.path.join(self.servicePath, filename)
if os.path.exists(thumb): if os.path.exists(thumb):
self.validate(file, thumb) if self.validate(file, thumb):
icon = build_icon(thumb) icon = build_icon(thumb)
else:
icon = build_icon(u':/general/general_delete.png')
else: else:
icon = self.IconFromFile(file, thumb) icon = self.IconFromFile(file, thumb)
item_name = QtGui.QListWidgetItem(filename) item_name = QtGui.QListWidgetItem(filename)
@ -136,10 +143,11 @@ class ImageMediaItem(MediaManagerItem):
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
items = self.ListView.selectedIndexes() items = self.ListView.selectedIndexes()
if items: if items:
service_item.title = self.trUtf8('Image(s)') service_item.title = unicode(self.trUtf8('Image(s)'))
service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsMaintain)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions)
for item in items: for item in items:
bitem = self.ListView.item(item.row()) bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())

View File

@ -29,7 +29,7 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities ItemCapabilities, SettingsManager, contextMenuAction, Receiver
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -47,12 +47,12 @@ class MediaMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title): def __init__(self, parent, icon, title):
self.PluginNameShort = u'Media' self.PluginNameShort = u'Media'
self.IconPath = u'images/image' self.IconPath = u'images/image'
self.ConfigSection = u'media' self.background = False
self.ConfigSection = title
# this next is a class, not an instance of a class - it will # this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem # be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = MediaListView 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) MediaManagerItem.__init__(self, parent, icon, title)
self.singleServiceItem = False self.singleServiceItem = False
self.ServiceItemIconName = u':/media/media_video.png' self.ServiceItemIconName = u':/media/media_video.png'
@ -72,6 +72,47 @@ class MediaMediaItem(MediaManagerItem):
self.hasNewIcon = False self.hasNewIcon = False
self.hasEditIcon = 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): def generateSlideData(self, service_item, item=None):
if item is None: if item is None:
item = self.ListView.currentItem() item = self.ListView.currentItem()
@ -89,15 +130,16 @@ class MediaMediaItem(MediaManagerItem):
self.ListView.setSelectionMode( self.ListView.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection) QtGui.QAbstractItemView.ExtendedSelection)
self.ListView.setIconSize(QtCore.QSize(88,50)) 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): def onDeleteClick(self):
item = self.ListView.currentItem() item = self.ListView.currentItem()
if item: if item:
row = self.ListView.row(item) row = self.ListView.row(item)
self.ListView.takeItem(row) self.ListView.takeItem(row)
self.parent.config.set_list( SettingsManager.set_list(self.settingsSection,
self.ConfigSection, self.getFileList()) self.settingsSection, self.getFileList())
def loadList(self, list): def loadList(self, list):
for file in list: for file in list:

View File

@ -58,6 +58,7 @@ class MediaPlugin(Plugin):
if len(value) == 2: if len(value) == 2:
if list.find(value[1]) == -1: if list.find(value[1]) == -1:
list += u'*.%s ' % value[1] list += u'*.%s ' % value[1]
self.service_manager.supportedSuffixes(value[1])
type = u'' type = u''
return list, type return list, type

View File

@ -47,7 +47,7 @@ else:
from PyQt4 import QtCore from PyQt4 import QtCore
from presentationcontroller import PresentationController, PresentationDocument from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -155,6 +155,10 @@ class ImpressController(PresentationController):
desktop = self.get_uno_desktop() desktop = self.get_uno_desktop()
else: else:
desktop = self.get_com_desktop() desktop = self.get_com_desktop()
#Sometimes we get a failure and desktop is None
if not desktop:
log.exception(u'Failed to terminate OpenOffice')
return
docs = desktop.getComponents() docs = desktop.getComponents()
if docs.hasElements(): if docs.hasElements():
log.debug(u'OpenOffice not terminated') log.debug(u'OpenOffice not terminated')
@ -167,13 +171,13 @@ class ImpressController(PresentationController):
def add_doc(self, name): def add_doc(self, name):
log.debug(u'Add Doc OpenOffice') log.debug(u'Add Doc OpenOffice')
doc = ImpressDocument(self, name) doc = ImpressDocument(self, name)
self.docs.append(doc) self.docs.append(doc)
return doc return doc
class ImpressDocument(PresentationDocument): class ImpressDocument(PresentationDocument):
def __init__(self, controller, presentation): def __init__(self, controller, presentation):
log.debug(u'Init Presentation OpenOffice') log.debug(u'Init Presentation OpenOffice')
self.controller = controller self.controller = controller
self.document = None self.document = None

View File

@ -28,7 +28,9 @@ import os
from PyQt4 import QtCore, QtGui 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 from openlp.plugins.presentations.lib import MessageListener
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -50,7 +52,6 @@ class PresentationMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title, controllers): def __init__(self, parent, icon, title, controllers):
self.controllers = controllers self.controllers = controllers
self.PluginNameShort = u'Presentation' self.PluginNameShort = u'Presentation'
self.ConfigSection = title
self.IconPath = u'presentations/presentation' self.IconPath = u'presentations/presentation'
self.Automatic = u'' self.Automatic = u''
# this next is a class, not an instance of a class - it will # this next is a class, not an instance of a class - it will
@ -68,10 +69,12 @@ class PresentationMediaItem(MediaManagerItem):
fileType = u'' fileType = u''
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled: 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: for type in types:
if fileType.find(type) == -1: if fileType.find(type) == -1:
fileType += u'*%s ' % type fileType += u'*%s ' % type
self.parent.service_manager.supportedSuffixes(type)
self.OnNewFileMasks = self.trUtf8('Presentations (%s)' % fileType) self.OnNewFileMasks = self.trUtf8('Presentations (%s)' % fileType)
def requiredIcons(self): def requiredIcons(self):
@ -103,7 +106,14 @@ class PresentationMediaItem(MediaManagerItem):
self.PageLayout.addWidget(self.PresentationWidget) self.PageLayout.addWidget(self.PresentationWidget)
def initialise(self): 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) self.loadList(list)
for item in self.controllers: for item in self.controllers:
#load the drop down selection #load the drop down selection
@ -128,8 +138,32 @@ class PresentationMediaItem(MediaManagerItem):
'A presentation with that filename already exists.'), 'A presentation with that filename already exists.'),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
else: 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 = QtGui.QListWidgetItem(filename)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
item_name.setIcon(icon)
self.ListView.addItem(item_name) self.ListView.addItem(item_name)
def onDeleteClick(self): def onDeleteClick(self):
@ -137,8 +171,8 @@ class PresentationMediaItem(MediaManagerItem):
if item: if item:
row = self.ListView.row(item) row = self.ListView.row(item)
self.ListView.takeItem(row) self.ListView.takeItem(row)
self.parent.config.set_list( SettingsManager.set_list(self.settingsSection,
self.ConfigSection, self.getFileList()) self.settingsSection, self.getFileList())
filepath = unicode((item.data(QtCore.Qt.UserRole)).toString()) filepath = unicode((item.data(QtCore.Qt.UserRole)).toString())
#not sure of this has errors #not sure of this has errors
#John please can you look at . #John please can you look at .
@ -154,26 +188,29 @@ class PresentationMediaItem(MediaManagerItem):
service_item.title = unicode(self.DisplayTypeComboBox.currentText()) service_item.title = unicode(self.DisplayTypeComboBox.currentText())
service_item.shortname = unicode(self.DisplayTypeComboBox.currentText()) service_item.shortname = unicode(self.DisplayTypeComboBox.currentText())
shortname = service_item.shortname shortname = service_item.shortname
for item in items: if shortname:
bitem = self.ListView.item(item.row()) for item in items:
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) bitem = self.ListView.item(item.row())
if shortname == self.Automatic: filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
service_item.shortname = self.findControllerByType(filename) if shortname == self.Automatic:
if not service_item.shortname: service_item.shortname = self.findControllerByType(filename)
return False if not service_item.shortname:
controller = self.controllers[service_item.shortname] return False
(path, name) = os.path.split(filename) controller = self.controllers[service_item.shortname]
doc = controller.add_doc(filename) (path, name) = os.path.split(filename)
if doc.get_slide_preview_file(1) is None: doc = controller.add_doc(filename)
doc.load_presentation() if doc.get_slide_preview_file(1) is None:
i = 1 doc.load_presentation()
img = doc.get_slide_preview_file(i) i = 1
while img:
service_item.add_from_command(path, name, img)
i = i + 1
img = doc.get_slide_preview_file(i) img = doc.get_slide_preview_file(i)
doc.close_presentation() while img:
return True 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): def findControllerByType(self, filename):
filetype = os.path.splitext(filename)[1] filetype = os.path.splitext(filename)[1]

View File

@ -44,7 +44,7 @@ class Controller(object):
self.doc = None self.doc = None
log.info(u'%s controller loaded' % live) log.info(u'%s controller loaded' % live)
def addHandler(self, controller, file, isBlank): def addHandler(self, controller, file, isBlank):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
self.controller = controller self.controller = controller
if self.doc is not None: if self.doc is not None:
@ -55,7 +55,7 @@ class Controller(object):
self.doc.start_presentation() self.doc.start_presentation()
if isBlank: if isBlank:
self.blank() self.blank()
Receiver.send_message(u'live_slide_hide') Receiver.send_message(u'maindisplay_hide')
self.doc.slidenumber = 0 self.doc.slidenumber = 0
def activate(self): def activate(self):
@ -144,7 +144,7 @@ class Controller(object):
""" """
log.debug(u'Live = %s, shutdown' % self.isLive) log.debug(u'Live = %s, shutdown' % self.isLive)
if self.isLive: if self.isLive:
Receiver.send_message(u'live_slide_show') Receiver.send_message(u'maindisplay_show')
self.doc.close_presentation() self.doc.close_presentation()
self.doc = None self.doc = None
#self.doc.slidenumber = 0 #self.doc.slidenumber = 0
@ -160,12 +160,23 @@ class Controller(object):
return return
self.doc.blank_screen() self.doc.blank_screen()
def stop(self):
log.debug(u'Live = %s, stop' % self.isLive)
if not self.isLive:
return
if not self.doc.is_loaded():
return
if not self.doc.is_active():
return
self.doc.stop_presentation()
def unblank(self): def unblank(self):
log.debug(u'Live = %s, unblank' % self.isLive) log.debug(u'Live = %s, unblank' % self.isLive)
if not self.isLive: if not self.isLive:
return return
self.activate() 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.goto_slide(self.doc.slidenumber)
self.doc.unblank_screen() self.doc.unblank_screen()
@ -189,6 +200,8 @@ class MessageListener(object):
QtCore.SIGNAL(u'presentations_start'), self.startup) QtCore.SIGNAL(u'presentations_start'), self.startup)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_stop'), self.shutdown) QtCore.SIGNAL(u'presentations_stop'), self.shutdown)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_hide'), self.hide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_first'), self.first) QtCore.SIGNAL(u'presentations_first'), self.first)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -205,91 +218,93 @@ class MessageListener(object):
QtCore.SIGNAL(u'presentations_unblank'), self.unblank) QtCore.SIGNAL(u'presentations_unblank'), self.unblank)
self.timer = QtCore.QTimer() self.timer = QtCore.QTimer()
self.timer.setInterval(500) 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): def startup(self, message):
""" """
Start of new presentation Start of new presentation
Save the handler as any new presentations start here Save the handler as any new presentations start here
""" """
isLive, item = self.decode_message(message)
log.debug(u'Startup called with message %s' % 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: if self.handler == self.mediaitem.Automatic:
self.handler = self.mediaitem.findControllerByType(file) self.handler = self.mediaitem.findControllerByType(file)
if not self.handler: if not self.handler:
return return
if isLive: if isLive:
controller = self.liveHandler controller = self.liveHandler
else: else:
controller = self.previewHandler controller = self.previewHandler
controller.addHandler(self.controllers[self.handler], file, isBlank) controller.addHandler(self.controllers[self.handler], file, isBlank)
def slide(self, message): def decode_message(self, message):
slide, live = self.splitMessage(message) if len(message) == 3:
if live: return message[1], message[0], message[2]
self.liveHandler.slide(slide, live)
else: 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: if isLive:
self.liveHandler.first() self.liveHandler.first()
else: else:
self.previewHandler.first() self.previewHandler.first()
def last(self, isLive): def last(self, message):
isLive, item = self.decode_message(message)
if isLive: if isLive:
self.liveHandler.last() self.liveHandler.last()
else: else:
self.previewHandler.last() self.previewHandler.last()
def next(self, isLive): def next(self, message):
isLive, item = self.decode_message(message)
if isLive: if isLive:
self.liveHandler.next() self.liveHandler.next()
else: else:
self.previewHandler.next() self.previewHandler.next()
def previous(self, isLive): def previous(self, message):
isLive, item = self.decode_message(message)
if isLive: if isLive:
self.liveHandler.previous() self.liveHandler.previous()
else: else:
self.previewHandler.previous() self.previewHandler.previous()
def shutdown(self, isLive): def shutdown(self, message):
isLive, item = self.decode_message(message)
if isLive: if isLive:
Receiver.send_message(u'maindisplay_show')
self.liveHandler.shutdown() self.liveHandler.shutdown()
Receiver.send_message(u'live_slide_show')
else: else:
self.previewHandler.shutdown() self.previewHandler.shutdown()
def blank(self): def hide(self, message):
self.liveHandler.blank() isLive, item = self.decode_message(message)
if isLive:
self.liveHandler.stop()
def unblank(self): def blank(self, message):
self.liveHandler.unblank() isLive, item = self.decode_message(message)
if isLive:
self.liveHandler.blank()
def splitMessage(self, message): def unblank(self, message):
""" isLive, item = self.decode_message(message)
Splits the selection messages if isLive:
into it's component parts self.liveHandler.unblank()
``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 timeout(self): def timeout(self):
self.liveHandler.poll() self.liveHandler.poll()

View File

@ -31,7 +31,7 @@ if os.name == u'nt':
import _winreg import _winreg
import win32ui import win32ui
from presentationcontroller import PresentationController, PresentationDocument from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -62,7 +62,8 @@ class PowerpointController(PresentationController):
log.debug(u'check_available') log.debug(u'check_available')
if os.name == u'nt': if os.name == u'nt':
try: try:
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close() _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
u'PowerPoint.Application').Close()
return True return True
except: except:
pass pass
@ -96,13 +97,13 @@ class PowerpointController(PresentationController):
def add_doc(self, name): def add_doc(self, name):
log.debug(u'Add Doc PowerPoint') log.debug(u'Add Doc PowerPoint')
doc = PowerpointDocument(self, name) doc = PowerpointDocument(self, name)
self.docs.append(doc) self.docs.append(doc)
return doc return doc
class PowerpointDocument(PresentationDocument): class PowerpointDocument(PresentationDocument):
def __init__(self, controller, presentation): def __init__(self, controller, presentation):
log.debug(u'Init Presentation Powerpoint') log.debug(u'Init Presentation Powerpoint')
self.presentation = None self.presentation = None
self.controller = controller self.controller = controller

View File

@ -82,7 +82,8 @@ class PptviewController(PresentationController):
if self.process: if self.process:
return return
log.debug(u'start PPTView') 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): def kill(self):
""" """
@ -94,13 +95,12 @@ class PptviewController(PresentationController):
def add_doc(self, name): def add_doc(self, name):
log.debug(u'Add Doc PPTView') log.debug(u'Add Doc PPTView')
doc = PptviewDocument(self, name) doc = PptviewDocument(self, name)
self.docs.append(doc) self.docs.append(doc)
return doc return doc
class PptviewDocument(PresentationDocument): class PptviewDocument(PresentationDocument):
def __init__(self, controller, presentation):
def __init__(self, controller, presentation):
log.debug(u'Init Presentation PowerPoint') log.debug(u'Init Presentation PowerPoint')
self.presentation = None self.presentation = None
self.pptid = None self.pptid = None

View File

@ -30,6 +30,7 @@ import shutil
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver from openlp.core.lib import Receiver
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -68,7 +69,8 @@ class PresentationController(object):
Called at system exit to clean up any running presentations Called at system exit to clean up any running presentations
``check_available()`` ``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()`` ``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails Deletes presentation specific files, e.g. thumbnails
@ -78,13 +80,14 @@ class PresentationController(object):
def __init__(self, plugin=None, name=u'PresentationController'): def __init__(self, plugin=None, name=u'PresentationController'):
""" """
This is the constructor for the presentationcontroller object. This is the constructor for the presentationcontroller object. This
This provides an easy way for descendent plugins to populate common data. provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so:: This method *must* be overridden, like so::
class MyPresentationController(PresentationController): class MyPresentationController(PresentationController):
def __init__(self, plugin): def __init__(self, plugin):
PresentationController.__init(self, plugin, u'My Presenter App') PresentationController.__init(
self, plugin, u'My Presenter App')
``plugin`` ``plugin``
Defaults to *None*. The presentationplugin object Defaults to *None*. The presentationplugin object
@ -97,13 +100,16 @@ class PresentationController(object):
self.docs = [] self.docs = []
self.plugin = plugin self.plugin = plugin
self.name = name self.name = name
self.settingsSection = self.plugin.settingsSection
self.available = self.check_available() self.available = self.check_available()
if self.available: if self.available:
self.enabled = int(plugin.config.get_config( self.enabled = QtCore.QSettings().value(
name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked self.settingsSection + u'/' + name,
QtCore.Qt.Unchecked).toInt()[0] == QtCore.Qt.Checked
else: else:
self.enabled = False 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') name, u'thumbnails')
self.thumbnailprefix = u'slide' self.thumbnailprefix = u'slide'
if not os.path.isdir(self.thumbnailroot): 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 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.slidenumber = 0
self.controller = controller self.controller = controller
self.store_filename(name) self.store_filename(name)
@ -237,11 +243,12 @@ class PresentationDocument(object):
if not os.path.isdir(self.thumbnailpath): if not os.path.isdir(self.thumbnailpath):
os.mkdir(self.thumbnailpath) os.mkdir(self.thumbnailpath)
def get_file_name(self, presentation): def get_file_name(self, presentation):
return os.path.split(presentation)[1] return os.path.split(presentation)[1]
def get_thumbnail_path(self, presentation): def get_thumbnail_path(self, presentation):
return os.path.join(self.controller.thumbnailroot, self.get_file_name(presentation)) return os.path.join(
self.controller.thumbnailroot, self.get_file_name(presentation))
def check_thumbnails(self): def check_thumbnails(self):
""" """
@ -326,11 +333,11 @@ class PresentationDocument(object):
pass pass
def next_step(self): def next_step(self):
""" """
Triggers the next effect of slide on the running presentation Triggers the next effect of slide on the running presentation
This might be the next animation on the current slide, or the next slide This might be the next animation on the current slide, or the next slide
""" """
pass pass
def previous_step(self): def previous_step(self):
""" """
@ -361,7 +368,7 @@ class PresentationDocument(object):
prefix = u'live' prefix = u'live'
else: else:
prefix = u'preview' prefix = u'preview'
Receiver.send_message(u'%s_slidecontroller_change' % prefix, Receiver.send_message(u'slidecontroller_%s_change' % prefix,
self.slidenumber - 1) self.slidenumber - 1)
def get_slide_text(self, slide_no): def get_slide_text(self, slide_no):

View File

@ -23,7 +23,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab from openlp.core.lib import SettingsTab
@ -31,9 +31,9 @@ class PresentationTab(SettingsTab):
""" """
PresentationsTab is the Presentations settings tab in the settings dialog. 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 self.controllers = controllers
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'PresentationTab') self.setObjectName(u'PresentationTab')
@ -93,19 +93,21 @@ class PresentationTab(SettingsTab):
controller = self.controllers[key] controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
checkbox.setText( checkbox.setText(
u'%s %s:' % (controller.name, self.trUtf8('available'))) u'%s %s' % (controller.name, self.trUtf8('available')))
def load(self): def load(self):
for key in self.controllers: for key in self.controllers:
controller = self.controllers[key] controller = self.controllers[key]
if controller.available: if controller.available:
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
checkbox.setChecked( checkbox.setChecked(QtCore.QSettings().value(
int(self.config.get_config(controller.name, 0))) self.settingsSection + u'/' + controller.name,
QtCore.QVariant(0)).toInt()[0])
def save(self): def save(self):
for key in self.controllers: for key in self.controllers:
controller = self.controllers[key] controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
self.config.set_config( QtCore.QSettings().setValue(
controller.name, unicode(checkbox.checkState())) self.settingsSection + u'/' + controller.name,
QtCore.QVariant(checkbox.checkState()))

View File

@ -26,7 +26,7 @@
import os import os
import logging 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.core.utils import AppLocation
from openlp.plugins.presentations.lib import * from openlp.plugins.presentations.lib import *
@ -53,15 +53,10 @@ class PresentationPlugin(Plugin):
log.info(u'Presentations Initialising') log.info(u'Presentations Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.insert_toolbox_item() self.insert_toolbox_item()
presentation_types = []
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled: if self.controllers[controller].enabled:
presentation_types.append({u'%s' % controller : self.controllers[controller].supports})
self.controllers[controller].start_process() self.controllers[controller].start_process()
Receiver.send_message(
u'presentation types', presentation_types)
def finalise(self): def finalise(self):
log.info(u'Plugin Finalise') log.info(u'Plugin Finalise')
#Ask each controller to tidy up #Ask each controller to tidy up
@ -101,7 +96,9 @@ class PresentationPlugin(Plugin):
try: try:
__import__(modulename, globals(), locals(), []) __import__(modulename, globals(), locals(), [])
except ImportError, e: 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__() controller_classes = PresentationController.__subclasses__()
for controller_class in controller_classes: for controller_class in controller_classes:
controller = controller_class(self) controller = controller_class(self)

View File

@ -0,0 +1,119 @@
<html>
<head>
<title>OpenLP Controller</title>
<script type='text/javascript'>
function send_event(eventname, data){
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if(req.readyState==4)
response(eventname, req);
}
var url = '';
if(eventname.substr(-8) == '_request')
url = 'request';
else
url = 'send';
url += '/' + eventname;
if(data!=null)
url += '?q=' + escape(data);
req.open('GET', url, true);
req.send();
}
function failed_response(eventname, req){
switch(eventname){
case 'remotes_poll_request':
if(req.status==408)
send_event("remotes_poll_request");
break;
}
}
function response(eventname, req){
if(req.status!=200){
failed_response(eventname, req);
return;
}
text = req.responseText;
switch(eventname){
case 'servicemanager_list_request':
var data = eval('(' + text + ')');
var html = '<table>';
for(row in data){
html += '<tr onclick="send_event('
html += "'servicemanager_set_item', " + row + ')"';
if(data[row]['selected'])
html += ' style="font-weight: bold"';
html += '>'
html += '<td>' + (parseInt(row)+1) + '</td>'
html += '<td>' + data[row]['title'] + '</td>'
html += '<td>' + data[row]['plugin'] + '</td>'
html += '<td>' + data[row]['notes'] + '</td>'
html += '</tr>';
}
html += '</table>';
document.getElementById('service').innerHTML = html;
break;
case 'slidecontroller_live_text_request':
var data = eval('(' + text + ')');
var html = '<table>';
for(row in data){
html += '<tr onclick="send_event('
html += "'slidecontroller_live_set', " + row + ')"';
if(data[row]['selected'])
html += ' style="font-weight: bold"';
html += '>';
html += '<td>' + data[row]['tag'] + '</td>';
html += '<td>' + data[row]['text'].replace(/\n/g, '<br>');
html += '</td></tr>';
}
html += '</table>';
document.getElementById('currentitem').innerHTML = html;
break;
case 'remotes_poll_request':
send_event("remotes_poll_request");
send_event("servicemanager_list_request");
send_event("slidecontroller_live_text_request");
break;
}
}
send_event("servicemanager_list_request");
send_event("slidecontroller_live_text_request");
send_event("remotes_poll_request");
</script>
</head>
<body>
<h1>OpenLP Controller</h1>
<input type='button' value='<- Previous Slide'
onclick='send_event("slidecontroller_live_previous");' />
<input type='button' value='Next Slide ->'
onclick='send_event("slidecontroller_live_next");' />
<br/>
<input type='button' value='<- Previous Item'
onclick='send_event("servicemanager_previous_item");' />
<input type='button' value='Next Item ->'
onclick='send_event("servicemanager_next_item");' />
<br/>
<input type='button' value='Blank'
onclick='send_event("slidecontroller_live_blank");' />
<input type='button' value='Unblank'
onclick='send_event("slidecontroller_live_unblank");' />
<br/>
<label>Alert text</label><input id='alert' type='text' />
<input type='button' value='Send'
onclick='send_event("alerts_text",
document.getElementById("alert").value);' />
<hr>
<input type='button' value='Order of service'
onclick='send_event("servicemanager_list_request");'>
<i>(Click service item to go live.)</i>
<div id='service'></div>
<hr>
<input type='button' value='Current item'
onclick='send_event("slidecontroller_live_text_request");'>
<i>(Click verse to display.)</i>
<div id='currentitem'></div>
<hr>
<a href="http://www.openlp.org/">OpenLP website</a>
</body>
</html>

View File

@ -24,3 +24,4 @@
############################################################################### ###############################################################################
from remotetab import RemoteTab from remotetab import RemoteTab
from httpserver import HttpServer

View File

@ -0,0 +1,337 @@
# -*- 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
mimetype = 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'':
mimetype, html = self.serve_file(u'')
elif folders[1] == u'files':
mimetype, html = self.serve_file(os.sep.join(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:
if mimetype:
self.send_200_ok(mimetype)
else:
self.send_200_ok()
self.socket.write(html)
else:
self.send_404_not_found()
self.close()
def serve_file(self, filename):
"""
Send a file to the socket. For now, just a subset of file types
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'
path = os.path.normpath(os.path.join(self.parent.html_dir, filename))
if not path.startswith(self.parent.html_dir):
return None
(fileroot, ext) = os.path.splitext(filename)
if ext == u'.html':
mimetype = u'text/html'
elif ext == u'.css':
mimetype = u'text/css'
elif ext == u'.js':
mimetype = u'application/x-javascript'
elif ext == u'.jpg':
mimetype = u'image/jpeg'
elif ext == u'.gif':
mimetype = u'image/gif'
elif ext == u'.png':
mimetype = u'image/png'
else:
return (None, None)
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 (mimetype, html)
def load_params(self, query):
"""
Decode the query string parameters sent from the browser
"""
log.debug(u'loading params %s' % query)
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
"""
log.debug(u'Processing event %s' % event)
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)
"""
log.debug(u'Processing request %s' % event)
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
"""
log.debug(u'Processing response for %s' % self.event)
if not self.socket:
return
self.timer.stop()
html = json.dumps(data)
self.send_200_ok()
self.socket.write(html)
self.close()
def send_200_ok(self, mimetype='text/html; charset="utf-8"'):
"""
Successful request. Send OK headers. Assume html for now.
"""
self.socket.write(u'HTTP/1.1 200 OK\r\n' + \
u'Content-Type: %s\r\n\r\n' % mimetype)
def send_404_not_found(self):
"""
Invalid url. Say so
"""
self.socket.write(u'HTTP/1.1 404 Not Found\r\n'+ \
u'Content-Type: text/html; charset="utf-8"\r\n' + \
u'\r\n')
def send_408_timeout(self):
"""
A _request hasn't returned anything in the timeout period.
Return timeout
"""
self.socket.write(u'HTTP/1.1 408 Request Timeout\r\n')
def timeout(self):
"""
Listener for timeout signal
"""
if not self.socket:
return
html = self.send_408_timeout()
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)

View File

@ -23,7 +23,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab from openlp.core.lib import SettingsTab
@ -31,8 +31,8 @@ class RemoteTab(SettingsTab):
""" """
RemoteTab is the Remotes settings tab in the settings dialog. RemoteTab is the Remotes settings tab in the settings dialog.
""" """
def __init__(self, title, section=None): def __init__(self, title):
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'RemoteTab') self.setObjectName(u'RemoteTab')
@ -57,8 +57,9 @@ class RemoteTab(SettingsTab):
def load(self): def load(self):
self.RemotePortSpinBox.setValue( 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): def save(self):
self.config.set_config( QtCore.QSettings().setValue(self.settingsSection + u'/remote port',
u'remote port', unicode(self.RemotePortSpinBox.value())) QtCore.QVariant(self.RemotePortSpinBox.value()))

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtNetwork, QtCore from PyQt4 import QtNetwork, QtCore
from openlp.core.lib import Plugin, Receiver 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__) log = logging.getLogger(__name__)
@ -36,20 +36,26 @@ class RemotesPlugin(Plugin):
log.info(u'Remote Plugin loaded') log.info(u'Remote Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
"""
remotes constructor
"""
Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers)
self.weight = -1 self.weight = -1
self.server = None self.server = None
def initialise(self): def initialise(self):
"""
Initialise the remotes plugin, and start the http server
"""
log.debug(u'initialise') log.debug(u'initialise')
Plugin.initialise(self) Plugin.initialise(self)
self.insert_toolbox_item() self.insert_toolbox_item()
self.server = QtNetwork.QUdpSocket() self.server = HttpServer(self)
self.server.bind(int(self.config.get_config(u'remote port', 4316)))
QtCore.QObject.connect(self.server,
QtCore.SIGNAL(u'readyRead()'), self.readData)
def finalise(self): def finalise(self):
"""
Tidy up and close down the http server
"""
log.debug(u'finalise') log.debug(u'finalise')
self.remove_toolbox_item() self.remove_toolbox_item()
if self.server: if self.server:
@ -61,25 +67,12 @@ class RemotesPlugin(Plugin):
""" """
return RemoteTab(self.name) 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): def about(self):
"""
Information about this plugin
"""
about_text = self.trUtf8('<b>Remote Plugin</b><br>This plugin ' about_text = self.trUtf8('<b>Remote Plugin</b><br>This plugin '
'provides the ability to send messages to a running version of ' 'provides the ability to send messages to a running version of '
'openlp on a different computer.<br>The Primary use for this ' 'openlp on a different computer via a web browser or other app<br>'
'would be to send alerts from a creche') 'The Primary use for this would be to send alerts from a creche')
return about_text return about_text

View File

@ -135,7 +135,7 @@ class Ui_EditSongDialog(object):
sizePolicy.setHeightForWidth( sizePolicy.setHeightForWidth(
self.AuthorsSelectionComboItem.sizePolicy().hasHeightForWidth()) self.AuthorsSelectionComboItem.sizePolicy().hasHeightForWidth())
self.AuthorsSelectionComboItem.setSizePolicy(sizePolicy) self.AuthorsSelectionComboItem.setSizePolicy(sizePolicy)
self.AuthorsSelectionComboItem.setEditable(False) self.AuthorsSelectionComboItem.setEditable(True)
self.AuthorsSelectionComboItem.setInsertPolicy( self.AuthorsSelectionComboItem.setInsertPolicy(
QtGui.QComboBox.InsertAlphabetically) QtGui.QComboBox.InsertAlphabetically)
self.AuthorsSelectionComboItem.setSizeAdjustPolicy( self.AuthorsSelectionComboItem.setSizeAdjustPolicy(
@ -212,6 +212,7 @@ class Ui_EditSongDialog(object):
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth( sizePolicy.setHeightForWidth(
self.SongTopicCombo.sizePolicy().hasHeightForWidth()) self.SongTopicCombo.sizePolicy().hasHeightForWidth())
self.SongTopicCombo.setEditable(True)
self.SongTopicCombo.setSizePolicy(sizePolicy) self.SongTopicCombo.setSizePolicy(sizePolicy)
self.SongTopicCombo.setObjectName(u'SongTopicCombo') self.SongTopicCombo.setObjectName(u'SongTopicCombo')
self.TopicAddLayout.addWidget(self.SongTopicCombo) self.TopicAddLayout.addWidget(self.SongTopicCombo)
@ -256,6 +257,7 @@ class Ui_EditSongDialog(object):
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.SongbookCombo.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.SongbookCombo.sizePolicy().hasHeightForWidth())
self.SongbookCombo.setEditable(True)
self.SongbookCombo.setSizePolicy(sizePolicy) self.SongbookCombo.setSizePolicy(sizePolicy)
self.SongbookCombo.setObjectName(u'SongbookCombo') self.SongbookCombo.setObjectName(u'SongbookCombo')
self.SongbookLayout.addWidget(self.SongbookCombo, 0, 0, 1, 1) self.SongbookLayout.addWidget(self.SongbookCombo, 0, 0, 1, 1)
@ -293,6 +295,7 @@ class Ui_EditSongDialog(object):
self.ThemeLayout.setMargin(8) self.ThemeLayout.setMargin(8)
self.ThemeLayout.setObjectName(u'ThemeLayout') self.ThemeLayout.setObjectName(u'ThemeLayout')
self.ThemeSelectionComboItem = QtGui.QComboBox(self.ThemeGroupBox) self.ThemeSelectionComboItem = QtGui.QComboBox(self.ThemeGroupBox)
self.ThemeSelectionComboItem.setEditable(True)
self.ThemeSelectionComboItem.setObjectName(u'ThemeSelectionComboItem') self.ThemeSelectionComboItem.setObjectName(u'ThemeSelectionComboItem')
self.ThemeLayout.addWidget(self.ThemeSelectionComboItem) self.ThemeLayout.addWidget(self.ThemeSelectionComboItem)
self.ThemeAddButton = QtGui.QPushButton(self.ThemeGroupBox) self.ThemeAddButton = QtGui.QPushButton(self.ThemeGroupBox)

View File

@ -93,7 +93,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.QObject.connect(self.CCLNumberEdit, QtCore.QObject.connect(self.CCLNumberEdit,
QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus) QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus)
QtCore.QObject.connect(Receiver.get_receiver(), 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.QObject.connect(self.CommentsEdit,
QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus) QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus)
QtCore.QObject.connect(self.VerseOrderEdit, QtCore.QObject.connect(self.VerseOrderEdit,
@ -122,6 +122,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def loadAuthors(self): def loadAuthors(self):
authors = self.songmanager.get_authors() authors = self.songmanager.get_authors()
authorsCompleter = QtGui.QCompleter(
[author.display_name for author in authors],
self.AuthorsSelectionComboItem)
authorsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive);
self.AuthorsSelectionComboItem.setCompleter(authorsCompleter);
self.AuthorsSelectionComboItem.clear() self.AuthorsSelectionComboItem.clear()
for author in authors: for author in authors:
row = self.AuthorsSelectionComboItem.count() row = self.AuthorsSelectionComboItem.count()
@ -131,6 +136,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def loadTopics(self): def loadTopics(self):
topics = self.songmanager.get_topics() topics = self.songmanager.get_topics()
topicsCompleter = QtGui.QCompleter(
[topic.name for topic in topics],
self.SongTopicCombo)
topicsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive);
self.SongTopicCombo.setCompleter(topicsCompleter);
self.SongTopicCombo.clear() self.SongTopicCombo.clear()
for topic in topics: for topic in topics:
row = self.SongTopicCombo.count() row = self.SongTopicCombo.count()
@ -139,6 +149,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def loadBooks(self): def loadBooks(self):
books = self.songmanager.get_books() books = self.songmanager.get_books()
booksCompleter = QtGui.QCompleter(
[book.name for book in books], self.SongbookCombo)
booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive);
self.SongbookCombo.setCompleter(booksCompleter);
self.SongbookCombo.clear() self.SongbookCombo.clear()
self.SongbookCombo.addItem(u' ') self.SongbookCombo.addItem(u' ')
for book in books: for book in books:
@ -147,6 +161,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongbookCombo.setItemData(row, QtCore.QVariant(book.id)) self.SongbookCombo.setItemData(row, QtCore.QVariant(book.id))
def loadThemes(self, theme_list): def loadThemes(self, theme_list):
themesCompleter = QtGui.QCompleter(
[theme for theme in theme_list],
self.ThemeSelectionComboItem)
themesCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive);
self.ThemeSelectionComboItem.setCompleter(themesCompleter);
self.ThemeSelectionComboItem.clear() self.ThemeSelectionComboItem.clear()
self.ThemeSelectionComboItem.addItem(u' ') self.ThemeSelectionComboItem.addItem(u' ')
for theme in theme_list: for theme in theme_list:
@ -320,7 +339,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verse_form.setVerse(u'', self.VerseListWidget.count() + 1, True) self.verse_form.setVerse(u'', self.VerseListWidget.count() + 1, True)
if self.verse_form.exec_(): if self.verse_form.exec_():
afterText, verse, subVerse = self.verse_form.getVerse() afterText, verse, subVerse = self.verse_form.getVerse()
data = u'%s:%s' %(verse, subVerse) data = u'%s:%s' % (verse, subVerse)
item = QtGui.QListWidgetItem(afterText) item = QtGui.QListWidgetItem(afterText)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data)) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
item.setText(afterText) item.setText(afterText)
@ -331,11 +350,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if item: if item:
tempText = item.text() tempText = item.text()
verseId = unicode((item.data(QtCore.Qt.UserRole)).toString()) verseId = unicode((item.data(QtCore.Qt.UserRole)).toString())
self.verse_form.setVerse(tempText, \ self.verse_form.setVerse(
self.VerseListWidget.count(), True, verseId) tempText, self.VerseListWidget.count(), True, verseId)
if self.verse_form.exec_(): if self.verse_form.exec_():
afterText, verse, subVerse = self.verse_form.getVerse() 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.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
item.setText(afterText) item.setText(afterText)
#number of lines has change so repaint the list moving the data #number of lines has change so repaint the list moving the data
@ -464,16 +483,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == unicode(self.trUtf8('Save && Preview')) \ if button.text() == unicode(self.trUtf8('Save && Preview')) \
and self.saveSong(): and self.saveSong():
Receiver.send_message(u'preview_song') Receiver.send_message(u'songs_preview')
def closePressed(self): def closePressed(self):
Receiver.send_message(u'remote_edit_clear') Receiver.send_message(u'songs_edit_clear')
self.close() self.close()
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveSong(): if self.saveSong():
Receiver.send_message(u'load_song_list') Receiver.send_message(u'songs_load_list')
self.close() self.close()
def saveSong(self): def saveSong(self):

View File

@ -25,6 +25,9 @@
import logging import logging
from PyQt4 import QtCore
from openlp.core.utils import AppLocation
from openlp.plugins.songs.lib.models import init_models, metadata, Song, \ from openlp.plugins.songs.lib.models import init_models, metadata, Song, \
Author, Topic, Book Author, Topic, Book
@ -37,26 +40,33 @@ class SongManager():
""" """
log.info(u'Song manager loaded') 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 Creates the connection to the database, and creates the tables if they
don't exist. don't exist.
""" """
self.config = config
log.debug(u'Song Initialising') log.debug(u'Song Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'songs')
self.db_url = u'' 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': if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/songs.sqlite' % \ self.db_url = u'sqlite:///%s/songs.sqlite' % \
self.config.get_data_path() AppLocation.get_section_data_path(u'songs')
else: else:
self.db_url = db_type + 'u://' + \ self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
self.config.get_config(u'db username') + u':' + \ unicode(settings.value(
self.config.get_config(u'db password') + u'@' + \ u'db username', QtCore.QVariant(u'')).toString()),
self.config.get_config(u'db hostname') + u'/' + \ unicode(settings.value(
self.config.get_config(u'db database') 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) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)
settings.endGroup()
log.debug(u'Song Initialised') log.debug(u'Song Initialised')
def get_songs(self): def get_songs(self):

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, \ from openlp.core.lib import MediaManagerItem, SongXMLParser, \
BaseListWithDnD, Receiver, str_to_bool, ItemCapabilities BaseListWithDnD, Receiver, ItemCapabilities
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -46,7 +46,6 @@ class SongMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title): def __init__(self, parent, icon, title):
self.PluginNameShort = u'Song' self.PluginNameShort = u'Song'
self.ConfigSection = title
self.IconPath = u'songs/song' self.IconPath = u'songs/song'
self.ListViewWithDnD_class = SongListView self.ListViewWithDnD_class = SongListView
MediaManagerItem.__init__(self, parent, icon, title) MediaManagerItem.__init__(self, parent, icon, title)
@ -122,19 +121,20 @@ class SongMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'textChanged(const QString&)'), QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onSearchTextEditChanged) self.onSearchTextEditChanged)
QtCore.QObject.connect(Receiver.get_receiver(), 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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(), 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.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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) QtCore.SIGNAL(u'songs_edit_clear'), self.onRemoteEditClear)
def configUpdated(self): def configUpdated(self):
self.searchAsYouType = str_to_bool( self.searchAsYouType = QtCore.QSettings().value(
self.parent.config.get_config(u'search as type', u'False')) self.settingsSection + u'/search as type',
QtCore.QVariant(u'False')).toBool()
def retranslateUi(self): def retranslateUi(self):
self.SearchTextLabel.setText(self.trUtf8('Search:')) self.SearchTextLabel.setText(self.trUtf8('Search:'))
@ -350,7 +350,7 @@ class SongMediaItem(MediaManagerItem):
author_list = author_list + unicode(author.display_name) author_list = author_list + unicode(author.display_name)
author_audit.append(unicode(author.display_name)) author_audit.append(unicode(author.display_name))
if song.ccli_number is None or len(song.ccli_number) == 0: 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: else:
ccli = unicode(song.ccli_number) ccli = unicode(song.ccli_number)
raw_footer.append(song.title) raw_footer.append(song.title)

View File

@ -29,22 +29,19 @@
# http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://www.oooforum.org/forum/viewtopic.phtml?t=14409
# http://wiki.services.openoffice.org/wiki/Python # http://wiki.services.openoffice.org/wiki/Python
import re
import os import os
import time import re
from PyQt4 import QtCore
from songimport import SongImport from songimport import SongImport
from oooimport import OooImport from oooimport import OooImport
if os.name == u'nt': if os.name == u'nt':
from win32com.client import Dispatch
BOLD = 150.0 BOLD = 150.0
ITALIC = 2 ITALIC = 2
PAGE_BEFORE = 4 PAGE_BEFORE = 4
PAGE_AFTER = 5 PAGE_AFTER = 5
PAGE_BOTH = 6 PAGE_BOTH = 6
else: else:
import uno
from com.sun.star.awt.FontWeight import BOLD from com.sun.star.awt.FontWeight import BOLD
from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.awt.FontSlant import ITALIC
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH

View File

@ -24,7 +24,9 @@
############################################################################### ###############################################################################
import string import string
from PyQt4 import QtGui, QtCore
from PyQt4 import QtGui
from openlp.core.lib import SongXMLBuilder from openlp.core.lib import SongXMLBuilder
from openlp.plugins.songs.lib.models import Song, Author, Topic, Book from openlp.plugins.songs.lib.models import Song, Author, Topic, Book

View File

@ -25,14 +25,14 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool from openlp.core.lib import SettingsTab
class SongsTab(SettingsTab): class SongsTab(SettingsTab):
""" """
SongsTab is the Songs settings tab in the settings dialog. SongsTab is the Songs settings tab in the settings dialog.
""" """
def __init__(self, title, section=None): def __init__(self, title):
SettingsTab.__init__(self, title, section) SettingsTab.__init__(self, title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'SongsTab') self.setObjectName(u'SongsTab')
@ -63,9 +63,9 @@ class SongsTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.SongsModeGroupBox.setTitle(self.trUtf8('Songs Mode')) self.SongsModeGroupBox.setTitle(self.trUtf8('Songs Mode'))
self.SearchAsTypeCheckBox.setText( self.SearchAsTypeCheckBox.setText(
self.trUtf8('Enable search as you type:')) self.trUtf8('Enable search as you type'))
self.SongBarActiveCheckBox.setText( self.SongBarActiveCheckBox.setText(
self.trUtf8('Display Verses on Live Tool bar:')) self.trUtf8('Display Verses on Live Tool bar'))
def onSearchAsTypeCheckBoxChanged(self, check_state): def onSearchAsTypeCheckBoxChanged(self, check_state):
self.song_search = False self.song_search = False
@ -80,13 +80,19 @@ class SongsTab(SettingsTab):
self.song_bar = True self.song_bar = True
def load(self): def load(self):
self.song_search = str_to_bool( settings = QtCore.QSettings()
self.config.get_config(u'search as type', False)) settings.beginGroup(self.settingsSection)
self.song_bar = str_to_bool( self.song_search = settings.value(
self.config.get_config(u'display songbar', True)) 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.SearchAsTypeCheckBox.setChecked(self.song_search)
self.SongBarActiveCheckBox.setChecked(self.song_bar) self.SongBarActiveCheckBox.setChecked(self.song_bar)
settings.endGroup()
def save(self): def save(self):
self.config.set_config(u'search as type', unicode(self.song_search)) settings = QtCore.QSettings()
self.config.set_config(u'display songbar', unicode(self.song_bar)) 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()

View File

@ -137,7 +137,7 @@ class _OpenSong(XmlRootClass):
newtag = "Pre-chorus" newtag = "Pre-chorus"
else: else:
newtag = t newtag = t
s = (u'# %s %s'%(newtag, c)).rstrip() s = (u'# %s %s' % (newtag, c)).rstrip()
res.append(s) res.append(s)
res.append(l[1:]) res.append(l[1:])
if (len(l) == 0) and (not tagPending): if (len(l) == 0) and (not tagPending):

View File

@ -51,7 +51,7 @@ class SongsPlugin(Plugin):
""" """
Plugin.__init__(self, u'Songs', u'1.9.1', plugin_helpers) Plugin.__init__(self, u'Songs', u'1.9.1', plugin_helpers)
self.weight = -10 self.weight = -10
self.songmanager = SongManager(self.config) self.songmanager = SongManager()
self.openlp_import_form = OpenLPImportForm() self.openlp_import_form = OpenLPImportForm()
self.opensong_import_form = OpenSongImportForm() self.opensong_import_form = OpenSongImportForm()
self.openlp_export_form = OpenLPExportForm() self.openlp_export_form = OpenLPExportForm()
@ -65,7 +65,7 @@ class SongsPlugin(Plugin):
def initialise(self): def initialise(self):
log.info(u'Songs Initialising') log.info(u'Songs Initialising')
#if self.songmanager is None: #if self.songmanager is None:
# self.songmanager = SongManager(self.config) # self.songmanager = SongManager()
Plugin.initialise(self) Plugin.initialise(self)
self.insert_toolbox_item() self.insert_toolbox_item()
self.ImportSongMenu.menuAction().setVisible(True) self.ImportSongMenu.menuAction().setVisible(True)
@ -212,7 +212,7 @@ class SongsPlugin(Plugin):
+ ' included with the Songs of Fellowship Music Editions'), + ' included with the Songs of Fellowship Music Editions'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
Receiver.send_message(u'load_song_list') Receiver.send_message(u'songs_load_list')
def onImportOooItemClick(self): def onImportOooItemClick(self):
filenames = QtGui.QFileDialog.getOpenFileNames( filenames = QtGui.QFileDialog.getOpenFileNames(
@ -220,7 +220,7 @@ class SongsPlugin(Plugin):
u'', u'All Files(*.*)') u'', u'All Files(*.*)')
oooimport = OooImport(self.songmanager) oooimport = OooImport(self.songmanager)
oooimport.import_docs(filenames) oooimport.import_docs(filenames)
Receiver.send_message(u'load_song_list') Receiver.send_message(u'songs_load_list')
def onExportOpenlp1ItemClicked(self): def onExportOpenlp1ItemClicked(self):
self.openlp_export_form.show() self.openlp_export_form.show()

View File

@ -23,10 +23,12 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import logging
import os import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import logging
from openlp.core.lib import SettingsManager
from songusagedetaildialog import Ui_SongUsageDetailDialog from songusagedetaildialog import Ui_SongUsageDetailDialog
@ -53,15 +55,16 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
fromDate = QtCore.QDate(year - 1, 9, 1) fromDate = QtCore.QDate(year - 1, 9, 1)
self.FromDate.setSelectedDate(fromDate) self.FromDate.setSelectedDate(fromDate)
self.ToDate.setSelectedDate(toDate) 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): def defineOutputLocation(self):
path = QtGui.QFileDialog.getExistingDirectory(self, path = QtGui.QFileDialog.getExistingDirectory(self,
self.trUtf8('Output File Location'), self.trUtf8('Output File Location'),
self.parent.config.get_last_dir(1) ) SettingsManager.get_last_dir(self.parent.settingsSection, 1))
path = unicode(path) path = unicode(path)
if path != u'': if path != u'':
self.parent.config.set_last_dir(path, 1) SettingsManager.set_last_dir(self.parent.settingsSection, path, 1)
self.FileLineEdit.setText(path) self.FileLineEdit.setText(path)
def accept(self): def accept(self):
@ -86,4 +89,3 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
finally: finally:
if file: if file:
file.close() file.close()

View File

@ -25,7 +25,11 @@
import logging 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__) log = logging.getLogger(__name__)
@ -36,27 +40,33 @@ class SongUsageManager():
""" """
log.info(u'SongUsage manager loaded') 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 Creates the connection to the database, and creates the tables if they
don't exist. don't exist.
""" """
self.config = config
log.debug(u'SongUsage Initialising') log.debug(u'SongUsage Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'songusage')
self.db_url = u'' 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': if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/songusage.sqlite' % \ self.db_url = u'sqlite:///%s/songusage.sqlite' % \
self.config.get_data_path() AppLocation.get_section_data_path(u'songusage')
else: else:
self.db_url = u'%s://%s:%s@%s/%s' % \ self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
(db_type, self.config.get_config(u'db username'), unicode(settings.value(u'db username',
self.config.get_config(u'db password'), QtCore.QVariant(u'')).toString()),
self.config.get_config(u'db hostname'), unicode(settings.value(u'db password',
self.config.get_config(u'db database')) 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) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)
settings.endGroup()
log.debug(u'SongUsage Initialised') log.debug(u'SongUsage Initialised')
def get_all_songusage(self, start_date, end_date): def get_all_songusage(self, start_date, end_date):

View File

@ -28,9 +28,10 @@ import logging
from PyQt4 import QtCore, QtGui 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.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 from openlp.plugins.songusage.lib.models import SongUsageItem
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -107,12 +108,14 @@ class SongUsagePlugin(Plugin):
log.info(u'SongUsage Initialising') log.info(u'SongUsage Initialising')
Plugin.initialise(self) Plugin.initialise(self)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songusage_live'), self.onReceiveSongUsage) QtCore.SIGNAL(u'songs_live_started'),
self.SongUsageActive = str_to_bool( self.onReceiveSongUsage)
self.config.get_config(u'active', False)) self.SongUsageActive = QtCore.QSettings().value(
self.settingsSection + u'/active',
QtCore.QVariant(False)).toBool()
self.SongUsageStatus.setChecked(self.SongUsageActive) self.SongUsageStatus.setChecked(self.SongUsageActive)
if self.songusagemanager is None: if self.songusagemanager is None:
self.songusagemanager = SongUsageManager(self.config) self.songusagemanager = SongUsageManager()
self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager) self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager)
self.SongUsagedetailform = SongUsageDetailForm(self) self.SongUsagedetailform = SongUsageDetailForm(self)
self.SongUsageMenu.menuAction().setVisible(True) self.SongUsageMenu.menuAction().setVisible(True)
@ -125,23 +128,25 @@ class SongUsagePlugin(Plugin):
def toggleSongUsageState(self): def toggleSongUsageState(self):
self.SongUsageActive = not self.SongUsageActive 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 SongUsage a live song from SlideController
""" """
if self.SongUsageActive: audit = items[0].audit
SongUsageitem = SongUsageItem() if self.SongUsageActive and audit:
SongUsageitem.usagedate = datetime.today() song_usage_item = SongUsageItem()
SongUsageitem.usagetime = datetime.now().time() song_usage_item.usagedate = datetime.today()
SongUsageitem.title = SongUsageData[0] song_usage_item.usagetime = datetime.now().time()
SongUsageitem.copyright = SongUsageData[2] song_usage_item.title = audit[0]
SongUsageitem.ccl_number = SongUsageData[3] song_usage_item.copyright = audit[2]
SongUsageitem.authors = u'' song_usage_item.ccl_number = audit[3]
for author in SongUsageData[1]: song_usage_item.authors = u''
SongUsageitem.authors += author + u' ' for author in audit[1]:
self.songusagemanager.insert_songusage(SongUsageitem) song_usage_item.authors += author + u' '
self.songusagemanager.insert_songusage(song_usage_item)
def onSongUsageDelete(self): def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_() self.SongUsagedeleteform.exec_()

View File

@ -35,6 +35,7 @@ if os.name == u'nt':
import win32con import win32con
from win32com.client import Dispatch from win32com.client import Dispatch
from openlp.core.utils import AppLocation
from openlp.migration.display import * from openlp.migration.display import *
from openlp.migration.migratefiles import * from openlp.migration.migratefiles import *
from openlp.migration.migratebibles import * from openlp.migration.migratebibles import *
@ -103,8 +104,10 @@ class Migration(object):
def convert_sqlite2_to_3(self, olddb, newdb): def convert_sqlite2_to_3(self, olddb, newdb):
print u'Converting sqlite2 ' + olddb + ' to sqlite3 ' + newdb print u'Converting sqlite2 ' + olddb + ' to sqlite3 ' + newdb
if os.name == u'nt': if os.name == u'nt':
# we can't make this a raw unicode string as the \U within it causes much confusion # we can't make this a raw unicode string as the \U within it
hKey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, u'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SQLite ODBC Driver') # 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') value, type = win32api.RegQueryValueEx (hKey, u'UninstallString')
sqlitepath, temp = os.path.split(value) sqlitepath, temp = os.path.split(value)
sqliteexe = os.path.join(sqlitepath, u'sqlite.exe') sqliteexe = os.path.join(sqlitepath, u'sqlite.exe')
@ -133,10 +136,8 @@ class Migration(object):
if __name__ == u'__main__': if __name__ == u'__main__':
mig = Migration() mig = Migration()
songconfig = PluginConfig(u'Songs') newsongpath = AppLocation.get_section_data_path(u'songs')
newsongpath = songconfig.get_data_path() newbiblepath = AppLocation.get_section_data_path(u'bibles')
bibleconfig = PluginConfig(u'Bibles')
newbiblepath = bibleconfig.get_data_path()
if os.name == u'nt': if os.name == u'nt':
if not os.path.isdir(newsongpath): if not os.path.isdir(newsongpath):
os.makedirs(newsongpath) os.makedirs(newsongpath)

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>AlertForm</class> <class>AlertDialog</class>
<widget class="QWidget" name="AlertForm"> <widget class="QDialog" name="AlertDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>430</width> <width>567</width>
<height>320</height> <height>440</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -25,85 +25,198 @@
<number>8</number> <number>8</number>
</property> </property>
<item> <item>
<widget class="QWidget" name="AlertEntryWidget" native="true"> <layout class="QFormLayout" name="AlertTextLayout">
<property name="sizePolicy"> <property name="horizontalSpacing">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <number>8</number>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <property name="verticalSpacing">
<item> <number>8</number>
<layout class="QVBoxLayout" name="verticalLayout"> </property>
<item> <property name="leftMargin">
<widget class="QLabel" name="AlertEntryLabel"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <property name="topMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <item row="0" column="0">
</property> <widget class="QLabel" name="AlertEntryLabel">
<property name="text"> <property name="sizePolicy">
<string>Alert Text:</string> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
</widget> <verstretch>0</verstretch>
</item> </sizepolicy>
<item> </property>
<widget class="QLineEdit" name="AlertEntryEditItem"/> <property name="text">
</item> <string>Alert &amp;text:</string>
<item> </property>
<widget class="QListWidget" name="AlertListWidget"> <property name="buddy">
<property name="alternatingRowColors"> <cstring>AlertTextEdit</cstring>
<bool>true</bool> </property>
</property> </widget>
</widget> </item>
</item> <item row="1" column="0">
</layout> <widget class="QLabel" name="AlertParameter">
</item> <property name="text">
<item> <string>&amp;Parameter(s):</string>
<layout class="QHBoxLayout" name="horizontalLayout"> </property>
<item> <property name="buddy">
<spacer name="ButtonBoxWidgetSpacer"> <cstring>ParameterEdit</cstring>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> </item>
<property name="sizeHint" stdset="0"> <item row="1" column="1">
<size> <widget class="QLineEdit" name="ParameterEdit"/>
<width>181</width> </item>
<height>38</height> <item row="0" column="1">
</size> <widget class="QLineEdit" name="AlertTextEdit"/>
</property> </item>
</spacer> </layout>
</item> </item>
<item> <item>
<widget class="QPushButton" name="DisplayButton"> <layout class="QHBoxLayout" name="ManagementLayout">
<property name="text"> <property name="spacing">
<string>Display</string> <number>8</number>
</property> </property>
</widget> <property name="bottomMargin">
</item> <number>0</number>
<item> </property>
<widget class="QPushButton" name="CancelButton"> <item>
<property name="text"> <widget class="QListWidget" name="AlertListWidget">
<string>Cancel</string> <property name="alternatingRowColors">
</property> <bool>true</bool>
</widget> </property>
</item> </widget>
</layout> </item>
</item> <item>
</layout> <layout class="QVBoxLayout" name="ManageButtonLayout">
</widget> <property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QPushButton" name="NewButton">
<property name="text">
<string>&amp;New</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/general/general_new.png</normaloff>:/general/general_new.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SaveButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Save</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/general/general_save.png</normaloff>:/general/general_save.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DeleteButton">
<property name="text">
<string>&amp;Delete</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/general/general_delete.png</normaloff>:/general/general_delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="ManagementSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="AlertButtonLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<spacer name="ButtonBoxWidgetSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>181</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="DisplayButton">
<property name="text">
<string>Displ&amp;ay</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/general/general_live.png</normaloff>:/general/general_live.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DisplayCloseButton">
<property name="text">
<string>Display &amp;&amp; Cl&amp;ose</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/general/general_live.png</normaloff>:/general/general_live.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="CloseButton">
<property name="text">
<string>&amp;Close</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/system/system_close.png</normaloff>:/system/system_close.png</iconset>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>
<resources> <tabstops>
<include location="../images/openlp-2.qrc"/> <tabstop>AlertTextEdit</tabstop>
</resources> <tabstop>ParameterEdit</tabstop>
<tabstop>AlertListWidget</tabstop>
<tabstop>NewButton</tabstop>
<tabstop>SaveButton</tabstop>
<tabstop>DeleteButton</tabstop>
<tabstop>DisplayButton</tabstop>
<tabstop>DisplayCloseButton</tabstop>
<tabstop>CloseButton</tabstop>
</tabstops>
<resources/>
<connections> <connections>
<connection> <connection>
<sender>CancelButton</sender> <sender>CloseButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>AlertForm</receiver> <receiver>AlertDialog</receiver>
<slot>close()</slot> <slot>close()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AlertEditDialog</class>
<widget class="QWidget" name="AlertEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Maintain Alerts</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>220</x>
<y>270</y>
<width>173</width>
<height>27</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>361</width>
<height>251</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="AlertLineEdit"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="AlertListWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="SaveButton">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ClearButton">
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AddButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="EdirButton">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DeleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,295 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DisplaysDialog</class>
<widget class="QWidget" name="DisplaysDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>620</width>
<height>716</height>
</rect>
</property>
<property name="windowTitle">
<string>Amend Display Settings</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>40</y>
<width>241</width>
<height>79</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="CurrentGroupBox">
<property name="title">
<string>Default Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="XLabel">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Xpos">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="YLabel">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Ypos">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="HeightLabel">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Height</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Height">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="WidthLabel">
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Width">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="CurrentGroupBox_2">
<property name="geometry">
<rect>
<x>0</x>
<y>130</y>
<width>248</width>
<height>87</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>500</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Amend Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="XAmendLabel">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="XposEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="YAmendLabel">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="YposEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="HeightAmendLabel">
<property name="text">
<string>Height</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="HeightEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLabel" name="WidthAmendLabel">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="WidthEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<zorder>layoutWidget</zorder>
<zorder>YAmendLabel</zorder>
<zorder>HeightAmendLabel</zorder>
<zorder>WidthAmendLabel</zorder>
<zorder>YAmendLabel</zorder>
</widget>
<widget class="QCheckBox" name="OverrideCheckBox">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>191</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Override Output Display</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -24,34 +24,33 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import socket import urllib
import sys import sys
from optparse import OptionParser from optparse import OptionParser
def sendData(options, message): def sendData(options):
addr = (options.address, options.port) addr = 'http://%s:%s/send/%s?q=%s' % (options.address, options.port,
options.event, options.message)
try: try:
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) urllib.urlopen(addr)
UDPSock.sendto(message, addr) print u'Message sent ', addr
print u'message sent ', message, addr
except: except:
print u'Errow thrown ', sys.exc_info()[1] print u'Error thrown ', sys.exc_info()[1]
def format_message(options):
return u'%s:%s' % (u'alert', options.message)
def main(): def main():
usage = "usage: %prog [options] arg1 arg2" usage = "usage: %prog [-a address] [-p port] [-e event] [-m message]"
parser = OptionParser(usage=usage) 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, parser.add_option("-p", "--port", default=4316,
help="IP Port number %default ") help="IP Port number %default ")
parser.add_option("-a", "--address", 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", 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() (options, args) = parser.parse_args()
if args: if args:
@ -60,12 +59,8 @@ def main():
elif options.address is None: elif options.address is None:
parser.print_help() parser.print_help()
parser.error("IP address missing") parser.error("IP address missing")
elif options.message is None:
parser.print_help()
parser.error("No message passed")
else: else:
text = format_message(options) sendData(options)
sendData(options, text)
if __name__ == u'__main__': if __name__ == u'__main__':
main() main()