HEAD+fixes

This commit is contained in:
Raoul Snyman 2010-05-17 22:48:16 +02:00
commit 09bcb066eb
203 changed files with 9449 additions and 9960 deletions

View File

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

View File

@ -1,58 +0,0 @@
This content can be found at this URL:
http://netsuperbrain.com/Postmodern%20PostgreSQL%20Application%20Development.pdf
Page 11-15: QtDesigner
Page 18-20: SQLAlchemy
Page 21-23: PyQt - widget
Page 24 : main
Page 28 : py2exe and release
==============================
This is the destilled content.
==============================
----------------
** sqlalchemy **
----------------
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker, mapper
engine = create_engine( 'postgres://postgres@localhost/customers' )
metadata = MetaData( bind=engine, reflect=True)
Session = sessionmaker(bind=engine, autoflush=True,
transactional=True)
class Customer(object): pass
mapper( Customer, Table('customers', metadata ) )
session = Session()
customer = Customer( businessName=“Jamb Safety”,
website=“www.jamb.com” )
session.save( customer )
for customer in Session.query(Customer).filter(
Customer.businessName.like(“Jamb%”)):
print customer.businessName
session.commit()
------------------------
** release and py2exe **
------------------------
from distutils.core import setup
import py2exe
import glob
setup(
name="Customers",
author="Sankel Software",
author_email="david@sankelsoftware.com",
url="http://sankelsoftware.com",
license=“GPL",
version=“1.0.0",
windows=[ { "script":"main.py“,}],
options={"py2exe":{"includes":["sip”]}},
data_files=[
("forms",glob.glob("forms/*.ui")),
] )
release:
python setup.py py2exe --quiet --dist-dir=dist

View File

@ -18,12 +18,6 @@
.. autoclass:: openlp.core.lib.eventreceiver.EventReceiver
:members:
:mod:`ListWithPreviews`
-----------------------
.. autoclass:: openlp.core.lib.listwithpreviews.ListWithPreviews
:members:
:mod:`MediaManagerItem`
-----------------------
@ -36,12 +30,6 @@
.. autoclass:: openlp.core.lib.plugin.Plugin
:members:
:mod:`PluginConfig`
-------------------
.. autoclass:: openlp.core.lib.pluginconfig.PluginConfig
:members:
: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
songs
:mod:`bibles` Plugin
--------------------
.. automodule:: openlp.plugins.bibles
:members:
bibles
:mod:`presentations` Plugin
---------------------------
@ -41,3 +36,8 @@
.. automodule:: openlp.plugins.custom
:members:
:mod:`songusage` Plugin
-----------------------
.. automodule:: openlp.plugins.songusage
:members:

View File

@ -34,10 +34,10 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger()
from openlp.core.lib import Receiver, str_to_bool
from openlp.core.lib import Receiver
from openlp.core.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen, ScreenList
from openlp.core.utils import AppLocation, ConfigHelper
from openlp.core.utils import AppLocation, LanguageManager
application_stylesheet = u"""
QMainWindow::separator
@ -78,9 +78,7 @@ class OpenLP(QtGui.QApplication):
Run the OpenLP application.
"""
#Load and store current Application Version
filepath = AppLocation.get_directory(AppLocation.AppDir)
if not hasattr(sys, u'frozen'):
filepath = os.path.join(filepath, u'openlp')
filepath = AppLocation.get_directory(AppLocation.VersionDir)
filepath = os.path.join(filepath, u'.version')
fversion = None
try:
@ -112,20 +110,17 @@ class OpenLP(QtGui.QApplication):
finally:
if fversion:
fversion.close()
#set the default string encoding
try:
sys.setappdefaultencoding(u'utf-8')
except:
pass
#provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'process_events'), self.processEvents)
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
self.setOrganizationName(u'OpenLP')
self.setOrganizationDomain(u'openlp.org')
self.setApplicationName(u'OpenLP')
self.setApplicationVersion(app_version[u'version'])
if os.name == u'nt':
self.setStyleSheet(application_stylesheet)
show_splash = str_to_bool(ConfigHelper.get_registry().get_value(
u'general', u'show splash', True))
show_splash = QtCore.QSettings().value(
u'general/show splash', QtCore.QVariant(True)).toBool()
if show_splash:
self.splash = SplashScreen(self.applicationVersion())
self.splash.show()
@ -135,8 +130,8 @@ class OpenLP(QtGui.QApplication):
# Decide how many screens we have and their size
for screen in xrange(0, self.desktop().numScreens()):
screens.add_screen({u'number': screen,
u'size': self.desktop().availableGeometry(screen),
u'primary': (self.desktop().primaryScreen() == screen)})
u'size': self.desktop().availableGeometry(screen),
u'primary': (self.desktop().primaryScreen() == screen)})
log.info(u'Screen %d found with resolution %s',
screen, self.desktop().availableGeometry(screen))
# start the main app window
@ -174,7 +169,7 @@ def main():
filename = os.path.join(log_path, u'openlp.log')
logfile = FileHandler(filename, u'w')
logfile.setFormatter(logging.Formatter(
u'%(asctime)s %(name)-20s %(levelname)-8s %(message)s'))
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
log.addHandler(logfile)
logging.addLevelName(15, u'Timer')
# Parse command line options and deal with them.
@ -195,6 +190,11 @@ def main():
qInitResources()
# Now create and actually run the application.
app = OpenLP(qt_args)
#i18n Set Language
language = LanguageManager.get_language()
appTranslator = LanguageManager.get_translator(language)
app.installTranslator(appTranslator)
sys.exit(app.run())
if __name__ == u'__main__':

View File

@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger(__name__)
def translate(context, text):
def translate(context, text, comment=None):
"""
A special shortcut method to wrap around the Qt4 translation functions.
This abstracts the translation procedure so that we can change it if at a
@ -48,8 +48,8 @@ def translate(context, text):
``text``
The text to put into the translation tables for translation.
"""
return QtGui.QApplication.translate(
context, text, None, QtGui.QApplication.UnicodeUTF8)
return QtCore.QCoreApplication.translate(context, text,
comment)
def get_text_file_string(text_file):
"""
@ -164,7 +164,6 @@ class ThemeLevel(object):
from eventreceiver import Receiver
from settingsmanager import SettingsManager
from pluginconfig import PluginConfig
from plugin import PluginStatus, Plugin
from pluginmanager import PluginManager
from settingstab import SettingsTab
@ -172,7 +171,7 @@ from mediamanageritem import MediaManagerItem
from xmlrootclass import XmlRootClass
from serviceitem import ServiceItem
from serviceitem import ServiceItemType
from serviceitem import ServiceItem
from serviceitem import ItemCapabilities
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
from songxmlhandler import SongXMLBuilder, SongXMLParser

View File

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

View File

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

View File

@ -35,36 +35,118 @@ class EventReceiver(QtCore.QObject):
system. This is a private class and should not be used directly
but rather via the Receiver class.
``stop_import``
Stops the Bible Import
``pre_load_bibles``
Triggers the plugin to relaod the bible lists
``process_events``
``openlp_process_events``
Requests the Application to flush the events queue
``{plugin}_add_service_item``
ask the plugin to push the selected items to the service item
``openlp_version_check``
Version has changed so pop up window.
``update_themes``
``config_updated``
Informs components the config has changed
``config_screen_changed``
The display monitor has been changed
``slidecontroller_{live|preview}_first``
Moves to the first slide
``slidecontroller_{live|preview}_next``
Moves to the next slide
``slidecontroller_{live|preview}_next_noloop``
Moves to the next slide without auto advance
``slidecontroller_{live|preview}_previous``
Moves to the previous slide
``slidecontroller_{live|preview}_previous_noloop``
Moves to the previous slide, without auto advance
``slidecontroller_{live|preview}_last``
Moves to the last slide
``slidecontroller_{live|preview}_set``
Moves to a specific slide, by index
``slidecontroller_{live|preview}_started``
Broadcasts that an item has been made live/previewed
``slidecontroller_{live|preview}_change``
Informs the slidecontroller that a slide change has occurred and to
update itself
``slidecontroller_{live|preview}_changed``
Broadcasts that the slidecontroller has changed the current slide
``slidecontroller_{live|preview}_text_request``
Request the text for the current item in the controller
Returns a slidecontroller_{live|preview}_text_response with an
array of dictionaries with the tag and verse text
``slidecontroller_{live|preview}_blank``
Request that the output screen is blanked
``slidecontroller_{live|preview}_unblank``
Request that the output screen is unblanked
``slidecontroller_live_spin_delay``
Pushes out the loop delay
``slidecontroller_live_stop_loop``
Stop the loop on the main display
``servicemanager_previous_item``
Display the previous item in the service
``servicemanager_next_item``
Display the next item in the service
``servicemanager_set_item``
Go live on a specific item, by index
``servicemanager_list_request``
Request the service list. Responds with servicemanager_list_response
containing a array of dictionaries
``maindisplay_blank``
Blank the maindisplay window
``maindisplay_hide``
Hide the maindisplay window
``maindisplay_show``
Return the maindisplay window
``maindisplay_active``
The maindisplay has been made active
``maindisplay_status_text``
Changes the bottom status bar text on the maindisplay window
``maindisplay_blank_check``
Check to see if the blank display message is required
``videodisplay_start``
Open a media item and prepare for playing
``videodisplay_play``
Start playing a media item
``videodisplay_pause``
Pause a media item
``videodisplay_stop``
Stop playing a media item
``videodisplay_background``
Replace the background video
``theme_update_list``
send out message with new themes
``update_global_theme``
``theme_update_global``
Tell the components we have a new global theme
``load_song_list``
Tells the the song plugin to reload the song list
``load_custom_list``
Tells the the custom plugin to reload the custom list
``update_spin_delay``
Pushes out the Image loop delay
``request_spin_delay``
Requests a spin delay
``{plugin}_start``
Requests a plugin to start a external program
Path and file provided in message
@ -81,33 +163,51 @@ class EventReceiver(QtCore.QObject):
``{plugin}_last``
Requests a plugin to handle a last event
``{plugin}_slide``
Requests a plugin to handle a go to specific slide event
``{plugin}_stop``
Requests a plugin to handle a stop event
``{plugin}_blank``
Requests a plugin to handle a blank screen event
``{plugin}_unblank``
Requests a plugin to handle an unblank screen event
``{plugin}_edit``
Requests a plugin edit a database item with the key as the payload
``songusage_live``
Sends live song audit requests to the audit component
``{plugin}_edit_clear``
Editing has been completed
``audit_changed``
Audit information may have changed
``{plugin}_load_list``
Tells the the plugin to reload the media manager list
``config_updated``
Informs components the config has changed
``{plugin}_preview``
Tells the plugin it's item can be previewed
``preview_song``
Tells the song plugin the edit has finished and the song can be previewed
Only available if the edit was triggered by the Preview button.
``{plugin}_add_service_item``
Ask the plugin to push the selected items to the service item
``slidecontroller_change``
Informs the slidecontroller that a slide change has occurred
``alerts_text``
Displays an alert message
``bibles_nobook``
Attempt to find book resulted in no match
``remote_edit_clear``
Informs all components that remote edit has been aborted.
``bibles_showprogress``
Show progress of bible verse import
``presentation types``
Informs all components of the presentation types supported.
``bibles_hideprogress``
Hide progress of bible verse import
``bibles_stop_import``
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):
@ -164,4 +264,3 @@ class Receiver():
Get the global ``eventreceiver`` instance.
"""
return Receiver.eventreceiver

View File

@ -29,7 +29,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib.toolbar import *
from openlp.core.lib import contextMenuAction, contextMenuSeparator
from openlp.core.lib import contextMenuAction, contextMenuSeparator, \
SettingsManager
from serviceitem import ServiceItem
log = logging.getLogger(__name__)
@ -69,11 +70,6 @@ class MediaManagerItem(QtGui.QWidget):
The user visible name for a plugin which should use a suitable
translation function.
``self.ConfigSection``
The section in the configuration where the items in the media
manager are stored. This could potentially be
``self.PluginNameShort.lower()``.
``self.OnNewPrompt``
Defaults to *'Select Image(s)'*.
@ -102,6 +98,7 @@ class MediaManagerItem(QtGui.QWidget):
"""
QtGui.QWidget.__init__(self)
self.parent = parent
self.settingsSection = title.lower()
if type(icon) is QtGui.QIcon:
self.icon = icon
elif type(icon) is types.StringType:
@ -114,6 +111,7 @@ class MediaManagerItem(QtGui.QWidget):
self.Toolbar = None
self.remoteTriggered = None
self.ServiceItemIconName = None
self.singleServiceItem = True
self.addToServiceItem = False
self.PageLayout = QtGui.QVBoxLayout(self)
self.PageLayout.setSpacing(0)
@ -333,24 +331,47 @@ class MediaManagerItem(QtGui.QWidget):
def onFileClick(self):
files = QtGui.QFileDialog.getOpenFileNames(
self, self.OnNewPrompt,
self.parent.config.get_last_dir(), self.OnNewFileMasks)
SettingsManager.get_last_dir(self.settingsSection),
self.OnNewFileMasks)
log.info(u'New files(s) %s', unicode(files))
if files:
self.loadList(files)
dir, filename = os.path.split(unicode(files[0]))
self.parent.config.set_last_dir(dir)
self.parent.config.set_list(self.ConfigSection, self.getFileList())
dir = os.path.split(unicode(files[0]))[0]
SettingsManager.set_last_dir(self.settingsSection, dir)
SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList())
def getFileList(self):
count = 0
filelist = []
while count < self.ListView.count():
while count < self.ListView.count():
bitem = self.ListView.item(count)
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
filelist.append(filename)
count += 1
return filelist
def validate(self, file, thumb):
"""
Validates to see if the file still exists or
thumbnail is up to date
"""
if os.path.exists(file):
filedate = os.stat(file).st_mtime
thumbdate = os.stat(thumb).st_mtime
#if file updated rebuild icon
if filedate > thumbdate:
self.IconFromFile(file, thumb)
return True
return False
def IconFromFile(self, file, thumb):
icon = build_icon(unicode(file))
pixmap = icon.pixmap(QtCore.QSize(88,50))
ext = os.path.splitext(thumb)[1].lower()
pixmap.save(thumb, ext[1:])
return icon
def loadList(self, list):
raise NotImplementedError(u'MediaManagerItem.loadList needs to be '
u'defined by the plugin')
@ -367,7 +388,7 @@ class MediaManagerItem(QtGui.QWidget):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
u'be defined by the plugin')
def generateSlideData(self, item):
def generateSlideData(self, service_item, item):
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
u'to be defined by the plugin')
@ -401,11 +422,22 @@ class MediaManagerItem(QtGui.QWidget):
self.trUtf8('No Items Selected'),
self.trUtf8('You must select one or more items.'))
else:
log.debug(self.PluginNameShort + u' Add requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item)
#Is it posssible to process multiple list items to generate multiple
#service items?
if self.singleServiceItem or self.remoteTriggered:
log.debug(self.PluginNameShort + u' Add requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item,
replace=self.remoteTriggered)
else:
items = self.ListView.selectedIndexes()
for item in items:
service_item = self.buildServiceItem(item)
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item)
def onAddEditClick(self):
if not self.ListView.selectedIndexes() and not self.remoteTriggered:
@ -418,18 +450,20 @@ class MediaManagerItem(QtGui.QWidget):
if not service_item:
QtGui.QMessageBox.information(self,
self.trUtf8('No Service Item Selected'),
self.trUtf8('You must select a existing service item to add to.'))
elif self.title == service_item.name:
self.trUtf8(
'You must select an existing service item to add to.'))
elif self.title.lower() == service_item.name.lower():
self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item)
self.parent.service_manager.addServiceItem(service_item,
replace=True)
else:
#Turn off the remote edit update message indicator
self.parent.service_manager.remoteEditTriggered = False
QtGui.QMessageBox.information(self,
self.trUtf8('Invalid Service Item'),
self.trUtf8(unicode('You must select a %s service item.' % self.title)))
self.trUtf8(unicode(
'You must select a %s service item.' % self.title)))
def buildServiceItem(self):
def buildServiceItem(self, item=None):
"""
Common method for generating a service item
"""
@ -439,7 +473,7 @@ class MediaManagerItem(QtGui.QWidget):
else:
service_item.addIcon(
u':/media/media_' + self.PluginNameShort.lower() + u'.png')
if self.generateSlideData(service_item):
if self.generateSlideData(service_item, item):
return service_item
else:
return None

View File

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

View File

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

View File

@ -49,7 +49,7 @@ class RenderManager(object):
"""
log.info(u'RenderManager Loaded')
def __init__(self, theme_manager, screens, screen_number=0):
def __init__(self, theme_manager, screens):
"""
Initialise the render manager.
"""
@ -57,7 +57,6 @@ class RenderManager(object):
self.screens = screens
self.theme_manager = theme_manager
self.renderer = Renderer()
self.screens.set_current_display(screen_number)
self.calculate_default(self.screens.current[u'size'])
self.theme = u''
self.service_theme = u''
@ -65,12 +64,9 @@ class RenderManager(object):
self.override_background = None
self.themedata = None
def update_display(self, screen_number):
def update_display(self):
"""
Updates the render manager's information about the current screen.
``screen_number``
The updated index of the output/display screen.
"""
log.debug(u'Update Display')
self.calculate_default(self.screens.current[u'size'])

View File

@ -30,7 +30,7 @@ import uuid
from PyQt4 import QtGui
from openlp.core.lib import build_icon, Receiver, resize_image
from openlp.core.lib import build_icon, resize_image
log = logging.getLogger(__name__)
@ -42,6 +42,14 @@ class ServiceItemType(object):
Image = 2
Command = 3
class ItemCapabilities(object):
AllowsPreview = 1
AllowsEdit = 2
AllowsMaintain = 3
RequiresMedia = 4
AllowsLoop = 5
AllowsAdditions = 6
class ServiceItem(object):
"""
The service item is a base class for the plugins to use to interact with
@ -67,14 +75,20 @@ class ServiceItem(object):
self.raw_footer = None
self.theme = None
self.service_item_type = None
self.edit_enabled = False
self.maintain_allowed = False
self._raw_frames = []
self._display_frames = []
self._uuid = unicode(uuid.uuid1())
self.auto_preview_allowed = False
self.notes = u''
self.from_plugin = False
self.capabilities = []
self.is_valid = True
self.cache = []
def add_capability(self, capability):
self.capabilities.append(capability)
def is_capable(self, capability):
return capability in self.capabilities
def addIcon(self, icon):
"""
@ -94,6 +108,7 @@ class ServiceItem(object):
"""
log.debug(u'Render called')
self._display_frames = []
self.cache = []
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
if self.theme is None:
@ -112,6 +127,7 @@ class ServiceItem(object):
lines += line + u'\n'
self._display_frames.append({u'title': title, \
u'text': lines.rstrip(), u'verseTag': slide[u'verseTag'] })
self.cache.insert(len(self._display_frames), None)
log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames:
@ -136,11 +152,15 @@ class ServiceItem(object):
self.RenderManager.set_override_theme(self.theme)
format = self._display_frames[row][u'text'].split(u'\n')
#if screen blank then do not display footer
if format[0]:
frame = self.RenderManager.generate_slide(format,
self.raw_footer)
if self.cache[row] is not None:
frame = self.cache[row]
else:
frame = self.RenderManager.generate_slide(format,u'')
if format[0]:
frame = self.RenderManager.generate_slide(format,
self.raw_footer)
else:
frame = self.RenderManager.generate_slide(format,u'')
self.cache[row] = frame
return frame
def add_from_image(self, path, title, image):
@ -207,10 +227,8 @@ class ServiceItem(object):
u'type':self.service_item_type,
u'audit':self.audit,
u'notes':self.notes,
u'preview':self.auto_preview_allowed,
u'edit':self.edit_enabled,
u'maintain':self.maintain_allowed,
u'from_plugin':self.from_plugin
u'from_plugin':self.from_plugin,
u'capabilities':self.capabilities
}
service_data = []
if self.service_item_type == ServiceItemType.Text:
@ -244,11 +262,9 @@ class ServiceItem(object):
self.addIcon(header[u'icon'])
self.raw_footer = header[u'footer']
self.audit = header[u'audit']
self.auto_preview_allowed = header[u'preview']
self.notes = header[u'notes']
self.edit_enabled = header[u'edit']
self.maintain_allowed = header[u'maintain']
self.from_plugin = header[u'from_plugin']
self.capabilities = header[u'capabilities']
if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
self._raw_frames.append(slide)
@ -284,11 +300,8 @@ class ServiceItem(object):
"""
return self._uuid != other._uuid
def is_song(self):
return self.name.lower() == u'songs'
def is_media(self):
return self.name.lower() == u'media'
return ItemCapabilities.RequiresMedia in self.capabilities
def is_command(self):
return self.service_item_type == ServiceItemType.Command
@ -330,7 +343,3 @@ class ServiceItem(object):
Returns the title of the raw frame
"""
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 #
###############################################################################
from openlp.core.lib import str_to_bool
from openlp.core.utils import ConfigHelper
import os
from PyQt4 import QtCore
from openlp.core.utils import AppLocation
class SettingsManager(object):
"""
Class to control the size of the UI components so they size correctly.
This class is created by the main window and then calculates the size of
individual components.
Class to control the initial settings for the UI and provide helper
functions for the loading and saving of application settings.
"""
def __init__(self, screen):
self.screen = screen.current
@ -50,26 +52,131 @@ class SettingsManager(object):
self.mainwindow_left + self.mainwindow_right) - 100 ) / 2
self.slidecontroller_image = self.slidecontroller - 50
self.showMediaManager = str_to_bool(ConfigHelper.get_config(
u'user interface', u'media manager', True))
self.showServiceManager = str_to_bool(ConfigHelper.get_config(
u'user interface', u'service manager', True))
self.showThemeManager = str_to_bool(ConfigHelper.get_config(
u'user interface', u'theme manager', True))
self.showPreviewPanel = str_to_bool(ConfigHelper.get_config(
u'user interface', u'preview panel', True))
def setUIItemVisibility(self, item=u'', isVisible=True):
if item:
if item == u'ThemeManagerDock':
ConfigHelper.set_config(u'user interface',
u'theme manager', isVisible)
elif item == u'ServiceManagerDock':
ConfigHelper.set_config(u'user interface',
u'service manager', isVisible)
elif item == u'MediaManagerDock':
ConfigHelper.set_config(u'user interface',
u'media manager', isVisible)
self.showPreviewPanel = QtCore.QSettings().value(
u'user interface/preview panel', QtCore.QVariant(True)).toBool()
def togglePreviewPanel(self, isVisible):
ConfigHelper.set_config(u'user interface', u'preview panel', isVisible)
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(isVisible))
@staticmethod
def get_last_dir(section, num=None):
"""
Read the last directory used for plugin.
``section``
The section of code calling the method. This is used in the
settings key.
``num``
Defaults to *None*. A further qualifier.
"""
if num:
name = u'last directory %d' % num
else:
name = u'last directory'
last_dir = unicode(QtCore.QSettings().value(
section + u'/' + name, QtCore.QVariant(u'')).toString())
return last_dir
@staticmethod
def set_last_dir(section, directory, num=None):
"""
Save the last directory used for plugin.
``section``
The section of code calling the method. This is used in the
settings key.
``directory``
The directory being stored in the settings.
``num``
Defaults to *None*. A further qualifier.
"""
if num:
name = u'last directory %d' % num
else:
name = u'last directory'
QtCore.QSettings().setValue(
section + u'/' + name, QtCore.QVariant(directory))
@staticmethod
def set_list(section, name, list):
"""
Save a list to application settings.
``section``
The section of the settings to store this list.
``name``
The name of the list to save.
``list``
The list of values to save.
"""
settings = QtCore.QSettings()
settings.beginGroup(section)
old_count = settings.value(
u'%s count' % name, QtCore.QVariant(0)).toInt()[0]
new_count = len(list)
settings.setValue(u'%s count' % name, QtCore.QVariant(new_count))
for counter in range (0, new_count):
settings.setValue(
u'%s %d' % (name, counter), QtCore.QVariant(list[counter-1]))
if old_count > new_count:
# Tidy up any old list items
for counter in range(new_count, old_count):
settings.remove(u'%s %d' % (name, counter))
settings.endGroup()
@staticmethod
def load_list(section, name):
"""
Load a list from the config file.
``section``
The section of the settings to load the list from.
``name``
The name of the list.
"""
settings = QtCore.QSettings()
settings.beginGroup(section)
list_count = settings.value(
u'%s count' % name, QtCore.QVariant(0)).toInt()[0]
list = []
if list_count:
for counter in range(0, list_count):
item = unicode(
settings.value(u'%s %d' % (name, counter)).toString())
if item:
list.append(item)
settings.endGroup()
return list
@staticmethod
def get_files(section=None, extension=None):
"""
Get a list of files from the data files path.
``section``
Defaults to *None*. The section of code getting the files - used
to load from a section's data subdirectory.
``extension``
Defaults to *None*. The extension to search for.
"""
path = AppLocation.get_data_path()
if section:
path = os.path.join(path, section)
try:
files = os.listdir(path)
except:
return []
if extension:
return [file for file in files
if extension == os.path.splitext(file)[1]]
else:
# no filtering required
return files

View File

@ -25,35 +25,26 @@
from PyQt4 import QtGui
from openlp.core.lib import PluginConfig
class SettingsTab(QtGui.QWidget):
"""
SettingsTab is a helper widget for plugins to define Tabs for the settings
dialog.
"""
def __init__(self, title, section=None):
def __init__(self, title):
"""
Constructor to create the Settings tab item.
``title``
Defaults to *None*. The title of the tab, which is usually
displayed on the tab.
``section``
Defaults to *None*. This is the section in the configuration file
to write to when the ``save`` method is called.
The title of the tab, which is usually displayed on the tab.
"""
QtGui.QWidget.__init__(self)
self.tabTitle = title
self.tabTitleVisible = None
self.settingsSection = self.tabTitle.lower()
self.setupUi()
self.retranslateUi()
self.initialise()
if section is None:
self.config = PluginConfig(title)
else:
self.config = PluginConfig(section)
self.preLoad()
self.load()
def setupUi(self):
@ -62,6 +53,12 @@ class SettingsTab(QtGui.QWidget):
"""
pass
def preLoad(self):
"""
Setup the tab's interface.
"""
pass
def retranslateUi(self):
"""
Setup the interface translation strings.

View File

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

View File

@ -117,10 +117,11 @@ class OpenLPToolbar(QtGui.QToolBar):
The title of the icon to search for.
"""
title = QtCore.QString(title)
if self.icons[title]:
return self.icons[title]
else:
log.error(u'getIconFromTitle - no icon for %s' % title)
try:
if self.icons[title]:
return self.icons[title]
except:
log.exception(u'getIconFromTitle - no icon for %s' % title)
return QtGui.QIcon()
def makeWidgetsInvisible(self, widgets):

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Theme>
<Name>openlp.org Packaged Theme</Name>
<BackgroundType>0</BackgroundType>
<BackgroundParameter1>clWhite</BackgroundParameter1>
<BackgroundParameter2/>
<BackgroundParameter3/>
<FontName>Tahoma</FontName>
<FontColor>$00007F</FontColor>
<FontProportion>53</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>0</Shadow>
<ShadowColor>$000000</ShadowColor>
<Outline>0</Outline>
<OutlineColor>$000000</OutlineColor>
<HorizontalAlign>0</HorizontalAlign>
<VerticalAlign>0</VerticalAlign>
<WrapStyle>1</WrapStyle>
</Theme>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,110 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
import os
import sys
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-30s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='plugins.log',
filemode='w')
console=logging.StreamHandler()
# set a format which is simpler for console use
formatter = logging.Formatter(u'%(name)24s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
logging.getLogger(u'').addHandler(console)
log = logging.getLogger(u'')
logging.info(u'Logging started')
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..')))
class TestMediaManager:
def setup_class(self):
self.app = QtGui.QApplication([])
logging.info (u'App is ' + unicode(self.app))
self.main_window = QtGui.QMainWindow()
self.main_window.resize(200, 600)
self.MediaManagerDock = QtGui.QDockWidget(self.main_window)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.MediaManagerDock.sizePolicy().hasHeightForWidth())
self.MediaManagerDock.setSizePolicy(sizePolicy)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/system/system_mediamanager.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.MediaManagerDock.setWindowIcon(icon)
self.MediaManagerDock.setFloating(False)
self.MediaManagerContents = QtGui.QWidget()
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.MediaManagerContents.sizePolicy().hasHeightForWidth())
self.MediaManagerContents.setSizePolicy(sizePolicy)
self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents)
self.MediaManagerLayout.setContentsMargins(0, 2, 0, 0)
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerContents)
self.MediaManagerDock.setWidget(self.MediaManagerContents)
self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1),
self.MediaManagerDock)
self.MediaManagerLayout.addWidget(self.MediaToolBox)
def test1(self):
log=logging.getLogger(u'test1')
log.info(u'Start')
i1=MediaManagerItem(self.MediaToolBox)
i2=MediaManagerItem(self.MediaToolBox)
log.info(u'i1'+unicode(i1))
log.info(u'i2'+unicode(i2))
i1.addToolbar()
i1.addToolbarButton(u'Test1', u'Test1', None)
i2.addToolbar()
i2.addToolbarButton(u'Test2', u'Test2', None)
self.MediaToolBox.setItemText(
self.MediaToolBox.indexOf(i1), self.trUtf8('Item1'))
self.MediaToolBox.setItemText(
self.MediaToolBox.indexOf(i2), self.trUtf8('Item2'))
log.info(u'Show window')
self.main_window.show()
log.info(u'End')
return 1
if __name__ == "__main__":
t=TestMediaManager()
t.setup_class()
t.test1()
log.info(u'exec')
sys.exit(t.app.exec_())

View File

@ -1,74 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
import os
import sys
from openlp.core.lib.pluginmanager import PluginManager
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='plugins.log',
filemode='w')
console=logging.StreamHandler()
# set a format which is simpler for console use
formatter = logging.Formatter(u'%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
logging.getLogger(u'').addHandler(console)
log = logging.getLogger(u'')
logging.info(u'Logging started')
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..')))
# test the plugin manager with some plugins in the test_plugins directory
class TestPluginManager:
def test_init(self):
self.p = PluginManager(u'./testplugins')
p = self.p
p.find_plugins(u'./testplugins', None, None)
assert(len(p.plugins) == 2)
# get list of the names of the plugins
names = [plugin.name for plugin in p.plugins]
# see which ones we've got
assert(u'testplugin1' in names)
assert(u'testplugin2' in names)
# and not got - it's too deep in the hierarchy!
assert(u'testplugin3' not in names)
# test that the weighting is done right
assert(p.plugins[0].name == "testplugin2")
assert(p.plugins[1].name == "testplugin1")
if __name__ == "__main__":
log.debug(u'Starting')
t = TestPluginManager()
t.test_init()
log.debug(u'List of plugins found:')
for plugin in t.p.plugins:
log.debug(u'Plugin %s, name=%s (version=%d)' %(unicode(plugin),
plugin.name, plugin.version))

View File

@ -1,241 +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 sys
import os
import os.path
from PyQt4 import QtGui, QtCore
from openlp.core.theme import Theme
from openlp.core.lib import Renderer
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
def whoami(depth=1):
return sys._getframe(depth).f_code.co_name
class TstFrame:
# {{{ init
def __init__(self, size):
"""Create the DemoPanel."""
self.width = size.width();
self.height = size.height();
# create something to be painted into
self._Buffer = QtGui.QPixmap(self.width, self.height)
def GetPixmap(self):
return self._Buffer
# }}}
class TestRender_base:
def __init__(self):
if not os.path.exists(u'test_results'):
os.mkdir(u'test_results')
self.app = None
def write_to_file(self, pixmap, name):
im=pixmap.toImage()
testpathname = os.path.join(u'test_results', name+'.bmp')
if os.path.exists(testpathname):
os.unlink(testpathname)
im.save(testpathname, 'bmp')
return im
# xxx quitting the app still leaves it hanging aroudn so we die
# when trying to start another one. Not quitting doesn't help
# though This means that the py.test runs both test modules in
# sequence and the second one tries to create another application
# which gives us errors :(
def setup_class(self):
print "class setup", self
try:
if self.app is None:
pass
except AttributeError: # didn't have one
print "No app"
self.app = None
print "Test app (should be None)"
if self.app is None:
print "App is None"
self.app = QtGui.QApplication([])
else:
print "class setup, app is", app
# self.app = QtGui.QApplication([])
def teardown_class(self):
print "class quit", self, self.app
self.app.quit()
def setup_method(self, method):
print "SSsetup", method
if not hasattr(self, 'app'):
self.app = None
try: # see if we already have an app for some reason.
# have to try and so something, cant just test against None
print "app", self.app, ";;;"
print self.app.quit()
print "quitted"
except RuntimeError: # not valid app, create one
print "Runtime error"
except AttributeError: # didn't have one
print "Attribute error"
# print "App", self.app
# self.app = QtGui.QApplication([])
print "Application created and sorted"
self.size = QtCore.QSize(800,600)
frame = TstFrame(size = self.size)
self.frame = frame
self.paintdest = frame.GetPixmap()
self.renderer = Renderer()
self.renderer.set_paint_dest(self.paintdest)
self.expected_answer = "Don't know yet"
self.answer = None
print "--------------- Setup Done -------------"
def teardown_method(self, method):
self.write_to_file(self.frame.GetPixmap(), 'test_render')
class TestRender(TestRender_base):
def __init__(self):
TestRender_base.__init__(self)
def setup_method(self, method):
TestRender_base.setup_method(self, method)
self.renderer.set_debug(1)
themefile = os.path.abspath(u'data_for_tests/render_theme.xml')
self.renderer.set_theme(Theme(themefile)) # set default theme
self.renderer._render_background()
self.renderer.set_text_rectangle(QtCore.QRect(
0,0, self.size.width()-1, self.size.height()-1))
self.msg = None
def test_easy(self):
answer = self.renderer._render_single_line(
u'Test line', tlcorner = (0,100))
assert(answer == (219,163))
def test_longer(self):
answer = self.renderer._render_single_line(
u'Test line with more words than fit on one line',
tlcorner = (10,10))
assert(answer == (753,136))
def test_even_longer(self):
answer = self.renderer._render_single_line(
u'Test line with more words than fit on either one or two lines',
tlcorner = (10,10))
assert(answer == (753,199))
def test_lines(self):
lines = []
lines.append(u'Line One')
lines.append(u'Line Two')
lines.append(u'Line Three and should be long enough to wrap')
lines.append(u'Line Four and should be long enough to wrap also')
answer = self.renderer._render_lines(lines)
assert(answer == QtCore.QRect(0,0,741,378))
def test_set_words_openlp(self):
words="""
Verse 1: Line 1
Line 2
Verse 2: Line 1
Line 2
Verse 3: Line 1
Line 2
Line 3"""
expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
answer = self.renderer.set_words_openlp(words)
assert(answer == expected_answer)
def test_render_screens(self):
words="""
Verse 1: Line 1
Line 2
Verse 2: Line 1
Line 2
Verse 3: Line 1
Line 2
Line 3"""
verses = self.renderer.set_words_openlp(words)
expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
assert(verses == expected_answer)
expected_answer = [QtCore.QRect(0,0,397,126), QtCore.QRect(0,0,397,126),
QtCore.QRect(0,0,397,189)]
for v in range(len(verses)):
answer=self.renderer.render_screen(v)
# print v, answer.x(), answer.y(), answer.width(), answer.height()
assert(answer == expected_answer[v])
def split_test(self, number, answer, expected_answers):
lines=[]
print "Split test", number, answer
for i in range(number):
extra=""
if i == 51: # make an extra long line on line 51 to test wrapping
extra = "Some more words to make it wrap around don't you know until it wraps so many times we don't know what to do"
lines.append(u'Line %d %s' % (i, extra))
result = self.renderer.split_set_of_lines(lines)
print "results---------------__", result
for i in range(len(result)):
self.setup_method(None)
answer = self.renderer._render_lines(result[i])
print answer
self.write_to_file(self.frame.GetPixmap(), "split_test_%03d"% i)
print number, i, answer.x(), answer.y(), answer.width(), \
answer.height()
e = expected_answers[i]
assert(answer == QtCore.QRect(e[0],e[1],e[2],e[3]))
def test_splits(self):
print "Test splits"
self.split_test(100, 11, [(0,0,180,567), (0,0,214,567), (0,0,214,567),
(0,0,214,567), (0,0,214,567), (0,0,214,378), (0,0,759,567),
(0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567),
(0,0,214,567), (0,0,214,567)])
self.split_test(30, 4, [ (0,0,180,441), (0,0,214,441), (0,0,214,441),
(0,0,214,441)])
self.split_test(20, 3, [(0,0,180,378), (0,0,214,378), (0,0,214,378)])
self.split_test(12, 2, [(0,0,180,378), (0,0,214,378)])
self.split_test(4, 1, [(0,0,180,252)])
self.split_test(6, 1, [(0,0,180,378)])
self.split_test(8, 1, [(0,0,180,504)])
if __name__ == "__main__":
t = TestRender()
t.setup_class()
t.setup_method(None)
t.test_easy()
t.test_splits()
t.teardown_method(None)

View File

@ -1,319 +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 sys
import os
from PyQt4 import QtGui, QtCore
from openlp.core.theme import Theme
from test_render import TestRender_base, whoami
pypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
def compare_images(goldenim, testim, threshold=0.01):
# easy test first
if goldenim == testim:
return 1
# how close are they? Calculated the sum of absolute differences in
# each channel of each pixel and divide by the number of pixels in the image
# if this sum is < threshold, the images are deemed to be "close enough"
sad = 0;
for x in range(goldenim.width()):
for y in range(goldenim.height()):
p1=goldenim.pixel(x,y)
p2=testim.pixel(x,y)
sad += abs((p1&0xFF)-(p2&0xFF))
sad += abs((p1>>8&0xFF)-(p2>>8&0xFF))
sad += abs((p1>>16&0xFF)-(p2>>16&0xFF))
sad /= float(goldenim.width()*goldenim.height())
if (sad < threshold):
return 1
return 0
class TestRenderTheme(TestRender_base):
# {{{ Basics
def __init__(self):
TestRender_base.__init__(self)
def setup_method(self, method):
TestRender_base.setup_method(self, method)
print "Theme setup", method
# print "setup theme"
self.renderer.set_theme(Theme(u'blank_theme.xml')) # set "blank" theme
self.renderer.set_text_rectangle(QtCore.QRect(0,0, self.size.width(),
self.size.height()))
words = """How sweet the name of Jesus sounds
In a believer's ear!
It soothes his sorrows, heals his wounds,
And drives away his fear.
"""
verses = self.renderer.set_words_openlp(words)
# usually the same
self.expected_answer = QtCore.QRect(0, 0, 559, 342)
self.msg = None
self.bmpname = "Not set a bitmap yet"
print "------------- setup done --------------"
def teardown_method(self, method):
print "============ teardown =============", method, self.bmpname
if self.bmpname is not None:
assert (self.compare_DC_to_file(self.bmpname))
if self.expected_answer is not None: # result=None => Nothing to check
assert self.expected_answer == self.answer
print "============ teardown done ========="
def compare_DC_to_file(self, name):
"""writes DC out to a bitmap file and then compares it with a golden
one returns True if OK, False if not (so you can assert on it)
"""
print "--- compare DC to file --- ", name
p = self.frame.GetPixmap()
im = self.write_to_file(p, name)
print "Compare"
goldenfilename=os.path.join(u'golden_bitmaps",name+".bmp')
if os.path.exists(goldenfilename):
goldenim = QtGui.QImage(goldenfilename)
else:
print "File", goldenfilename, "not found"
return False
if (compare_images(goldenim, im)):
print name, "Images match"
return True
else:
print name, goldenfilename, "Images don't match"
return False
def test_theme_basic(self):
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
print self.renderer._theme.FontProportion
print self.answer, self.expected_answer, \
self.answer == self.expected_answer
# self.msg=self.bmpname
# }}}
# {{{ Gradients
def test_gradient_h(self):
# normally we wouldn't hack with these directly!
self.renderer._theme.BackgroundType = 1
self.renderer._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
self.renderer._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
self.renderer._theme.BackgroundParameter3 = 1
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_gradient_v(self):
# normally we wouldn't hack with these directly!
self.renderer._theme.BackgroundType = 1
self.renderer._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
self.renderer._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
self.renderer._theme.BackgroundParameter3 = 0
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
# }}}
# {{{ backgrounds
def test_bg_stretch_y(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'snowsmall.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.Name = "stretch y"
self.renderer.set_theme(t)
print "render"
self.answer = self.renderer.render_screen(0)
print "whoami"
self.bmpname = whoami()
print "fone"
def test_bg_shrink_y(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowbig.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.Name = "shrink y"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_bg_stretch_x(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'treessmall.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
t.Name = "stretch x"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.bmpname = whoami()
def test_bg_shrink_x(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'treesbig.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
t.Name = "shrink x"
self.renderer.set_theme(t)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
# }}}
# {{{ Vertical alignment
def test_theme_vertical_align_top(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.Name = "valign top"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_vertical_align_bot(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 1
t.Name = "valign bot"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 257, 559, 342)
self.bmpname = whoami()
def test_theme_vertical_align_cen(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 2
t.Name = "valign cen"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.bmpname = whoami()
# }}}
# {{{ Horzontal alignment
def test_theme_horizontal_align_left(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 0
t.Name = "halign left"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_horizontal_align_right(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 1
t.Name = "halign right"
self.renderer.set_theme(t)
self.expected_answer = QtCore.QRect(0, 0, 800, 342)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_horizontal_align_centre(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 2
t.Name = "halign centre"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 679, 342)
self.bmpname = whoami()
def test_theme_horizontal_align_left_lyric(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 0
t.WrapStyle = 1
t.Name = "halign left lyric"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 778, 342)
self.bmpname = whoami()
# }}}
# {{{ Shadows and outlines
def test_theme_shadow_outline(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,0);
t.Name="shadow/outline"
t.Shadow = 1
t.Outline = 1
t.ShadowColor = QtGui.QColor(64,128,0)
t.OutlineColor = QtGui.QColor(128,0,0)
self.renderer.set_debug(1)
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
hoffset = self.renderer._shadow_offset+2*(self.renderer._outline_offset)
voffset = hoffset * (len(self.renderer.words[0])+1)
self.expected_answer = QtCore.QRect(0, 0, 559+hoffset, 342+voffset)
self.bmpname = whoami()
# }}}
def test_theme_font(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.Name = "font"
t.FontName = "Times New Roman"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 499, 336)
self.bmpname=whoami()
if __name__ == "__main__":
test_render_theme = TestRenderTheme()
test_render_theme.setup_class()
test_render_theme.setup_method(None)
test_render_theme.test_bg_stretch_y()
test_render_theme.teardown_method(None)

View File

@ -1,13 +0,0 @@
from openlp.core.lib import Plugin
import logging
class testplugin3toodeep(Plugin):
name="testplugin3"
version=0
global log
log=logging.getLogger(u'testplugin1')
log.info(u'Started')
weight=10
def __init__(self):
pass

View File

@ -1,13 +0,0 @@
from openlp.core.lib import Plugin
import logging
class testplugin1(Plugin):
name="testplugin1"
version=0
global log
log=logging.getLogger(u'testplugin1')
log.info(u'Started')
weight=10
def __init__(self):
pass

View File

@ -1,8 +0,0 @@
from openlp.core.lib import Plugin
class testplugin2(Plugin):
name="testplugin2"
version=1
weight=1
def __init__(self):
pass

View File

@ -1,82 +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
import os.path
import sys
from PyQt4 import QtGui
from openlp.core.theme import Theme
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..', '..')))
print sys.path
def test_read_theme():
dir = os.path.split(__file__)[0]
# test we can read a theme
theme = Theme(os.path.join(dir, 'test_theme.xml'))
print theme
assert(theme.BackgroundParameter1 == 'sunset1.jpg')
assert(theme.BackgroundParameter2 is None)
assert(theme.BackgroundParameter3 is None)
assert(theme.BackgroundType == 2)
assert(theme.FontColor == QtGui.QColor(255,255,255))
assert(theme.FontName == 'Tahoma')
assert(theme.FontProportion == 16)
assert(theme.FontUnits == 'pixels')
assert(theme.HorizontalAlign == 2)
assert(theme.Name == 'openlp.org Packaged Theme')
assert(theme.Outline == -1)
assert(theme.OutlineColor == QtGui.QColor(255,0,0))
assert(theme.Shadow == -1)
assert(theme.ShadowColor == QtGui.QColor(0,0,1))
assert(theme.VerticalAlign == 0)
def test_theme():
# test we create a "blank" theme correctly
theme = Theme()
print theme
assert(theme.BackgroundParameter1 == QtGui.QColor(0,0,0))
assert(theme.BackgroundParameter2 is None)
assert(theme.BackgroundParameter3 is None)
assert(theme.BackgroundType == 0)
assert(theme.FontColor == QtGui.QColor(255,255,255))
assert(theme.FontName == 'Arial')
assert(theme.FontProportion == 30)
assert(theme.HorizontalAlign == 0)
assert(theme.FontUnits == 'pixels')
assert(theme.Name == 'BlankStyle')
assert(theme.Outline == 0)
assert(theme.Shadow == 0)
assert(theme.VerticalAlign == 0)
print "Tests passed"
if __name__ == "__main__":
test_read_theme()
test_theme()

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Theme>
<Name>openlp.org Packaged Theme</Name>
<BackgroundType>2</BackgroundType>
<BackgroundParameter1>sunset1.jpg</BackgroundParameter1>
<BackgroundParameter2/>
<BackgroundParameter3/>
<FontName>Tahoma</FontName>
<FontColor>clWhite</FontColor>
<FontProportion>16</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>-1</Shadow>
<ShadowColor>$00000001</ShadowColor>
<Outline>-1</Outline>
<OutlineColor>clRed</OutlineColor>
<HorizontalAlign>2</HorizontalAlign>
<VerticalAlign>0</VerticalAlign>
</Theme>

View File

@ -23,14 +23,27 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
class HideMode(object):
"""
This is basically an enumeration class which specifies the mode of a Bible.
Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to
be downloaded from the Internet on an as-needed basis.
"""
Blank = 1
Theme = 2
Screen = 3
from slidecontroller import HideMode
from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList
from maindisplay import MainDisplay
from maindisplay import VideoDisplay
from maindisplay import DisplayManager
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController
from splashscreen import SplashScreen
from displaytab import DisplayTab
from generaltab import GeneralTab
from themestab import ThemesTab
from aboutform import AboutForm

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_AboutDialog(object):
def setupUi(self, AboutDialog):
@ -113,8 +114,8 @@ class Ui_AboutDialog(object):
QtCore.QMetaObject.connectSlotsByName(AboutDialog)
def retranslateUi(self, AboutDialog):
AboutDialog.setWindowTitle(self.trUtf8('About OpenLP'))
self.AboutTextEdit.setPlainText(self.trUtf8(
AboutDialog.setWindowTitle(translate('AboutForm', 'About OpenLP'))
self.AboutTextEdit.setPlainText(translate('AboutForm',
'OpenLP <version><revision> - Open Source Lyrics '
'Projection\n'
'\n'
@ -131,8 +132,8 @@ class Ui_AboutDialog(object):
'consider contributing by using the button below.'
))
self.AboutNotebook.setTabText(
self.AboutNotebook.indexOf(self.AboutTab), self.trUtf8('About'))
self.CreditsTextEdit.setPlainText(self.trUtf8(
self.AboutNotebook.indexOf(self.AboutTab), translate('AboutForm', 'About'))
self.CreditsTextEdit.setPlainText(translate('AboutForm',
'Project Lead\n'
' Raoul "superfly" Snyman\n'
'\n'
@ -164,11 +165,10 @@ class Ui_AboutDialog(object):
))
self.AboutNotebook.setTabText(
self.AboutNotebook.indexOf(self.CreditsTab),
self.trUtf8('Credits'))
self.LicenseTextEdit.setPlainText(self.trUtf8(
'Copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 Raoul '
'Snyman\n'
'Portions copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 '
translate('AboutForm', 'Credits'))
self.LicenseTextEdit.setPlainText(translate('AboutForm',
'Copyright \xa9 2004-2010 Raoul Snyman\n'
'Portions copyright \xa9 2004-2010 '
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri, '
'Christian Richter, Maikel Stuivenberg, Martin Thompson, Jon '
'Tibble, Carsten Tinggaard\n'
@ -557,6 +557,6 @@ class Ui_AboutDialog(object):
'instead of this License.'))
self.AboutNotebook.setTabText(
self.AboutNotebook.indexOf(self.LicenseTab),
self.trUtf8('License'))
self.ContributeButton.setText(self.trUtf8('Contribute'))
self.CloseButton.setText(self.trUtf8('Close'))
translate('AboutForm', 'License'))
self.ContributeButton.setText(translate('AboutForm', 'Contribute'))
self.CloseButton.setText(translate('AboutForm', 'Close'))

View File

@ -25,6 +25,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon
from openlp.core.lib import translate
class Ui_AmendThemeDialog(object):
def setupUi(self, AmendThemeDialog):
@ -178,16 +179,23 @@ class Ui_AmendThemeDialog(object):
self.FontMainWeightLabel.setObjectName("FontMainWeightLabel")
self.MainFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.FontMainWeightLabel)
self.MainLeftLayout.addWidget(self.FontMainGroupBox)
self.FontMainWrapLineAdjustmentLabel = QtGui.QLabel(self.FontMainGroupBox)
self.FontMainWrapLineAdjustmentLabel.setObjectName("FontMainWrapLineAdjustmentLabel")
self.MainFontLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.FontMainWrapLineAdjustmentLabel)
self.FontMainLineAdjustmentSpinBox = QtGui.QSpinBox(self.FontMainGroupBox)
self.FontMainLineAdjustmentSpinBox.setObjectName("FontMainLineAdjustmentSpinBox")
self.FontMainLineAdjustmentSpinBox.setMinimum(-99)
self.MainFontLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.FontMainLineAdjustmentSpinBox)
self.FontMainWrapIndentationLabel = QtGui.QLabel(self.FontMainGroupBox)
self.FontMainWrapIndentationLabel.setObjectName("FontMainWrapIndentationLabel")
self.MainFontLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.FontMainWrapIndentationLabel)
self.MainFontLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.FontMainWrapIndentationLabel)
self.FontMainLineSpacingSpinBox = QtGui.QSpinBox(self.FontMainGroupBox)
self.FontMainLineSpacingSpinBox.setObjectName("FontMainLineSpacingSpinBox")
self.FontMainLineSpacingSpinBox.setMaximum(10)
self.MainFontLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.FontMainLineSpacingSpinBox)
self.MainFontLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.FontMainLineSpacingSpinBox)
self.FontMainLinesPageLabel = QtGui.QLabel(self.FontMainGroupBox)
self.FontMainLinesPageLabel.setObjectName("FontMainLinesPageLabel")
self.MainFontLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.FontMainLinesPageLabel)
self.MainFontLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.FontMainLinesPageLabel)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.MainLeftLayout.addItem(spacerItem1)
self.FontMainLayout.addWidget(self.MainLeftWidget)
@ -595,94 +603,95 @@ class Ui_AmendThemeDialog(object):
AmendThemeDialog.setTabOrder(self.HorizontalComboBox, self.VerticalComboBox)
def retranslateUi(self, AmendThemeDialog):
AmendThemeDialog.setWindowTitle(self.trUtf8('Theme Maintenance'))
self.ThemeNameLabel.setText(self.trUtf8('Theme Name:'))
self.BackgroundLabel.setText(self.trUtf8('Background:'))
self.BackgroundComboBox.setItemText(0, self.trUtf8('Opaque'))
self.BackgroundComboBox.setItemText(1, self.trUtf8('Transparent'))
self.BackgroundTypeLabel.setText(self.trUtf8('Background Type:'))
self.BackgroundTypeComboBox.setItemText(0, self.trUtf8('Solid Color'))
self.BackgroundTypeComboBox.setItemText(1, self.trUtf8('Gradient'))
self.BackgroundTypeComboBox.setItemText(2, self.trUtf8('Image'))
self.Color1Label.setText(self.trUtf8('<Color1>'))
self.Color2Label.setText(self.trUtf8('<Color2>'))
self.ImageLabel.setText(self.trUtf8('Image:'))
self.GradientLabel.setText(self.trUtf8('Gradient :'))
self.GradientComboBox.setItemText(0, self.trUtf8('Horizontal'))
self.GradientComboBox.setItemText(1, self.trUtf8('Vertical'))
self.GradientComboBox.setItemText(2, self.trUtf8('Circular'))
AmendThemeDialog.setWindowTitle(translate('AmendThemeForm', 'Theme Maintenance'))
self.ThemeNameLabel.setText(translate('AmendThemeForm', 'Theme Name:'))
self.BackgroundLabel.setText(translate('AmendThemeForm', 'Background:'))
self.BackgroundComboBox.setItemText(0, translate('AmendThemeForm', 'Opaque'))
self.BackgroundComboBox.setItemText(1, translate('AmendThemeForm', 'Transparent'))
self.BackgroundTypeLabel.setText(translate('AmendThemeForm', 'Background Type:'))
self.BackgroundTypeComboBox.setItemText(0, translate('AmendThemeForm', 'Solid Color'))
self.BackgroundTypeComboBox.setItemText(1, translate('AmendThemeForm', 'Gradient'))
self.BackgroundTypeComboBox.setItemText(2, translate('AmendThemeForm', 'Image'))
self.Color1Label.setText(translate('AmendThemeForm', '<Color1>'))
self.Color2Label.setText(translate('AmendThemeForm', '<Color2>'))
self.ImageLabel.setText(translate('AmendThemeForm', 'Image:'))
self.GradientLabel.setText(translate('AmendThemeForm', 'Gradient :'))
self.GradientComboBox.setItemText(0, translate('AmendThemeForm', 'Horizontal'))
self.GradientComboBox.setItemText(1, translate('AmendThemeForm', 'Vertical'))
self.GradientComboBox.setItemText(2, translate('AmendThemeForm', 'Circular'))
self.ThemeTabWidget.setTabText(
self.ThemeTabWidget.indexOf(self.BackgroundTab),
self.trUtf8('Background'))
self.FontMainGroupBox.setTitle(self.trUtf8('Main Font'))
self.FontMainlabel.setText(self.trUtf8('Font:'))
self.FontMainColorLabel.setText(self.trUtf8('Font Color:'))
self.FontMainSize.setText(self.trUtf8('Size:'))
self.FontMainSizeSpinBox.setSuffix(self.trUtf8('pt'))
self.FontMainWrapIndentationLabel.setText(self.trUtf8('Wrap Indentation'))
self.FontMainWeightComboBox.setItemText(0, self.trUtf8('Normal'))
self.FontMainWeightComboBox.setItemText(1, self.trUtf8('Bold'))
self.FontMainWeightComboBox.setItemText(2, self.trUtf8('Italics'))
self.FontMainWeightComboBox.setItemText(3, self.trUtf8('Bold/Italics'))
self.FontMainWeightLabel.setText(self.trUtf8('Font Weight:'))
self.MainLocationGroupBox.setTitle(self.trUtf8('Display Location'))
self.DefaultLocationLabel.setText(self.trUtf8('Use Default Location:'))
self.FontMainXLabel.setText(self.trUtf8('X Position:'))
self.FontMainYLabel.setText(self.trUtf8('Y Position:'))
self.FontMainWidthLabel.setText(self.trUtf8('Width:'))
self.FontMainHeightLabel.setText(self.trUtf8('Height:'))
self.FontMainXSpinBox.setSuffix(self.trUtf8('px'))
self.FontMainYSpinBox.setSuffix(self.trUtf8('px'))
self.FontMainWidthSpinBox.setSuffix(self.trUtf8('px'))
self.FontMainHeightSpinBox.setSuffix(self.trUtf8('px'))
translate('AmendThemeForm', 'Background'))
self.FontMainGroupBox.setTitle(translate('AmendThemeForm', 'Main Font'))
self.FontMainlabel.setText(translate('AmendThemeForm', 'Font:'))
self.FontMainColorLabel.setText(translate('AmendThemeForm', 'Font Color:'))
self.FontMainSize.setText(translate('AmendThemeForm', 'Size:'))
self.FontMainSizeSpinBox.setSuffix(translate('AmendThemeForm', 'pt'))
self.FontMainWrapIndentationLabel.setText(translate('AmendThemeForm', 'Wrap Indentation'))
self.FontMainWrapLineAdjustmentLabel.setText(translate('AmendThemeForm', 'Adjust Line Spacing'))
self.FontMainWeightComboBox.setItemText(0, translate('AmendThemeForm', 'Normal'))
self.FontMainWeightComboBox.setItemText(1, translate('AmendThemeForm', 'Bold'))
self.FontMainWeightComboBox.setItemText(2, translate('AmendThemeForm', 'Italics'))
self.FontMainWeightComboBox.setItemText(3, translate('AmendThemeForm', 'Bold/Italics'))
self.FontMainWeightLabel.setText(translate('AmendThemeForm', 'Font Weight:'))
self.MainLocationGroupBox.setTitle(translate('AmendThemeForm', 'Display Location'))
self.DefaultLocationLabel.setText(translate('AmendThemeForm', 'Use Default Location:'))
self.FontMainXLabel.setText(translate('AmendThemeForm', 'X Position:'))
self.FontMainYLabel.setText(translate('AmendThemeForm', 'Y Position:'))
self.FontMainWidthLabel.setText(translate('AmendThemeForm', 'Width:'))
self.FontMainHeightLabel.setText(translate('AmendThemeForm', 'Height:'))
self.FontMainXSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontMainYSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontMainWidthSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontMainHeightSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.ThemeTabWidget.setTabText(
self.ThemeTabWidget.indexOf(self.FontMainTab),
self.trUtf8('Font Main'))
self.FooterFontGroupBox.setTitle(self.trUtf8('Footer Font'))
self.FontFooterLabel.setText(self.trUtf8('Font:'))
self.FontFooterColorLabel.setText(self.trUtf8('Font Color:'))
self.FontFooterSizeLabel.setText(self.trUtf8('Size:'))
self.FontFooterSizeSpinBox.setSuffix(self.trUtf8('pt'))
self.FontFooterWeightComboBox.setItemText(0, self.trUtf8('Normal'))
self.FontFooterWeightComboBox.setItemText(1, self.trUtf8('Bold'))
self.FontFooterWeightComboBox.setItemText(2, self.trUtf8('Italics'))
self.FontFooterWeightComboBox.setItemText(3, self.trUtf8('Bold/Italics'))
self.FontFooterWeightLabel.setText(self.trUtf8('Font Weight:'))
self.LocationFooterGroupBox.setTitle(self.trUtf8('Display Location'))
self.FontFooterDefaultLabel.setText(self.trUtf8('Use Default Location:'))
self.FontFooterXLabel.setText(self.trUtf8('X Position:'))
self.FontFooterYLabel.setText(self.trUtf8('Y Position:'))
self.FontFooterWidthLabel.setText(self.trUtf8('Width:'))
self.FontFooterHeightLabel.setText(self.trUtf8('Height:'))
self.FontFooterXSpinBox.setSuffix(self.trUtf8('px'))
self.FontFooterYSpinBox.setSuffix(self.trUtf8('px'))
self.FontFooterWidthSpinBox.setSuffix(self.trUtf8('px'))
self.FontFooterHeightSpinBox.setSuffix(self.trUtf8('px'))
translate('AmendThemeForm', 'Font Main'))
self.FooterFontGroupBox.setTitle(translate('AmendThemeForm', 'Footer Font'))
self.FontFooterLabel.setText(translate('AmendThemeForm', 'Font:'))
self.FontFooterColorLabel.setText(translate('AmendThemeForm', 'Font Color:'))
self.FontFooterSizeLabel.setText(translate('AmendThemeForm', 'Size:'))
self.FontFooterSizeSpinBox.setSuffix(translate('AmendThemeForm', 'pt'))
self.FontFooterWeightComboBox.setItemText(0, translate('AmendThemeForm', 'Normal'))
self.FontFooterWeightComboBox.setItemText(1, translate('AmendThemeForm', 'Bold'))
self.FontFooterWeightComboBox.setItemText(2, translate('AmendThemeForm', 'Italics'))
self.FontFooterWeightComboBox.setItemText(3, translate('AmendThemeForm', 'Bold/Italics'))
self.FontFooterWeightLabel.setText(translate('AmendThemeForm', 'Font Weight:'))
self.LocationFooterGroupBox.setTitle(translate('AmendThemeForm', 'Display Location'))
self.FontFooterDefaultLabel.setText(translate('AmendThemeForm', 'Use Default Location:'))
self.FontFooterXLabel.setText(translate('AmendThemeForm', 'X Position:'))
self.FontFooterYLabel.setText(translate('AmendThemeForm', 'Y Position:'))
self.FontFooterWidthLabel.setText(translate('AmendThemeForm', 'Width:'))
self.FontFooterHeightLabel.setText(translate('AmendThemeForm', 'Height:'))
self.FontFooterXSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontFooterYSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontFooterWidthSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.FontFooterHeightSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.ThemeTabWidget.setTabText(
self.ThemeTabWidget.indexOf(self.FontFooterTab),
self.trUtf8('Font Footer'))
self.OutlineGroupBox.setTitle(self.trUtf8('Outline'))
self.OutlineSpinBoxLabel.setText(self.trUtf8('Outline Size:'))
self.OutlineSpinBox.setSuffix(self.trUtf8('px'))
self.OutlineColorLabel.setText(self.trUtf8('Outline Color:'))
self.OutlineEnabledLabel.setText(self.trUtf8('Show Outline:'))
self.ShadowGroupBox.setTitle(self.trUtf8('Shadow'))
self.ShadowSpinBoxLabel.setText(self.trUtf8('Shadow Size:'))
self.ShadowSpinBox.setSuffix(self.trUtf8('px'))
self.ShadowColorLabel.setText(self.trUtf8('Shadow Color:'))
self.ShadowEnabledLabel.setText(self.trUtf8('Show Shadow:'))
self.AlignmentGroupBox.setTitle(self.trUtf8('Alignment'))
self.HorizontalLabel.setText(self.trUtf8('Horizontal Align:'))
self.HorizontalComboBox.setItemText(0, self.trUtf8('Left'))
self.HorizontalComboBox.setItemText(1, self.trUtf8('Right'))
self.HorizontalComboBox.setItemText(2, self.trUtf8('Center'))
self.VerticalLabel.setText(self.trUtf8('Vertical Align:'))
self.VerticalComboBox.setItemText(0, self.trUtf8('Top'))
self.VerticalComboBox.setItemText(1, self.trUtf8('Middle'))
self.VerticalComboBox.setItemText(2, self.trUtf8('Bottom'))
self.TransitionGroupBox.setTitle(self.trUtf8('Slide Transition'))
self.SlideTransitionCheckedBoxLabel.setText(self.trUtf8('Transition Active:'))
translate('AmendThemeForm', 'Font Footer'))
self.OutlineGroupBox.setTitle(translate('AmendThemeForm', 'Outline'))
self.OutlineSpinBoxLabel.setText(translate('AmendThemeForm', 'Outline Size:'))
self.OutlineSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.OutlineColorLabel.setText(translate('AmendThemeForm', 'Outline Color:'))
self.OutlineEnabledLabel.setText(translate('AmendThemeForm', 'Show Outline:'))
self.ShadowGroupBox.setTitle(translate('AmendThemeForm', 'Shadow'))
self.ShadowSpinBoxLabel.setText(translate('AmendThemeForm', 'Shadow Size:'))
self.ShadowSpinBox.setSuffix(translate('AmendThemeForm', 'px'))
self.ShadowColorLabel.setText(translate('AmendThemeForm', 'Shadow Color:'))
self.ShadowEnabledLabel.setText(translate('AmendThemeForm', 'Show Shadow:'))
self.AlignmentGroupBox.setTitle(translate('AmendThemeForm', 'Alignment'))
self.HorizontalLabel.setText(translate('AmendThemeForm', 'Horizontal Align:'))
self.HorizontalComboBox.setItemText(0, translate('AmendThemeForm', 'Left'))
self.HorizontalComboBox.setItemText(1, translate('AmendThemeForm', 'Right'))
self.HorizontalComboBox.setItemText(2, translate('AmendThemeForm', 'Center'))
self.VerticalLabel.setText(translate('AmendThemeForm', 'Vertical Align:'))
self.VerticalComboBox.setItemText(0, translate('AmendThemeForm', 'Top'))
self.VerticalComboBox.setItemText(1, translate('AmendThemeForm', 'Middle'))
self.VerticalComboBox.setItemText(2, translate('AmendThemeForm', 'Bottom'))
self.TransitionGroupBox.setTitle(translate('AmendThemeForm', 'Slide Transition'))
self.SlideTransitionCheckedBoxLabel.setText(translate('AmendThemeForm', 'Transition Active:'))
self.ThemeTabWidget.setTabText(
self.ThemeTabWidget.indexOf(self.OtherOptionsTab),
self.trUtf8('Other Options'))
self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))
translate('AmendThemeForm', 'Other Options'))
self.PreviewGroupBox.setTitle(translate('AmendThemeForm', 'Preview'))

View File

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

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(u'layoutWidget')
self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget)
self.verticalLayout.setObjectName(u'verticalLayout')
self.CurrentGroupBox = QtGui.QGroupBox(self.layoutWidget)
self.CurrentGroupBox.setObjectName(u'CurrentGroupBox')
self.horizontalLayout = QtGui.QHBoxLayout(self.CurrentGroupBox)
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.verticalLayout_6 = QtGui.QVBoxLayout()
self.verticalLayout_6.setObjectName(u'verticalLayout_6')
self.XLabel = QtGui.QLabel(self.CurrentGroupBox)
self.XLabel.setAlignment(QtCore.Qt.AlignCenter)
self.XLabel.setObjectName(u'XLabel')
self.verticalLayout_6.addWidget(self.XLabel)
self.Xpos = QtGui.QLabel(self.CurrentGroupBox)
self.Xpos.setAlignment(QtCore.Qt.AlignCenter)
self.Xpos.setObjectName(u'Xpos')
self.verticalLayout_6.addWidget(self.Xpos)
self.horizontalLayout.addLayout(self.verticalLayout_6)
self.verticalLayout_7 = QtGui.QVBoxLayout()
self.verticalLayout_7.setObjectName(u'verticalLayout_7')
self.YLabel = QtGui.QLabel(self.CurrentGroupBox)
self.YLabel.setAlignment(QtCore.Qt.AlignCenter)
self.YLabel.setObjectName(u'YLabel')
self.verticalLayout_7.addWidget(self.YLabel)
self.Ypos = QtGui.QLabel(self.CurrentGroupBox)
self.Ypos.setAlignment(QtCore.Qt.AlignCenter)
self.Ypos.setObjectName(u'Ypos')
self.verticalLayout_7.addWidget(self.Ypos)
self.horizontalLayout.addLayout(self.verticalLayout_7)
self.verticalLayout_9 = QtGui.QVBoxLayout()
self.verticalLayout_9.setObjectName(u'verticalLayout_9')
self.HeightLabel = QtGui.QLabel(self.CurrentGroupBox)
self.HeightLabel.setMaximumSize(QtCore.QSize(100, 16777215))
self.HeightLabel.setAlignment(QtCore.Qt.AlignCenter)
self.HeightLabel.setObjectName(u'HeightLabel')
self.verticalLayout_9.addWidget(self.HeightLabel)
self.Height = QtGui.QLabel(self.CurrentGroupBox)
self.Height.setAlignment(QtCore.Qt.AlignCenter)
self.Height.setObjectName(u'Height')
self.verticalLayout_9.addWidget(self.Height)
self.horizontalLayout.addLayout(self.verticalLayout_9)
self.verticalLayout_8 = QtGui.QVBoxLayout()
self.verticalLayout_8.setObjectName(u'verticalLayout_8')
self.WidthLabel = QtGui.QLabel(self.CurrentGroupBox)
self.WidthLabel.setAlignment(QtCore.Qt.AlignCenter)
self.WidthLabel.setObjectName(u'WidthLabel')
self.verticalLayout_8.addWidget(self.WidthLabel)
self.Width = QtGui.QLabel(self.CurrentGroupBox)
self.Width.setAlignment(QtCore.Qt.AlignCenter)
self.Width.setObjectName(u'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(u'CurrentGroupBox_2')
self.horizontalLayout_2 = QtGui.QHBoxLayout(self.CurrentGroupBox_2)
self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.XAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2)
self.XAmendLabel.setAlignment(QtCore.Qt.AlignCenter)
self.XAmendLabel.setObjectName(u'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(u'XposEdit')
self.verticalLayout_2.addWidget(self.XposEdit)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setObjectName(u'verticalLayout_3')
self.YAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2)
self.YAmendLabel.setAlignment(QtCore.Qt.AlignCenter)
self.YAmendLabel.setObjectName(u'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(u'YposEdit')
self.verticalLayout_3.addWidget(self.YposEdit)
self.horizontalLayout_2.addLayout(self.verticalLayout_3)
self.verticalLayout_4 = QtGui.QVBoxLayout()
self.verticalLayout_4.setObjectName(u'verticalLayout_4')
self.HeightAmendLabel = QtGui.QLabel(self.CurrentGroupBox_2)
self.HeightAmendLabel.setAlignment(QtCore.Qt.AlignCenter)
self.HeightAmendLabel.setObjectName(u'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(u'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(u'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(u'WidthAmendLabel')
self.verticalLayout_5.addWidget(self.WidthAmendLabel)
self.WidthEdit = QtGui.QLineEdit(self.CurrentGroupBox_2)
self.WidthEdit.setMaximumSize(QtCore.QSize(60, 16777215))
self.WidthEdit.setObjectName(u'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(u'OverrideCheckBox')
QtCore.QMetaObject.connectSlotsByName(self)
QtCore.QObject.connect(self.OverrideCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onOverrideCheckBoxChanged)
def retranslateUi(self):
self.setWindowTitle( self.trUtf8(u'Amend Display Settings'))
self.CurrentGroupBox.setTitle( self.trUtf8(u'Default Settings'))
self.XLabel.setText(self.trUtf8(u'X'))
self.Xpos.setText(u'0')
self.YLabel.setText( self.trUtf8(u'Y'))
self.Ypos.setText(u'0')
self.HeightLabel.setText( self.trUtf8(u'Height'))
self.Height.setText(u'0')
self.WidthLabel.setText( self.trUtf8(u'Width'))
self.Width.setText(u'0')
self.CurrentGroupBox_2.setTitle( self.trUtf8(u'Amend Settings'))
self.XAmendLabel.setText( self.trUtf8(u'X'))
self.YAmendLabel.setText( self.trUtf8(u'Y'))
self.HeightAmendLabel.setText( self.trUtf8(u'Height'))
self.WidthAmendLabel.setText( self.trUtf8(u'Width'))
self.OverrideCheckBox.setText( self.trUtf8(u'Override Output Display'))
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,16 +25,33 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool
from openlp.core.lib import SettingsTab, Receiver
class GeneralTab(SettingsTab):
"""
GeneralTab is the general settings tab in the settings dialog.
"""
def __init__(self, screen_list):
self.screen_list = screen_list
def __init__(self, screens):
self.screens = screens
SettingsTab.__init__(self, u'General')
def preLoad(self):
"""
Set up the display screen and set correct screen
values.
If not set before default to last screen.
"""
settings = QtCore.QSettings()
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.monitor_number = self.MonitorNumber
self.DisplayOnMonitor = settings.value(
u'display on monitor', QtCore.QVariant(True)).toBool()
self.screens.display = self.DisplayOnMonitor
settings.endGroup()
def setupUi(self):
self.setObjectName(u'GeneralTab')
self.tabTitleVisible = self.trUtf8('General')
@ -60,6 +77,10 @@ class GeneralTab(SettingsTab):
self.MonitorComboBox = QtGui.QComboBox(self.MonitorGroupBox)
self.MonitorComboBox.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.DisplayOnMonitorCheck = QtGui.QCheckBox(self.MonitorGroupBox)
self.DisplayOnMonitorCheck.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.DisplayOnMonitorCheck)
self.GeneralLeftLayout.addWidget(self.MonitorGroupBox)
self.StartupGroupBox = QtGui.QGroupBox(self.GeneralLeftWidget)
self.StartupGroupBox.setObjectName(u'StartupGroupBox')
@ -133,14 +154,19 @@ class GeneralTab(SettingsTab):
self.GeneralLayout.addWidget(self.GeneralRightWidget)
QtCore.QObject.connect(self.MonitorComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onMonitorComboBoxChanged)
QtCore.QObject.connect(self.DisplayOnMonitorCheck,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onDisplayOnMonitorCheckChanged)
QtCore.QObject.connect(self.WarningCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onWarningCheckBoxChanged)
QtCore.QObject.connect(self.AutoOpenCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoOpenCheckBoxChanged)
QtCore.QObject.connect(self.ShowSplashCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onShowSplashCheckBoxChanged)
QtCore.SIGNAL(u'stateChanged(int)'),
self.onShowSplashCheckBoxChanged)
QtCore.QObject.connect(self.SaveCheckServiceCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onSaveCheckServiceCheckBox)
QtCore.SIGNAL(u'stateChanged(int)'),
self.onSaveCheckServiceCheckBox)
QtCore.QObject.connect(self.AutoPreviewCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onAutoPreviewCheckBox)
QtCore.QObject.connect(self.NumberEdit,
@ -152,14 +178,20 @@ class GeneralTab(SettingsTab):
def retranslateUi(self):
self.MonitorGroupBox.setTitle(self.trUtf8('Monitors'))
self.MonitorLabel.setText(self.trUtf8('Select monitor for output display:'))
self.MonitorLabel.setText(
self.trUtf8('Select monitor for output display:'))
self.DisplayOnMonitorCheck.setText(
self.trUtf8('Display if a single screen'))
self.StartupGroupBox.setTitle(self.trUtf8('Application Startup'))
self.WarningCheckBox.setText(self.trUtf8('Show blank screen warning'))
self.AutoOpenCheckBox.setText(self.trUtf8('Automatically open the last service'))
self.AutoOpenCheckBox.setText(
self.trUtf8('Automatically open the last service'))
self.ShowSplashCheckBox.setText(self.trUtf8('Show the splash screen'))
self.SettingsGroupBox.setTitle(self.trUtf8('Application Settings'))
self.SaveCheckServiceCheckBox.setText(self.trUtf8('Prompt to save Service before starting New'))
self.AutoPreviewCheckBox.setText(self.trUtf8('Preview Next Song from Service Manager'))
self.SaveCheckServiceCheckBox.setText(
self.trUtf8('Prompt to save Service before starting New'))
self.AutoPreviewCheckBox.setText(
self.trUtf8('Preview Next Song from Service Manager'))
self.CCLIGroupBox.setTitle(self.trUtf8('CCLI Details'))
self.NumberLabel.setText(self.trUtf8('CCLI Number:'))
self.UsernameLabel.setText(self.trUtf8('SongSelect Username:'))
@ -168,6 +200,9 @@ class GeneralTab(SettingsTab):
def onMonitorComboBoxChanged(self):
self.MonitorNumber = self.MonitorComboBox.currentIndex()
def onDisplayOnMonitorCheckChanged(self, value):
self.DisplayOnMonitor = (value == QtCore.Qt.Checked)
def onAutoOpenCheckBoxChanged(self, value):
self.AutoOpen = (value == QtCore.Qt.Checked)
@ -193,24 +228,36 @@ class GeneralTab(SettingsTab):
self.Password = self.PasswordEdit.displayText()
def load(self):
for screen in self.screen_list.screen_list:
screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1)
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
for screen in self.screens.screen_list:
screen_name = u'%s %d' % (self.trUtf8('Screen'),
screen[u'number'] + 1)
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary'))
self.MonitorComboBox.addItem(screen_name)
# Get the configs
self.MonitorNumber = int(self.config.get_config(u'monitor', u'0'))
self.Warning = str_to_bool(self.config.get_config(u'blank warning', u'False'))
self.AutoOpen = str_to_bool(self.config.get_config(u'auto open', u'False'))
self.ShowSplash = str_to_bool(self.config.get_config(u'show splash', u'True'))
self.PromptSaveService = str_to_bool(self.config.get_config(u'save prompt', u'False'))
self.AutoPreview = str_to_bool(self.config.get_config(u'auto preview', u'False'))
self.CCLINumber = unicode(self.config.get_config(u'ccli number', u''))
self.Username = unicode(self.config.get_config(u'songselect username', u''))
self.Password = unicode(self.config.get_config(u'songselect password', u''))
self.Warning = settings.value(
u'blank warning', QtCore.QVariant(False)).toBool()
self.AutoOpen = settings.value(
u'auto open', QtCore.QVariant(False)).toBool()
self.ShowSplash = settings.value(
u'show splash', QtCore.QVariant(True)).toBool()
self.PromptSaveService = settings.value(
u'save prompt', QtCore.QVariant(False)).toBool()
self.AutoPreview = settings.value(
u'auto preview', QtCore.QVariant(False)).toBool()
self.CCLINumber = unicode(settings.value(
u'ccli number', QtCore.QVariant(u'')).toString())
self.Username = unicode(settings.value(
u'songselect username', QtCore.QVariant(u'')).toString())
self.Password = unicode(settings.value(
u'songselect password', QtCore.QVariant(u'')).toString())
settings.endGroup()
self.SaveCheckServiceCheckBox.setChecked(self.PromptSaveService)
# Set a few things up
self.MonitorComboBox.setCurrentIndex(self.MonitorNumber)
self.DisplayOnMonitorCheck.setChecked(self.DisplayOnMonitor)
self.WarningCheckBox.setChecked(self.Warning)
self.AutoOpenCheckBox.setChecked(self.AutoOpen)
self.ShowSplashCheckBox.setChecked(self.ShowSplash)
@ -220,12 +267,27 @@ class GeneralTab(SettingsTab):
self.PasswordEdit.setText(self.Password)
def save(self):
self.config.set_config(u'monitor', self.MonitorNumber)
self.config.set_config(u'blank warning', self.Warning)
self.config.set_config(u'auto open', self.AutoOpen)
self.config.set_config(u'show splash', self.ShowSplash)
self.config.set_config(u'save prompt', self.PromptSaveService)
self.config.set_config(u'auto preview', self.AutoPreview)
self.config.set_config(u'ccli number', self.CCLINumber)
self.config.set_config(u'songselect username', self.Username)
self.config.set_config(u'songselect password', self.Password)
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
settings.setValue(u'monitor', QtCore.QVariant(self.MonitorNumber))
settings.setValue(u'display on monitor',
QtCore.QVariant(self.DisplayOnMonitor))
settings.setValue(u'blank warning', QtCore.QVariant(self.Warning))
settings.setValue(u'auto open', QtCore.QVariant(self.AutoOpen))
settings.setValue(u'show splash', QtCore.QVariant(self.ShowSplash))
settings.setValue(u'save prompt',
QtCore.QVariant(self.PromptSaveService))
settings.setValue(u'auto preview', QtCore.QVariant(self.AutoPreview))
settings.setValue(u'ccli number', QtCore.QVariant(self.CCLINumber))
settings.setValue(u'songselect username',
QtCore.QVariant(self.Username))
settings.setValue(u'songselect password',
QtCore.QVariant(self.Password))
settings.endGroup()
self.screens.display = self.DisplayOnMonitor
#Monitor Number has changed.
if self.screens.monitor_number != self.MonitorNumber:
self.screens.monitor_number = self.MonitorNumber
self.screens.set_current_display(self.MonitorNumber)
Receiver.send_message(u'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__)
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):
"""
Customised version of QTableWidget which can respond to keyboard
@ -42,28 +64,29 @@ class DisplayWidget(QtGui.QWidget):
log.info(u'MainDisplay loaded')
def __init__(self, parent=None, name=None):
QtGui.QWidget.__init__(self, parent)
QtGui.QWidget.__init__(self, None)
self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'}
self.hotkey_map = {
QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'live_slidecontroller_previous')
Receiver.send_message(u'slidecontroller_live_previous')
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'live_slidecontroller_next')
Receiver.send_message(u'slidecontroller_live_next')
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'live_slidecontroller_first')
Receiver.send_message(u'slidecontroller_live_first')
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'live_slidecontroller_last')
Receiver.send_message(u'slidecontroller_live_last')
event.accept()
elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()])
@ -91,17 +114,18 @@ class MainDisplay(DisplayWidget):
``screens``
The list of screens.
"""
log.debug(u'Initilisation started')
DisplayWidget.__init__(self, None)
log.debug(u'Initialisation started')
DisplayWidget.__init__(self, parent)
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
self.setWindowState(QtCore.Qt.WindowFullScreen)
self.parent = parent
self.setWindowTitle(u'OpenLP Display')
# WA_TranslucentBackground is not available in QT4.4
try:
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
except AttributeError:
pass
self.screens = screens
self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget()
self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self)
@ -112,41 +136,30 @@ class MainDisplay(DisplayWidget):
self.displayBlank = False
self.blankFrame = None
self.frame = None
self.firstTime = True
self.mediaLoaded = False
self.hasTransition = False
self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay)
QtCore.SIGNAL(u'videodisplay_start'), self.hideDisplayForVideo)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_show'), self.showDisplay)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaFinish)
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
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'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
QtCore.SIGNAL(u'videodisplay_background'), self.hideDisplayForVideo)
def setup(self, screenNumber):
def setup(self):
"""
Sets up the screen on a particular screen.
@param (integer) screen This is the screen number.
"""
log.debug(u'Setup %s for %s ' %(self.screens, screenNumber))
log.debug(u'Setup %s for %s ' % (
self.screens, self.screens.monitor_number))
self.setVisible(False)
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
self.display_alert.setGeometry(self.screen[u'size'])
self.video.setGeometry(self.screen[u'size'])
self.display_image.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.display_image.resize(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_text.resize(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.setGeometry(self.screen[u'size'])
#Build a custom splash screen
self.InitialFrame = QtGui.QImage(
self.screen[u'size'].width(),
@ -171,10 +184,11 @@ class MainDisplay(DisplayWidget):
painter.begin(self.blankFrame)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
#build a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.transparent = QtGui.QPixmap(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
self.frameView(self.transparent)
# To display or not to display?
if not self.screen[u'primary']:
@ -183,42 +197,88 @@ class MainDisplay(DisplayWidget):
else:
self.setVisible(False)
self.primary = True
Receiver.send_message(u'screen_changed')
def resetDisplay(self):
Receiver.send_message(u'stop_display_loop')
log.debug(u'resetDisplay')
Receiver.send_message(u'slidecontroller_live_stop_loop')
if self.primary:
self.setVisible(False)
else:
self.showFullScreen()
def hideDisplay(self):
self.mediaLoaded = True
self.setVisible(False)
def hideDisplayForVideo(self):
"""
Hides the main display if for the video to be played
"""
self.hideDisplay(HideMode.Screen)
def hideDisplay(self, mode=HideMode.Screen):
"""
Hide the display by making all layers transparent
Store the images so they can be replaced when required
"""
log.debug(u'hideDisplay mode = %d', mode)
self.storeImage = QtGui.QPixmap(self.display_image.pixmap())
self.storeText = QtGui.QPixmap(self.display_text.pixmap())
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
if mode == HideMode.Screen:
self.display_image.setPixmap(self.transparent)
elif mode == HideMode.Blank:
self.display_image.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
else:
if self.parent.renderManager.renderer.bg_frame:
self.display_image.setPixmap(QtGui.QPixmap.fromImage(
self.parent.renderManager.renderer.bg_frame))
else:
self.display_image.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
self.moveToTop()
def moveToTop(self):
log.debug(u'moveToTop')
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
self.show()
def showDisplay(self):
self.mediaLoaded = False
if not self.primary:
self.setVisible(True)
self.showFullScreen()
Receiver.send_message(u'flush_alert')
"""
Show the stored layers so the screen reappears as it was
originally.
Make the stored images None to release memory.
"""
log.debug(u'showDisplay')
if self.storeImage:
self.display_image.setPixmap(self.storeImage)
self.display_alert.setPixmap(self.transparent)
if self.storeText:
self.display_text.setPixmap(self.storeText)
self.storeImage = None
self.store = None
self.moveToTop()
Receiver.send_message(u'maindisplay_active')
def addImageWithText(self, frame):
frame = resize_image(frame,
self.screen[u'size'].width(),
self.screen[u'size'].height() )
log.debug(u'addImageWithText')
frame = resize_image(
frame, self.screen[u'size'].width(), self.screen[u'size'].height())
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
self.moveToTop()
def setAlertSize(self, top, height):
log.debug(u'setAlertSize')
self.display_alert.setGeometry(
QtCore.QRect(0, top,
self.screen[u'size'].width(), height))
def addAlertImage(self, frame, blank=False):
log.debug(u'addAlertImage')
if blank:
self.display_alert.setPixmap(self.transparent)
else:
self.display_alert.setPixmap(frame)
self.moveToTop()
def frameView(self, frame, transition=False):
"""
@ -231,14 +291,17 @@ class MainDisplay(DisplayWidget):
if not self.displayBlank:
if transition:
if self.frame is not None:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.frame))
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(self.frame))
self.repaint()
self.frame = None
if frame[u'trans'] is not None:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
self.frame = frame[u'trans']
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main']))
self.display_frame = frame[u'main']
self.repaint()
else:
@ -247,77 +310,179 @@ class MainDisplay(DisplayWidget):
else:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame))
self.display_frame = frame
if not self.isVisible():
if not self.isVisible() and self.screens.display:
self.setVisible(True)
self.showFullScreen()
else:
self.waitingFrame = frame
self.waitingFrameTrans = transition
def blankDisplay(self, blankType=HideMode.Blank, blanked=True):
log.debug(u'Blank main Display %d' % blanked)
if blanked:
self.displayBlank = True
if blankType == HideMode.Blank:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
elif blankType == HideMode.Theme:
theme = self.parent.RenderManager.renderer.bg_frame
if not theme:
theme = self.blankFrame
self.display_text.setPixmap(QtGui.QPixmap.fromImage(theme))
self.waitingFrame = None
self.waitingFrameTrans = False
class VideoDisplay(Phonon.VideoWidget):
"""
This is the form that is used to display videos on the projector.
"""
log.info(u'VideoDisplay Loaded')
def __init__(self, parent, screens,
aspect=Phonon.VideoWidget.AspectRatioWidget):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'VideoDisplay Initialisation started')
Phonon.VideoWidget.__init__(self)
self.setWindowTitle(u'OpenLP Video Display')
self.parent = parent
self.screens = screens
self.hidden = False
self.message = None
self.mediaObject = Phonon.MediaObject()
self.setAspectRatio(aspect)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.audioObject)
flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog
# WindowsStaysOnBottomHint is not available in QT4.4
try:
flags = flags | QtCore.Qt.WindowStaysOnBottomHint
except AttributeError:
pass
self.setWindowFlags(flags)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.mediaHide)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.mediaShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_start'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_stop'), self.onMediaStop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'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:
self.displayBlank = False
if self.waitingFrame:
self.frameView(self.waitingFrame, self.waitingFrameTrans)
elif self.display_frame:
self.frameView(self.display_frame)
event.ignore()
def setup(self):
"""
Sets up the screen on a particular screen.
"""
log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens,
self.screens.monitor_number))
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
# To display or not to display?
if not self.screen[u'primary'] 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):
log.debug(u'Queue new media message %s' % message)
self.display_image.close()
self.display_text.close()
self.display_alert.close()
file = os.path.join(message[1], message[2])
if self.firstTime:
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.firstTime = False
else:
self.mediaObject.enqueue(Phonon.MediaSource(file))
self.onMediaPlay()
"""
Set up a video to play from the serviceitem.
"""
log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(),
message[0].get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self._play()
def onMediaPlay(self):
log.debug(u'Play the new media, Live ')
if not self.mediaLoaded and not self.displayBlank:
self.blankDisplay()
self.display_frame = self.blankFrame
self.firstTime = True
self.mediaLoaded = True
self.display_image.hide()
self.display_text.hide()
self.display_alert.hide()
self.video.setFullScreen(True)
self.video.setVisible(True)
"""
Respond to the Play button on the slide controller unless the display
has been hidden by the slidecontroller
"""
if not self.hidden:
log.debug(u'VideoDisplay Play the new media, Live ')
self._play()
def _play(self):
"""
We want to play the video so start it and display the screen
"""
log.debug(u'VideoDisplay _play called')
self.mediaObject.play()
self.setVisible(True)
self.hide()
self.showFullScreen()
def onMediaPause(self):
log.debug(u'Media paused by user')
"""
Pause the video and refresh the screen
"""
log.debug(u'VideoDisplay Media paused by user')
self.mediaObject.pause()
self.show()
def onMediaStop(self):
log.debug(u'Media stopped by user')
"""
Stop the video and clean up
"""
log.debug(u'VideoDisplay Media stopped by user')
self.message = None
self.mediaObject.stop()
self.onMediaFinish()
def onMediaFinish(self):
log.debug(u'Reached end of media playlist')
self.mediaObject.stop()
"""
Clean up the Object queue
"""
log.debug(u'VideoDisplay Reached end of media playlist')
self.mediaObject.clearQueue()
self.mediaLoaded = False
self.video.setVisible(False)
self.display_text.show()
self.display_image.show()
self.blankDisplay(False, 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

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
@ -28,12 +29,11 @@ import time
from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, \
ServiceManager, ThemeManager, MainDisplay, SlideController, \
PluginForm, MediaDockManager
from openlp.core.lib import RenderManager, PluginConfig, build_icon, \
OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool
from openlp.core.utils import check_latest_version, AppLocation
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, DisplayManager
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.utils import check_latest_version, AppLocation, add_actions, LanguageManager
log = logging.getLogger(__name__)
@ -57,23 +57,21 @@ class VersionThread(QtCore.QThread):
A special Qt thread class to fetch the version of OpenLP from the website.
This is threaded so that it doesn't affect the loading time of OpenLP.
"""
def __init__(self, parent, app_version, generalConfig):
def __init__(self, parent, app_version):
QtCore.QThread.__init__(self, parent)
self.parent = parent
self.app_version = app_version
self.generalConfig = generalConfig
def run(self):
"""
Run the thread.
"""
time.sleep(1)
Receiver.send_message(u'blank_check')
version = check_latest_version(self.generalConfig, self.app_version)
Receiver.send_message(u'maindisplay_blank_check')
version = check_latest_version(self.app_version)
#new version has arrived
if version != self.app_version[u'full']:
Receiver.send_message(u'version_check', u'%s' % version)
Receiver.send_message(u'openlp_version_check', u'%s' % version)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
@ -164,7 +162,6 @@ class Ui_MainWindow(object):
self.MediaManagerDock.setWidget(self.MediaManagerContents)
MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
self.MediaManagerDock.setVisible(self.settingsmanager.showMediaManager)
# Create the service manager
self.ServiceManagerDock = OpenLPDockWidget(MainWindow)
ServiceManagerIcon = build_icon(u':/system/system_servicemanager.png')
@ -176,18 +173,17 @@ class Ui_MainWindow(object):
self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock)
self.ServiceManagerDock.setVisible(
self.settingsmanager.showServiceManager)
# Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget(MainWindow)
ThemeManagerIcon = build_icon(u':/system/system_thememanager.png')
self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon)
self.ThemeManagerDock.setObjectName(u'ThemeManagerDock')
self.ThemeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(self)
self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
MainWindow.addDockWidget(
QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock)
self.ThemeManagerDock.setVisible(self.settingsmanager.showThemeManager)
# Create the menu items
self.FileNewItem = QtGui.QAction(MainWindow)
self.FileNewItem.setIcon(
@ -226,20 +222,18 @@ class Ui_MainWindow(object):
self.OptionsSettingsItem.setObjectName(u'OptionsSettingsItem')
self.ViewMediaManagerItem = QtGui.QAction(MainWindow)
self.ViewMediaManagerItem.setCheckable(True)
self.ViewMediaManagerItem.setChecked(
self.settingsmanager.showMediaManager)
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible())
self.ViewMediaManagerItem.setIcon(MediaManagerIcon)
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem')
self.ViewThemeManagerItem = QtGui.QAction(MainWindow)
self.ViewThemeManagerItem.setCheckable(True)
self.ViewThemeManagerItem.setChecked(
self.settingsmanager.showThemeManager)
self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
self.ViewThemeManagerItem.setIcon(ThemeManagerIcon)
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
self.ViewServiceManagerItem = QtGui.QAction(MainWindow)
self.ViewServiceManagerItem.setCheckable(True)
self.ViewServiceManagerItem.setChecked(
self.settingsmanager.showServiceManager)
self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon(ServiceManagerIcon)
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
self.PluginItem = QtGui.QAction(MainWindow)
@ -249,18 +243,32 @@ class Ui_MainWindow(object):
ContentsIcon = build_icon(u':/system/system_help_contents.png')
self.HelpDocumentationItem.setIcon(ContentsIcon)
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem.setEnabled(False)
self.HelpAboutItem = QtGui.QAction(MainWindow)
AboutIcon = build_icon(u':/system/system_about.png')
self.HelpAboutItem.setIcon(AboutIcon)
self.HelpAboutItem.setObjectName(u'HelpAboutItem')
self.HelpOnlineHelpItem = QtGui.QAction(MainWindow)
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False)
self.HelpWebSiteItem = QtGui.QAction(MainWindow)
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
self.LanguageTranslateItem = QtGui.QAction(MainWindow)
self.LanguageTranslateItem.setObjectName(u'LanguageTranslateItem')
self.LanguageEnglishItem = QtGui.QAction(MainWindow)
self.LanguageEnglishItem.setObjectName(u'LanguageEnglishItem')
#i18n Language Items
self.AutoLanguageItem = QtGui.QAction(MainWindow)
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem')
self.AutoLanguageItem.setCheckable(True)
self.LanguageGroup = QtGui.QActionGroup(MainWindow)
qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language()
self.AutoLanguageItem.setChecked(LanguageManager.AutoLanguage)
for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(MainWindow)
languageItem.setObjectName(key)
languageItem.setCheckable(True)
if qmList[key] == savedLanguage:
languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem])
self.LanguageGroup.setDisabled(LanguageManager.AutoLanguage)
self.ToolsAddToolItem = QtGui.QAction(MainWindow)
AddToolIcon = build_icon(u':/tools/tools_add.png')
self.ToolsAddToolItem.setIcon(AddToolIcon)
@ -274,50 +282,37 @@ class Ui_MainWindow(object):
self.settingsmanager.showPreviewPanel)
self.ModeLiveItem = QtGui.QAction(MainWindow)
self.ModeLiveItem.setObjectName(u'ModeLiveItem')
self.FileImportMenu.addAction(self.ImportThemeItem)
self.FileImportMenu.addAction(self.ImportLanguageItem)
self.FileExportMenu.addAction(self.ExportThemeItem)
self.FileExportMenu.addAction(self.ExportLanguageItem)
self.FileMenu.addAction(self.FileNewItem)
self.FileMenu.addAction(self.FileOpenItem)
self.FileMenu.addAction(self.FileSaveItem)
self.FileMenu.addAction(self.FileSaveAsItem)
self.FileMenu.addSeparator()
self.FileMenu.addAction(self.FileImportMenu.menuAction())
self.FileMenu.addAction(self.FileExportMenu.menuAction())
self.FileMenu.addSeparator()
self.FileMenu.addAction(self.FileExitItem)
self.ViewModeMenu.addAction(self.ModeLiveItem)
self.OptionsViewMenu.addAction(self.ViewModeMenu.menuAction())
self.OptionsViewMenu.addSeparator()
self.OptionsViewMenu.addAction(self.ViewMediaManagerItem)
self.OptionsViewMenu.addAction(self.ViewServiceManagerItem)
self.OptionsViewMenu.addAction(self.ViewThemeManagerItem)
self.OptionsViewMenu.addSeparator()
self.OptionsViewMenu.addAction(self.action_Preview_Panel)
self.OptionsLanguageMenu.addAction(self.LanguageEnglishItem)
self.OptionsLanguageMenu.addSeparator()
self.OptionsLanguageMenu.addAction(self.LanguageTranslateItem)
self.OptionsMenu.addAction(self.OptionsLanguageMenu.menuAction())
self.OptionsMenu.addAction(self.OptionsViewMenu.menuAction())
self.OptionsMenu.addSeparator()
self.OptionsMenu.addAction(self.OptionsSettingsItem)
self.ToolsMenu.addAction(self.PluginItem)
self.ToolsMenu.addSeparator()
self.ToolsMenu.addAction(self.ToolsAddToolItem)
self.HelpMenu.addAction(self.HelpDocumentationItem)
self.HelpMenu.addAction(self.HelpOnlineHelpItem)
self.HelpMenu.addSeparator()
self.HelpMenu.addAction(self.HelpWebSiteItem)
self.HelpMenu.addAction(self.HelpAboutItem)
self.MenuBar.addAction(self.FileMenu.menuAction())
self.MenuBar.addAction(self.OptionsMenu.menuAction())
self.MenuBar.addAction(self.ToolsMenu.menuAction())
self.MenuBar.addAction(self.HelpMenu.menuAction())
add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem))
add_actions(self.FileExportMenu,
(self.ExportThemeItem, self.ExportLanguageItem))
self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
self.FileSaveItem, self.FileSaveAsItem, None,
self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(),
self.FileExitItem)
add_actions(self.ViewModeMenu, [self.ModeLiveItem])
add_actions(self.OptionsViewMenu, (self.ViewModeMenu.menuAction(),
None, self.ViewMediaManagerItem, self.ViewServiceManagerItem,
self.ViewThemeManagerItem, None, self.action_Preview_Panel))
#i18n add Language Actions
add_actions(self.OptionsLanguageMenu, (self.AutoLanguageItem, None))
add_actions(self.OptionsLanguageMenu, self.LanguageGroup.actions())
add_actions(self.OptionsMenu, (self.OptionsLanguageMenu.menuAction(),
self.OptionsViewMenu.menuAction(), None, self.OptionsSettingsItem))
add_actions(self.ToolsMenu,
(self.PluginItem, None, self.ToolsAddToolItem))
add_actions(self.HelpMenu,
(self.HelpDocumentationItem, self.HelpOnlineHelpItem, None,
self.HelpWebSiteItem, self.HelpAboutItem))
add_actions(self.MenuBar,
(self.FileMenu.menuAction(), self.OptionsMenu.menuAction(),
self.ToolsMenu.menuAction(), self.HelpMenu.menuAction()))
# Initialise the translation
self.retranslateUi(MainWindow)
self.MediaToolBox.setCurrentIndex(0)
# Connect up some signals and slots
QtCore.QObject.connect(self.FileMenu,
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
QtCore.QObject.connect(self.FileExitItem,
QtCore.SIGNAL(u'triggered()'), MainWindow.close)
QtCore.QObject.connect(self.ControlSplitter,
@ -335,95 +330,101 @@ class Ui_MainWindow(object):
"""
Set up the translation system
"""
MainWindow.mainTitle = self.trUtf8('OpenLP 2.0')
MainWindow.defaultThemeText = self.trUtf8(
MainWindow.mainTitle = translate('MainWindow', 'OpenLP 2.0')
MainWindow.language = translate('MainWindow', 'English')
MainWindow.defaultThemeText = translate('MainWindow',
'Default Theme: ')
MainWindow.setWindowTitle(MainWindow.mainTitle)
self.FileMenu.setTitle(self.trUtf8('&File'))
self.FileImportMenu.setTitle(self.trUtf8('&Import'))
self.FileExportMenu.setTitle(self.trUtf8('&Export'))
self.OptionsMenu.setTitle(self.trUtf8('&Options'))
self.OptionsViewMenu.setTitle(self.trUtf8('&View'))
self.ViewModeMenu.setTitle(self.trUtf8('M&ode'))
self.OptionsLanguageMenu.setTitle(self.trUtf8(
self.FileMenu.setTitle(translate('MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('MainWindow', '&Import'))
self.FileExportMenu.setTitle(translate('MainWindow', '&Export'))
self.OptionsMenu.setTitle(translate('MainWindow', '&Options'))
self.OptionsViewMenu.setTitle(translate('MainWindow', '&View'))
self.ViewModeMenu.setTitle(translate('MainWindow', 'M&ode'))
self.OptionsLanguageMenu.setTitle(translate('MainWindow',
u'&Language'))
self.ToolsMenu.setTitle(self.trUtf8('&Tools'))
self.HelpMenu.setTitle(self.trUtf8('&Help'))
self.ToolsMenu.setTitle(translate('MainWindow', '&Tools'))
self.HelpMenu.setTitle(translate('MainWindow', '&Help'))
self.MediaManagerDock.setWindowTitle(
self.trUtf8('Media Manager'))
translate('MainWindow', 'Media Manager'))
self.ServiceManagerDock.setWindowTitle(
self.trUtf8('Service Manager'))
translate('MainWindow', 'Service Manager'))
self.ThemeManagerDock.setWindowTitle(
self.trUtf8('Theme Manager'))
self.FileNewItem.setText(self.trUtf8('&New'))
self.FileNewItem.setToolTip(self.trUtf8('New Service'))
self.FileNewItem.setStatusTip(self.trUtf8('Create a new Service'))
self.FileNewItem.setShortcut(self.trUtf8('Ctrl+N'))
self.FileOpenItem.setText(self.trUtf8('&Open'))
self.FileOpenItem.setToolTip(self.trUtf8('Open Service'))
self.FileOpenItem.setStatusTip(self.trUtf8('Open an existing service'))
self.FileOpenItem.setShortcut(self.trUtf8('Ctrl+O'))
self.FileSaveItem.setText(self.trUtf8('&Save'))
self.FileSaveItem.setToolTip(self.trUtf8('Save Service'))
translate('MainWindow', 'Theme Manager'))
self.FileNewItem.setText(translate('MainWindow', '&New'))
self.FileNewItem.setToolTip(translate('MainWindow', 'New Service'))
self.FileNewItem.setStatusTip(translate('MainWindow', 'Create a new Service'))
self.FileNewItem.setShortcut(translate('MainWindow', 'Ctrl+N'))
self.FileOpenItem.setText(translate('MainWindow', '&Open'))
self.FileOpenItem.setToolTip(translate('MainWindow', 'Open Service'))
self.FileOpenItem.setStatusTip(translate('MainWindow', 'Open an existing service'))
self.FileOpenItem.setShortcut(translate('MainWindow', 'Ctrl+O'))
self.FileSaveItem.setText(translate('MainWindow', '&Save'))
self.FileSaveItem.setToolTip(translate('MainWindow', 'Save Service'))
self.FileSaveItem.setStatusTip(
self.trUtf8('Save the current service to disk'))
self.FileSaveItem.setShortcut(self.trUtf8('Ctrl+S'))
self.FileSaveAsItem.setText(self.trUtf8('Save &As...'))
self.FileSaveAsItem.setToolTip(self.trUtf8('Save Service As'))
translate('MainWindow', 'Save the current service to disk'))
self.FileSaveItem.setShortcut(translate('MainWindow', 'Ctrl+S'))
self.FileSaveAsItem.setText(translate('MainWindow', 'Save &As...'))
self.FileSaveAsItem.setToolTip(translate('MainWindow', 'Save Service As'))
self.FileSaveAsItem.setStatusTip(
self.trUtf8('Save the current service under a new name'))
self.FileSaveAsItem.setShortcut(self.trUtf8('F12'))
self.FileExitItem.setText(self.trUtf8('E&xit'))
self.FileExitItem.setStatusTip(self.trUtf8('Quit OpenLP'))
self.FileExitItem.setShortcut(self.trUtf8('Alt+F4'))
self.ImportThemeItem.setText(self.trUtf8('&Theme'))
self.ImportLanguageItem.setText(self.trUtf8('&Language'))
self.ExportThemeItem.setText(self.trUtf8('&Theme'))
self.ExportLanguageItem.setText(self.trUtf8('&Language'))
self.actionLook_Feel.setText(self.trUtf8('Look && &Feel'))
self.OptionsSettingsItem.setText(self.trUtf8('&Settings'))
self.ViewMediaManagerItem.setText(self.trUtf8('&Media Manager'))
self.ViewMediaManagerItem.setToolTip(self.trUtf8('Toggle Media Manager'))
translate('MainWindow', 'Save the current service under a new name'))
self.FileSaveAsItem.setShortcut(translate('MainWindow', 'F12'))
self.FileExitItem.setText(translate('MainWindow', 'E&xit'))
self.FileExitItem.setStatusTip(translate('MainWindow', 'Quit OpenLP'))
self.FileExitItem.setShortcut(translate('MainWindow', 'Alt+F4'))
self.ImportThemeItem.setText(translate('MainWindow', '&Theme'))
self.ImportLanguageItem.setText(translate('MainWindow', '&Language'))
self.ExportThemeItem.setText(translate('MainWindow', '&Theme'))
self.ExportLanguageItem.setText(translate('MainWindow', '&Language'))
self.actionLook_Feel.setText(translate('MainWindow', 'Look && &Feel'))
self.OptionsSettingsItem.setText(translate('MainWindow', '&Settings'))
self.ViewMediaManagerItem.setText(translate('MainWindow', '&Media Manager'))
self.ViewMediaManagerItem.setToolTip(
translate('MainWindow', 'Toggle Media Manager'))
self.ViewMediaManagerItem.setStatusTip(
self.trUtf8('Toggle the visibility of the Media Manager'))
self.ViewMediaManagerItem.setShortcut(self.trUtf8('F8'))
self.ViewThemeManagerItem.setText(self.trUtf8('&Theme Manager'))
self.ViewThemeManagerItem.setToolTip(self.trUtf8('Toggle Theme Manager'))
translate('MainWindow', 'Toggle the visibility of the Media Manager'))
self.ViewMediaManagerItem.setShortcut(translate('MainWindow', 'F8'))
self.ViewThemeManagerItem.setText(translate('MainWindow', '&Theme Manager'))
self.ViewThemeManagerItem.setToolTip(
translate('MainWindow', 'Toggle Theme Manager'))
self.ViewThemeManagerItem.setStatusTip(
self.trUtf8('Toggle the visibility of the Theme Manager'))
self.ViewThemeManagerItem.setShortcut(self.trUtf8('F10'))
self.ViewServiceManagerItem.setText(self.trUtf8('&Service Manager'))
translate('MainWindow', 'Toggle the visibility of the Theme Manager'))
self.ViewThemeManagerItem.setShortcut(translate('MainWindow', 'F10'))
self.ViewServiceManagerItem.setText(translate('MainWindow', '&Service Manager'))
self.ViewServiceManagerItem.setToolTip(
self.trUtf8('Toggle Service Manager'))
translate('MainWindow', 'Toggle Service Manager'))
self.ViewServiceManagerItem.setStatusTip(
self.trUtf8('Toggle the visibility of the Service Manager'))
self.ViewServiceManagerItem.setShortcut(self.trUtf8('F9'))
self.action_Preview_Panel.setText(self.trUtf8('&Preview Panel'))
self.action_Preview_Panel.setToolTip(self.trUtf8('Toggle Preview Panel'))
translate('MainWindow', 'Toggle the visibility of the Service Manager'))
self.ViewServiceManagerItem.setShortcut(translate('MainWindow', 'F9'))
self.action_Preview_Panel.setText(translate('MainWindow', '&Preview Panel'))
self.action_Preview_Panel.setToolTip(
translate('MainWindow', 'Toggle Preview Panel'))
self.action_Preview_Panel.setStatusTip(
self.trUtf8('Toggle the visibility of the Preview Panel'))
self.action_Preview_Panel.setShortcut(self.trUtf8('F11'))
self.PluginItem.setText(self.trUtf8('&Plugin List'))
self.PluginItem.setStatusTip(self.trUtf8('List the Plugins'))
self.PluginItem.setShortcut(self.trUtf8('Alt+F7'))
self.HelpDocumentationItem.setText(self.trUtf8('&User Guide'))
self.HelpAboutItem.setText(self.trUtf8('&About'))
translate('MainWindow', 'Toggle the visibility of the Preview Panel'))
self.action_Preview_Panel.setShortcut(translate('MainWindow', 'F11'))
self.PluginItem.setText(translate('MainWindow', '&Plugin List'))
self.PluginItem.setStatusTip(translate('MainWindow', 'List the Plugins'))
self.PluginItem.setShortcut(translate('MainWindow', 'Alt+F7'))
self.HelpDocumentationItem.setText(translate('MainWindow', '&User Guide'))
self.HelpAboutItem.setText(translate('MainWindow', '&About'))
self.HelpAboutItem.setStatusTip(
self.trUtf8('More information about OpenLP'))
self.HelpAboutItem.setShortcut(self.trUtf8('Ctrl+F1'))
self.HelpOnlineHelpItem.setText(self.trUtf8('&Online Help'))
self.HelpWebSiteItem.setText(self.trUtf8('&Web Site'))
self.LanguageTranslateItem.setText(self.trUtf8('&Translate'))
self.LanguageTranslateItem.setStatusTip(
self.trUtf8('Translate the interface to your language'))
self.LanguageEnglishItem.setText(self.trUtf8('English'))
self.LanguageEnglishItem.setStatusTip(
self.trUtf8('Set the interface language to English'))
self.ToolsAddToolItem.setText(self.trUtf8('Add &Tool...'))
translate('MainWindow', 'More information about OpenLP'))
self.HelpAboutItem.setShortcut(translate('MainWindow', 'Ctrl+F1'))
self.HelpOnlineHelpItem.setText(translate('MainWindow', '&Online Help'))
self.HelpWebSiteItem.setText(translate('MainWindow', '&Web Site'))
#i18n
self.AutoLanguageItem.setText(translate('MainWindow', '&Auto Detect'))
self.AutoLanguageItem.setStatusTip(
translate('MainWindow', 'Choose System language, if available'))
for item in self.LanguageGroup.actions():
item.setText(item.objectName())
item.setStatusTip(
translate('MainWindow', 'Set the interface language to %1').arg(item.objectName()))
self.ToolsAddToolItem.setText(translate('MainWindow', 'Add &Tool...'))
self.ToolsAddToolItem.setStatusTip(
self.trUtf8('Add an application to the list of tools'))
self.action_Preview_Panel.setText(self.trUtf8('&Preview Pane'))
self.ModeLiveItem.setText(self.trUtf8('&Live'))
translate('MainWindow', 'Add an application to the list of tools'))
self.action_Preview_Panel.setText(translate('MainWindow', '&Preview Pane'))
self.ModeLiveItem.setText(translate('MainWindow', '&Live'))
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
@ -440,18 +441,28 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMainWindow.__init__(self)
self.screens = screens
self.applicationVersion = applicationVersion
# Set up settings sections for the main application
# (not for use by plugins)
self.uiSettingsSection = u'user interface'
self.generalSettingsSection = u'general'
self.serviceSettingsSection = u'servicemanager'
self.songsSettingsSection = u'songs'
self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens)
self.generalConfig = PluginConfig(u'General')
self.mainDisplay = MainDisplay(self, screens)
self.displayManager = DisplayManager(screens)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self)
self.recentFiles = []
# Set up the path with plugins
pluginpath = AppLocation.get_directory(AppLocation.PluginsDir)
self.plugin_manager = PluginManager(pluginpath)
self.plugin_helpers = {}
# Set up the interface
self.setupUi(self)
# Load settings after setupUi so default UI sizes are overwritten
self.loadSettings()
# Once settings are loaded update FileMenu with recentFiles
self.updateFileMenu()
self.pluginForm = PluginForm(self)
# Set up signals and slots
QtCore.QObject.connect(self.ImportThemeItem,
@ -484,6 +495,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.PreviewController.Panel,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.action_Preview_Panel.setChecked)
QtCore.QObject.connect(self.HelpWebSiteItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpAboutItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.PluginItem,
@ -491,11 +504,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.OptionsSettingsItem,
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged)
QtCore.SIGNAL(u'theme_update_global'), self.defaultThemeChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'version_check'), self.versionCheck)
QtCore.SIGNAL(u'openlp_version_check'), self.versionCheck)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'blank_check'), self.blankCheck)
QtCore.SIGNAL(u'maindisplay_blank_check'), self.blankCheck)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'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.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService)
@ -508,11 +525,17 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveService)
#i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'),
self.setAutoLanguage)
self.LanguageGroup.triggered.connect(LanguageManager.set_language)
#warning cyclic dependency
#RenderManager needs to call ThemeManager and
#ThemeManager needs to call RenderManager
self.RenderManager = RenderManager(self.ThemeManagerContents,
self.screens, self.getMonitorNumber())
self.RenderManager = RenderManager(
self.ThemeManagerContents, self.screens)
self.displayManager.renderManager = self.RenderManager
#Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
log.info(u'Load Plugins')
@ -521,9 +544,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_helpers[u'live'] = self.LiveController
self.plugin_helpers[u'render'] = self.RenderManager
self.plugin_helpers[u'service'] = self.ServiceManagerContents
self.plugin_helpers[u'settings'] = self.settingsForm
self.plugin_helpers[u'settings form'] = self.settingsForm
self.plugin_helpers[u'toolbox'] = self.mediaDockManager
self.plugin_helpers[u'maindisplay'] = self.mainDisplay
self.plugin_helpers[u'maindisplay'] = self.displayManager.mainDisplay
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
# hook methods have to happen after find_plugins. Find plugins needs
# the controllers hence the hooks have moved from setupUI() to here
@ -549,9 +572,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
log.info(u'Load data from Settings')
self.settingsForm.postSetUp()
#i18n
def setAutoLanguage(self, value):
self.LanguageGroup.setDisabled(value)
LanguageManager.AutoLanguage = value
LanguageManager.set_language(self.LanguageGroup.checkedAction())
def versionCheck(self, version):
"""
Checks the version of the Application called from openlp.pyw
Triggered by delay thread.
"""
app_version = self.applicationVersion[u'full']
version_text = unicode(self.trUtf8('Version %s of OpenLP is now '
@ -563,45 +593,52 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
def getMonitorNumber(self):
"""
Set up the default behaviour of the monitor configuration in
here. Currently it is set to default to monitor 0 if the saved
monitor number does not exist.
"""
screen_number = int(self.generalConfig.get_config(u'monitor', 0))
if not self.screens.screen_exists(screen_number):
screen_number = 0
return screen_number
def show(self):
"""
Show the main form, as well as the display form
"""
self.showMaximized()
screen_number = self.getMonitorNumber()
self.mainDisplay.setup(screen_number)
if self.mainDisplay.isVisible():
self.mainDisplay.setFocus()
QtGui.QWidget.show(self)
#screen_number = self.getMonitorNumber()
self.displayManager.setup()
if self.displayManager.mainDisplay.isVisible():
self.displayManager.mainDisplay.setFocus()
self.activateWindow()
if str_to_bool(self.generalConfig.get_config(u'auto open', False)):
if QtCore.QSettings().value(
self.generalSettingsSection + u'/auto open',
QtCore.QVariant(False)).toBool():
self.ServiceManagerContents.onLoadService(True)
def blankCheck(self):
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)
QtGui.QMessageBox.question(self,
self.trUtf8('OpenLP Main Display Blanked'),
self.trUtf8('The Main Display has been blanked out'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
settings.endGroup()
def versionThread(self):
#app_version = self.applicationVersion[u'full']
vT = VersionThread(self, self.applicationVersion, self.generalConfig)
"""
Start an initial setup thread to delay notifications
"""
vT = VersionThread(self, self.applicationVersion)
vT.start()
def onHelpWebSiteClicked(self):
"""
Load the OpenLP website
"""
import webbrowser
webbrowser.open_new(u'http://openlp.org/')
def onHelpAboutItemClicked(self):
"""
Show the About form
@ -621,13 +658,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Show the Settings dialog
"""
self.settingsForm.exec_()
updated_display = self.getMonitorNumber()
if updated_display != self.screens.current_display:
self.screens.set_current_display(updated_display)
self.RenderManager.update_display(updated_display)
self.mainDisplay.setup(updated_display)
#Trigger after changes have been made
Receiver.send_message(u'config_updated')
def screenChanged(self):
"""
The screen has changed to so tell the displays to update_display
their locations
"""
self.RenderManager.update_display()
self.displayManager.setup()
self.setFocus()
self.activateWindow()
def closeEvent(self, event):
@ -637,7 +676,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if self.serviceNotSaved:
ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your service has changed, do you want to save those changes?'),
self.trUtf8('Your service has changed. '
'Do you want to save those changes?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Discard |
@ -645,17 +685,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save:
self.ServiceManagerContents.onSaveService()
self.mainDisplay.close()
self.cleanUp()
event.accept()
elif ret == QtGui.QMessageBox.Discard:
self.mainDisplay.close()
self.cleanUp()
event.accept()
else:
event.ignore()
else:
self.mainDisplay.close()
self.cleanUp()
event.accept()
@ -668,6 +705,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Call the cleanup method to shutdown plugins.
log.info(u'cleanup plugins')
self.plugin_manager.finalise_plugins()
# Save settings
self.saveSettings()
#Close down the displays
self.displayManager.close()
def serviceChanged(self, reset=False, serviceName=None):
"""
@ -691,6 +732,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
title = u'%s - %s*' % (self.mainTitle, service_name)
self.setWindowTitle(title)
def showStatusMessage(self, message):
self.StatusBar.showMessage(message)
def defaultThemeChanged(self, theme):
self.DefaultThemeLabel.setText(
u'%s %s' % (self.defaultThemeText, theme))
@ -698,22 +742,75 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def toggleMediaManager(self, visible):
if self.MediaManagerDock.isVisible() != visible:
self.MediaManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.MediaManagerDock.objectName(), visible)
def toggleServiceManager(self, visible):
if self.ServiceManagerDock.isVisible() != visible:
self.ServiceManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.ServiceManagerDock.objectName(), visible)
def toggleThemeManager(self, visible):
if self.ThemeManagerDock.isVisible() != visible:
self.ThemeManagerDock.setVisible(visible)
self.settingsmanager.setUIItemVisibility(
self.ThemeManagerDock.objectName(), visible)
def togglePreviewPanel(self):
previewBool = self.PreviewController.Panel.isVisible()
self.PreviewController.Panel.setVisible(not previewBool)
self.settingsmanager.togglePreviewPanel(not previewBool)
def loadSettings(self):
log.debug(u'Loading QSettings')
settings = QtCore.QSettings()
settings.beginGroup(self.generalSettingsSection)
self.recentFiles = settings.value(u'recent files').toStringList()
settings.endGroup()
settings.beginGroup(self.uiSettingsSection)
self.move(settings.value(u'main window position',
QtCore.QVariant(QtCore.QPoint(0, 0))).toPoint())
self.restoreGeometry(
settings.value(u'main window geometry').toByteArray())
self.restoreState(settings.value(u'main window state').toByteArray())
settings.endGroup()
def saveSettings(self):
log.debug(u'Saving QSettings')
settings = QtCore.QSettings()
settings.beginGroup(self.generalSettingsSection)
recentFiles = QtCore.QVariant(self.recentFiles) \
if self.recentFiles else QtCore.QVariant()
settings.setValue(u'recent files', recentFiles)
settings.endGroup()
settings.beginGroup(self.uiSettingsSection)
settings.setValue(u'main window position',
QtCore.QVariant(self.pos()))
settings.setValue(u'main window state',
QtCore.QVariant(self.saveState()))
settings.setValue(u'main window geometry',
QtCore.QVariant(self.saveGeometry()))
settings.endGroup()
def updateFileMenu(self):
self.FileMenu.clear()
add_actions(self.FileMenu, self.FileMenuActions[:-1])
existingRecentFiles = []
for file in self.recentFiles:
if QtCore.QFile.exists(file):
existingRecentFiles.append(file)
if existingRecentFiles:
self.FileMenu.addSeparator()
for fileId, filename in enumerate(existingRecentFiles):
action = QtGui.QAction(u'&%d %s' % (fileId +1,
QtCore.QFileInfo(filename).fileName()), self)
action.setData(QtCore.QVariant(filename))
self.connect(action, QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.loadService)
self.FileMenu.addAction(action)
self.FileMenu.addSeparator()
self.FileMenu.addAction(self.FileMenuActions[-1])
def addRecentFile(self, filename):
recentFileCount = QtCore.QSettings().value(
self.generalSettingsSection + u'/max recent files',
QtCore.QVariant(4)).toInt()[0]
if filename and not self.recentFiles.contains(filename):
self.recentFiles.prepend(QtCore.QString(filename))
while self.recentFiles.count() > recentFileCount:
self.recentFiles.takeLast()

View File

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

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_PluginViewDialog(object):
def setupUi(self, PluginViewDialog):
@ -98,11 +99,11 @@ class Ui_PluginViewDialog(object):
QtCore.QMetaObject.connectSlotsByName(PluginViewDialog)
def retranslateUi(self, PluginViewDialog):
PluginViewDialog.setWindowTitle(self.trUtf8('Plugin List'))
self.PluginInfoGroupBox.setTitle(self.trUtf8('Plugin Details'))
self.VersionLabel.setText(self.trUtf8('Version:'))
self.VersionNumberLabel.setText(self.trUtf8('TextLabel'))
self.AboutLabel.setText(self.trUtf8('About:'))
self.StatusLabel.setText(self.trUtf8('Status:'))
self.StatusComboBox.setItemText(0, self.trUtf8('Active'))
self.StatusComboBox.setItemText(1, self.trUtf8('Inactive'))
PluginViewDialog.setWindowTitle(translate('PluginForm', 'Plugin List'))
self.PluginInfoGroupBox.setTitle(translate('PluginForm', 'Plugin Details'))
self.VersionLabel.setText(translate('PluginForm', 'Version:'))
self.VersionNumberLabel.setText(translate('PluginForm', 'TextLabel'))
self.AboutLabel.setText(translate('PluginForm', 'About:'))
self.StatusLabel.setText(translate('PluginForm', 'Status:'))
self.StatusComboBox.setItemText(0, translate('PluginForm', 'Active'))
self.StatusComboBox.setItemText(1, translate('PluginForm', 'Inactive'))

View File

@ -24,6 +24,7 @@
###############################################################################
import logging
import copy
log = logging.getLogger(__name__)
@ -36,15 +37,19 @@ class ScreenList(object):
def __init__(self):
self.preview = None
self.current = None
self.override = None
self.screen_list = []
self.count = 0
self.display_count = 0
#actual display number
self.current_display = 0
#save config display number
self.monitor_number = 0
def add_screen(self, screen):
if screen[u'primary']:
self.current = screen
self.screen_list.append(screen)
self.count += 1
self.display_count += 1
def screen_exists(self, number):
for screen in self.screen_list:
@ -53,21 +58,35 @@ class ScreenList(object):
return False
def set_current_display(self, number):
if number + 1 > self.count:
"""
Set up the current screen dimensions
"""
log.debug(u'set_current_display %s', number, )
if number + 1 > self.display_count:
self.current = self.screen_list[0]
self.override = copy.deepcopy(self.current)
self.current_display = 0
else:
self.current = self.screen_list[number]
self.preview = self.current
self.override = copy.deepcopy(self.current)
self.preview = copy.deepcopy(self.current)
self.current_display = number
if self.count == 1:
if self.display_count == 1:
self.preview = self.screen_list[0]
# if self.screen[u'number'] != screenNumber:
# # We will most probably never actually hit this bit, but just in
# # case the index in the list doesn't match the screen number, we
# # search for it.
# for scrn in self.screens:
# if scrn[u'number'] == screenNumber:
# self.screen = scrn
# break
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

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_ServiceItemEditDialog(object):
def setupUi(self, ServiceItemEditDialog):
@ -66,8 +67,8 @@ class Ui_ServiceItemEditDialog(object):
QtCore.QMetaObject.connectSlotsByName(ServiceItemEditDialog)
def retranslateUi(self, ServiceItemEditDialog):
ServiceItemEditDialog.setWindowTitle(self.trUtf8('Service Item Maintenance'))
self.upButton.setText(self.trUtf8('Up'))
self.deleteButton.setText(self.trUtf8('Delete'))
self.downButton.setText(self.trUtf8('Down'))
ServiceItemEditDialog.setWindowTitle(translate('ServiceItemEditForm', 'Service Item Maintenance'))
self.upButton.setText(translate('ServiceItemEditForm', 'Up'))
self.deleteButton.setText(translate('ServiceItemEditForm', 'Delete'))
self.downButton.setText(translate('ServiceItemEditForm', 'Down'))

View File

@ -32,14 +32,15 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \
contextMenuAction, Receiver, str_to_bool, build_icon
from openlp.core.lib import OpenLPToolbar, ServiceItem, contextMenuAction, \
Receiver, build_icon, ItemCapabilities, SettingsManager
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
from openlp.core.utils import AppLocation
class ServiceManagerList(QtGui.QTreeWidget):
def __init__(self, parent=None, name=None):
QtGui.QTreeWidget.__init__(self,parent)
QtGui.QTreeWidget.__init__(self, parent)
self.parent = parent
def keyPressEvent(self, event):
@ -83,7 +84,7 @@ class ServiceManagerList(QtGui.QTreeWidget):
mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData)
mimeData.setText(u'ServiceManager')
dropAction = drag.start(QtCore.Qt.CopyAction)
drag.start(QtCore.Qt.CopyAction)
class ServiceManager(QtGui.QWidget):
"""
@ -100,12 +101,10 @@ class ServiceManager(QtGui.QWidget):
self.parent = parent
self.serviceItems = []
self.serviceName = u''
self.suffixes = []
self.droppos = 0
#is a new service and has not been saved
self.isNew = True
#Indicates if remoteTriggering is active. If it is the next addServiceItem call
#will replace the currently selected one.
self.remoteEditTriggered = False
self.serviceNoteForm = ServiceNoteForm()
self.serviceItemEditForm = ServiceItemEditForm()
#start with the layout
@ -186,29 +185,38 @@ class ServiceManager(QtGui.QWidget):
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentation types'), self.onPresentationTypes)
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_previous_item'), self.previousItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_set_item'), self.onSetItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
# Last little bits of setting up
self.config = PluginConfig(u'ServiceManager')
self.servicePath = self.config.get_data_path()
self.service_theme = unicode(
self.config.get_config(u'service theme', u''))
self.service_theme = unicode(QtCore.QSettings().value(
self.parent.serviceSettingsSection + u'/service theme',
QtCore.QVariant(u'')).toString())
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
#build the drag and drop context menu
self.dndMenu = QtGui.QMenu()
self.newAction = self.dndMenu.addAction(self.trUtf8('&Add New Item'))
self.newAction.setIcon(build_icon(u':/general/general_edit.png'))
self.addToAction = self.dndMenu.addAction(self.trUtf8('&Add to Selected Item'))
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
#build the context menu
self.menu = QtGui.QMenu()
self.editAction = self.menu.addAction(self.trUtf8('&Edit Item'))
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item'))
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
self.maintainAction.setIcon(build_icon(u':/general/general_edit.png'))
self.notesAction = self.menu.addAction(self.trUtf8('&Notes'))
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
self.deleteAction = self.menu.addAction(self.trUtf8('&Delete From Service'))
self.deleteAction = self.menu.addAction(
self.trUtf8('&Delete From Service'))
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
self.sep1 = self.menu.addAction(u'')
self.sep1.setSeparator(True)
@ -221,6 +229,9 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu = QtGui.QMenu(self.trUtf8(u'&Change Item Theme'))
self.menu.addMenu(self.themeMenu)
def supportedSuffixes(self, suffix):
self.suffixes.append(suffix)
def contextMenu(self, point):
item = self.ServiceManagerList.itemAt(point)
if item is None:
@ -233,9 +244,10 @@ class ServiceManager(QtGui.QWidget):
self.editAction.setVisible(False)
self.maintainAction.setVisible(False)
self.notesAction.setVisible(False)
if serviceItem[u'service_item'].edit_enabled:
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit):
self.editAction.setVisible(True)
if serviceItem[u'service_item'].maintain_allowed:
if serviceItem[u'service_item']\
.is_capable(ItemCapabilities.AllowsMaintain):
self.maintainAction.setVisible(True)
if item.parent() is None:
self.notesAction.setVisible(True)
@ -256,9 +268,6 @@ class ServiceManager(QtGui.QWidget):
if action == self.liveAction:
self.makeLive()
def onPresentationTypes(self, presentation_types):
self.presentation_types = presentation_types
def onServiceItemNoteForm(self):
item, count = self.findServiceItem()
self.serviceNoteForm.textEdit.setPlainText(
@ -296,6 +305,41 @@ class ServiceManager(QtGui.QWidget):
lookFor = 1
serviceIterator += 1
def previousItem(self):
"""
Called by the SlideController to select the
previous service item
"""
if len(self.ServiceManagerList.selectedItems()) == 0:
return
selected = self.ServiceManagerList.selectedItems()[0]
prevItem = None
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
while serviceIterator.value():
if serviceIterator.value() == selected:
if prevItem:
self.ServiceManagerList.setCurrentItem(prevItem)
self.makeLive()
return
if serviceIterator.value().parent() is None:
prevItem = serviceIterator.value()
serviceIterator += 1
def onSetItem(self, message):
"""
Called by a signal to select a specific item
"""
self.setItem(int(message[0]))
def setItem(self, index):
"""
Makes a specific item in the service live
"""
if index >= 0 and index < self.ServiceManagerList.topLevelItemCount:
item = self.ServiceManagerList.topLevelItem(index)
self.ServiceManagerList.setCurrentItem(item)
self.makeLive()
def onMoveSelectionUp(self):
"""
Moves the selection up the window
@ -410,13 +454,13 @@ class ServiceManager(QtGui.QWidget):
"""
Clear the list to create a new service
"""
if self.parent.serviceNotSaved and \
str_to_bool(PluginConfig(u'General').
get_config(u'save prompt', u'False')):
if self.parent.serviceNotSaved and QtCore.QSettings().value(
self.parent.generalSettingsSection + u'/save prompt',
QtCore.QVariant(False)).toBool():
ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your service is unsaved, do you want to save those '
'changes before creating a new one ?'),
self.trUtf8('Your service is unsaved, do you want to save '
'those changes before creating a new one?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Save),
@ -455,19 +499,22 @@ class ServiceManager(QtGui.QWidget):
for itemcount, item in enumerate(self.serviceItems):
serviceitem = item[u'service_item']
treewidgetitem = QtGui.QTreeWidgetItem(self.ServiceManagerList)
if serviceitem.notes:
icon = QtGui.QImage(serviceitem.icon)
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
overlay = QtGui.QImage(':/services/service_item_notes.png')
overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
painter = QtGui.QPainter(icon)
painter.drawImage(0, 0, overlay)
painter.end()
treewidgetitem.setIcon(0, build_icon(icon))
if serviceitem.is_valid:
if serviceitem.notes:
icon = QtGui.QImage(serviceitem.icon)
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
overlay = QtGui.QImage(':/services/service_item_notes.png')
overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
painter = QtGui.QPainter(icon)
painter.drawImage(0, 0, overlay)
painter.end()
treewidgetitem.setIcon(0, build_icon(icon))
else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation)
else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation)
treewidgetitem.setIcon(0, build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.title)
treewidgetitem.setToolTip(0, serviceitem.notes)
treewidgetitem.setData(0, QtCore.Qt.UserRole,
@ -495,17 +542,21 @@ class ServiceManager(QtGui.QWidget):
log.debug(u'onSaveService')
if not quick or self.isNew:
filename = QtGui.QFileDialog.getSaveFileName(self,
self.trUtf8(u'Save Service'), self.config.get_last_dir(),
self.trUtf8(u'Save Service'),
SettingsManager.get_last_dir(self.parent.serviceSettingsSection),
self.trUtf8(u'OpenLP Service Files (*.osz)'))
else:
filename = self.config.get_last_dir()
filename = SettingsManager.get_last_dir(
self.parent.serviceSettingsSection)
if filename:
splittedFile = filename.split(u'.')
if splittedFile[-1] != u'osz':
filename = filename + u'.osz'
filename = unicode(filename)
self.isNew = False
self.config.set_last_dir(filename)
SettingsManager.set_last_dir(
self.parent.serviceSettingsSection,
os.path.split(filename)[0])
service = []
servicefile = filename + u'.osd'
zip = None
@ -513,7 +564,8 @@ class ServiceManager(QtGui.QWidget):
try:
zip = zipfile.ZipFile(unicode(filename), 'w')
for item in self.serviceItems:
service.append({u'serviceitem':item[u'service_item'].get_service_repr()})
service.append({u'serviceitem':item[u'service_item']
.get_service_repr()})
if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames():
path_from = unicode(os.path.join(
@ -537,27 +589,52 @@ class ServiceManager(QtGui.QWidget):
pass #if not present do not worry
name = filename.split(os.path.sep)
self.serviceName = name[-1]
self.parent.addRecentFile(filename)
self.parent.serviceChanged(True, self.serviceName)
def onQuickSaveService(self):
self.onSaveService(True)
def onLoadService(self, lastService=False):
if lastService:
filename = SettingsManager.get_last_dir(
self.parent.serviceSettingsSection)
else:
filename = QtGui.QFileDialog.getOpenFileName(
self, self.trUtf8('Open Service'),
SettingsManager.get_last_dir(
self.parent.serviceSettingsSection), u'Services (*.osz)')
self.loadService(filename)
def loadService(self, filename=None):
"""
Load an existing service from disk and rebuild the serviceitems. All
files retrieved from the zip file are placed in a temporary directory
and will only be used for this service.
"""
if lastService:
filename = self.config.get_last_dir()
else:
filename = QtGui.QFileDialog.getOpenFileName(
self, self.trUtf8('Open Service'),
self.config.get_last_dir(), u'Services (*.osz)')
if self.parent.serviceNotSaved:
ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your current service is unsaved, do you want to '
'save the changes before opening a new one?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save:
self.onSaveService()
if filename is None:
action = self.sender()
if isinstance(action, QtGui.QAction):
filename = action.data().toString()
else:
return
filename = unicode(filename)
name = filename.split(os.path.sep)
if filename:
self.config.set_last_dir(filename)
SettingsManager.set_last_dir(
self.parent.serviceSettingsSection,
os.path.split(filename)[0])
zip = None
f = None
try:
@ -581,8 +658,8 @@ class ServiceManager(QtGui.QWidget):
serviceitem = ServiceItem()
serviceitem.RenderManager = self.parent.RenderManager
serviceitem.set_from_service(item, self.servicePath)
if self.validateItem(serviceitem):
self.addServiceItem(serviceitem)
self.validateItem(serviceitem)
self.addServiceItem(serviceitem)
try:
if os.path.isfile(p_file):
os.remove(p_file)
@ -597,15 +674,18 @@ class ServiceManager(QtGui.QWidget):
zip.close()
self.isNew = False
self.serviceName = name[len(name) - 1]
self.parent.addRecentFile(filename)
self.parent.serviceChanged(True, self.serviceName)
def validateItem(self, serviceItem):
# print "---"
# print serviceItem.name
# print serviceItem.title
# print serviceItem.service_item_path
# print serviceItem.service_item_type
return True
"""
Validates the service item and if the suffix matches an accepted
one it allows the item to be displayed
"""
if serviceItem.is_command():
type = serviceItem._raw_frames[0][u'title'].split(u'.')[1]
if type not in self.suffixes:
serviceItem.is_valid = False
def cleanUp(self):
"""
@ -625,7 +705,9 @@ class ServiceManager(QtGui.QWidget):
"""
self.service_theme = unicode(self.ThemeComboBox.currentText())
self.parent.RenderManager.set_service_theme(self.service_theme)
self.config.set_config(u'service theme', self.service_theme)
QtCore.QSettings().setValue(
self.parent.serviceSettingsSection + u'/service theme',
QtCore.QVariant(self.service_theme))
self.regenerateServiceItems()
def regenerateServiceItems(self):
@ -637,12 +719,13 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems = []
self.isNew = True
for item in tempServiceItems:
self.addServiceItem(item[u'service_item'], False, item[u'expanded'])
self.addServiceItem(
item[u'service_item'], False, item[u'expanded'])
#Set to False as items may have changed rendering
#does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName)
def addServiceItem(self, item, rebuild=False, expand=True):
def addServiceItem(self, item, rebuild=False, expand=True, replace=False):
"""
Add a Service item to the list
@ -652,10 +735,9 @@ class ServiceManager(QtGui.QWidget):
"""
sitem, count = self.findServiceItem()
item.render()
if self.remoteEditTriggered:
if replace:
item.merge(self.serviceItems[sitem][u'service_item'])
self.serviceItems[sitem][u'service_item'] = item
self.remoteEditTriggered = False
self.repaintServiceList(sitem + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(item)
else:
@ -687,8 +769,17 @@ class ServiceManager(QtGui.QWidget):
Send the current item to the Preview slide controller
"""
item, count = self.findServiceItem()
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count)
if self.serviceItems[item][u'service_item'].is_valid:
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):
"""
@ -698,8 +789,6 @@ class ServiceManager(QtGui.QWidget):
if item == -1:
return False
else:
#Switch on remote edit update functionality.
self.remoteEditTriggered = True
return self.serviceItems[item][u'service_item']
def makeLive(self):
@ -707,30 +796,38 @@ class ServiceManager(QtGui.QWidget):
Send the current item to the Live slide controller
"""
item, count = self.findServiceItem()
self.parent.LiveController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count)
if str_to_bool(PluginConfig(u'General').
get_config(u'auto preview', u'False')):
item += 1
if self.serviceItems and item < len(self.serviceItems) and \
self.serviceItems[item][u'service_item'].auto_preview_allowed:
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], 0)
if self.serviceItems[item][u'service_item'].is_valid:
self.parent.LiveController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count)
if QtCore.QSettings().value(
self.parent.generalSettingsSection + u'/auto preview',
QtCore.QVariant(False)).toBool():
item += 1
if self.serviceItems and item < len(self.serviceItems) and \
self.serviceItems[item][u'service_item'].is_capable(
ItemCapabilities.AllowsPreview):
self.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):
"""
Posts a remote edit message to a plugin to allow item to be edited.
"""
item, count = self.findServiceItem()
if self.serviceItems[item][u'service_item'].edit_enabled:
self.remoteEditTriggered = True
if self.serviceItems[item][u'service_item']\
.is_capable(ItemCapabilities.AllowsEdit):
Receiver.send_message(u'%s_edit' %
self.serviceItems[item][u'service_item'].name, u'L:%s' %
self.serviceItems[item][u'service_item'].name.lower(), u'L:%s' %
self.serviceItems[item][u'service_item'].editId )
def onRemoteEditClear(self):
self.remoteEditTriggered = False
def findServiceItem(self):
"""
Finds a ServiceItem in the list
@ -772,8 +869,9 @@ class ServiceManager(QtGui.QWidget):
if link.hasText():
plugin = event.mimeData().text()
item = self.ServiceManagerList.itemAt(event.pos())
#ServiceManager started the drag and drop
if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem()
startpos, startCount = self.findServiceItem()
if item is None:
endpos = len(self.serviceItems)
else:
@ -787,11 +885,28 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems.insert(newpos, serviceItem)
self.repaintServiceList(endpos, startCount)
else:
#we are not over anything so drop
replace = False
if item == None:
self.droppos = len(self.serviceItems)
else:
self.droppos = self._getParentItemData(item)
Receiver.send_message(u'%s_add_service_item' % plugin)
#we are over somthing so lets investigate
pos = self._getParentItemData(item) - 1
serviceItem = self.serviceItems[pos]
if plugin == serviceItem[u'service_item'].name \
and serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsAdditions):
action = self.dndMenu.exec_(QtGui.QCursor.pos())
#New action required
if action == self.newAction:
self.droppos = self._getParentItemData(item)
#Append to existing action
if action == self.addToAction:
self.droppos = self._getParentItemData(item)
item.setSelected(True)
replace = True
else:
self.droppos = self._getParentItemData(item)
Receiver.send_message(u'%s_add_service_item' % plugin, replace)
def updateThemeList(self, theme_list):
"""
@ -832,3 +947,20 @@ class ServiceManager(QtGui.QWidget):
return item.data(0, QtCore.Qt.UserRole).toInt()[0]
else:
return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
def listRequest(self, message=None):
data = []
curindex, count = self.findServiceItem()
if curindex >= 0 and curindex < len(self.serviceItems):
curitem = self.serviceItems[curindex]
else:
curitem = None
for item in self.serviceItems:
service_item = item[u'service_item']
data_item = {}
data_item[u'title'] = unicode(service_item.title)
data_item[u'plugin'] = unicode(service_item.name)
data_item[u'notes'] = unicode(service_item.notes)
data_item[u'selected'] = (item == curitem)
data.append(data_item)
Receiver.send_message(u'servicemanager_list_response', data)

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_ServiceNoteEdit(object):
def setupUi(self, ServiceNoteEdit):
@ -46,4 +47,4 @@ class Ui_ServiceNoteEdit(object):
QtCore.QMetaObject.connectSlotsByName(ServiceNoteEdit)
def retranslateUi(self, ServiceNoteEdit):
ServiceNoteEdit.setWindowTitle(self.trUtf8('Service Item Notes'))
ServiceNoteEdit.setWindowTitle(translate('ServiceNoteForm', 'Service Item Notes'))

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_SettingsDialog(object):
def setupUi(self, SettingsDialog):
@ -59,4 +60,4 @@ class Ui_SettingsDialog(object):
QtCore.QMetaObject.connectSlotsByName(SettingsDialog)
def retranslateUi(self, SettingsDialog):
SettingsDialog.setWindowTitle(self.trUtf8('Settings'))
SettingsDialog.setWindowTitle(translate('SettingsForm', 'Settings'))

View File

@ -27,22 +27,25 @@ import logging
from PyQt4 import QtGui
from openlp.core.ui import GeneralTab, ThemesTab
from openlp.core.ui import GeneralTab, ThemesTab, DisplayTab
from settingsdialog import Ui_SettingsDialog
log = logging.getLogger(__name__)
class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
def __init__(self, screen_list, mainWindow, parent=None):
def __init__(self, screens, mainWindow, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
# General tab
self.GeneralTab = GeneralTab(screen_list)
self.GeneralTab = GeneralTab(screens)
self.addTab(u'General', self.GeneralTab)
# Themes tab
self.ThemesTab = ThemesTab(mainWindow)
self.addTab(u'Themes', self.ThemesTab)
# Display tab
self.DisplayTab = DisplayTab(screens)
self.addTab(u'Display', self.DisplayTab)
def addTab(self, name, tab):
log.info(u'Adding %s tab' % tab.tabTitle)

View File

@ -30,20 +30,30 @@ import os
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
class HideMode(object):
"""
This is basically an enumeration class which specifies the mode of a Bible.
Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to
be downloaded from the Internet on an as-needed basis.
"""
Blank = 1
Theme = 2
from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \
PluginConfig, resize_image
from openlp.core.ui import HideMode
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities
log = logging.getLogger(__name__)
class SlideThread(QtCore.QThread):
"""
A special Qt thread class to speed up the display of text based frames.
This is threaded so it loads the frames in background
"""
def __init__(self, parent, prefix, count):
QtCore.QThread.__init__(self, parent)
self.prefix = prefix
self.count = count
def run(self):
"""
Run the thread.
"""
time.sleep(1)
for i in range(0, self.count):
Receiver.send_message(u'%s_slide_cache' % self.prefix, i)
class SlideList(QtGui.QTableWidget):
"""
Customised version of QTableWidget which can respond to keyboard
@ -52,11 +62,12 @@ class SlideList(QtGui.QTableWidget):
def __init__(self, parent=None, name=None):
QtGui.QTableWidget.__init__(self, parent.Controller)
self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'}
self.hotkeyMap = {
QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
@ -73,8 +84,8 @@ class SlideList(QtGui.QTableWidget):
elif event.key() == QtCore.Qt.Key_PageDown:
self.parent.onSlideSelectedLast()
event.accept()
elif event.key() in self.hotkey_map and self.parent.isLive:
Receiver.send_message(self.hotkey_map[event.key()])
elif event.key() in self.hotkeyMap and self.parent.isLive:
Receiver.send_message(self.hotkeyMap[event.key()])
event.accept()
event.ignore()
else:
@ -93,20 +104,16 @@ class SlideController(QtGui.QWidget):
self.settingsmanager = settingsmanager
self.isLive = isLive
self.parent = parent
self.songsconfig = PluginConfig(u'Songs')
self.image_list = [
self.mainDisplay = self.parent.displayManager.mainDisplay
self.loopList = [
u'Start Loop',
u'Stop Loop',
u'Loop Separator',
u'Image SpinBox'
]
self.song_edit_list = [
self.songEditList = [
u'Edit Song',
]
if isLive:
self.labelWidth = 20
else:
self.labelWidth = 0
self.timer_id = 0
self.songEdit = False
self.selectedRow = 0
@ -122,11 +129,11 @@ class SlideController(QtGui.QWidget):
if self.isLive:
self.TypeLabel.setText(self.trUtf8('Live'))
self.split = 1
prefix = u'live_slidecontroller'
self.typePrefix = u'live'
else:
self.TypeLabel.setText(self.trUtf8('Preview'))
self.split = 0
prefix = u'preview_slidecontroller'
self.typePrefix = u'preview'
self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.PanelLayout.addWidget(self.TypeLabel)
@ -146,17 +153,18 @@ class SlideController(QtGui.QWidget):
self.ControllerLayout.setMargin(0)
# Controller list view
self.PreviewListWidget = SlideList(self)
self.PreviewListWidget.setColumnCount(2)
self.PreviewListWidget.setColumnCount(1)
self.PreviewListWidget.horizontalHeader().setVisible(False)
self.PreviewListWidget.verticalHeader().setVisible(False)
self.PreviewListWidget.setColumnWidth(1, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, self.Controller.width() - self.labelWidth)
#self.PreviewListWidget.verticalHeader().setVisible(False)
self.PreviewListWidget.setColumnWidth(
0, self.Controller.width())
self.PreviewListWidget.isLive = self.isLive
self.PreviewListWidget.setObjectName(u'PreviewListWidget')
self.PreviewListWidget.setSelectionBehavior(1)
self.PreviewListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers)
self.PreviewListWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.PreviewListWidget.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff)
self.PreviewListWidget.setAlternatingRowColors(True)
self.ControllerLayout.addWidget(self.PreviewListWidget)
# Build the full toolbar
@ -193,8 +201,6 @@ class SlideController(QtGui.QWidget):
self.hideButton = self.Toolbar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png',
self.trUtf8('Hide Screen'), self.onHideDisplay, True)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen)
if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
@ -207,7 +213,7 @@ class SlideController(QtGui.QWidget):
if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Separator')
self.Toolbar.addToolbarButton(
u'Start Loop', u':/media/media_time.png',
u'Start Loop', u':/media/media_time.png',
self.trUtf8('Start continuous loop'), self.onStartLoop)
self.Toolbar.addToolbarButton(
u'Stop Loop', u':/media/media_stop.png',
@ -218,19 +224,36 @@ class SlideController(QtGui.QWidget):
self.Toolbar.addToolbarWidget(
u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(self.trUtf8('s'))
self.DelaySpinBox.setToolTip(self.trUtf8('Delay between slides in seconds'))
self.DelaySpinBox.setToolTip(
self.trUtf8('Delay between slides in seconds'))
self.ControllerLayout.addWidget(self.Toolbar)
#Build a Media ToolBar
self.Mediabar = OpenLPToolbar(self)
self.Mediabar.addToolbarButton(
u'Media Start', u':/slides/media_playback_start.png',
u'Media Start', u':/slides/media_playback_start.png',
self.trUtf8('Start playing media'), self.onMediaPlay)
self.Mediabar.addToolbarButton(
u'Media Pause', u':/slides/media_playback_pause.png',
u'Media Pause', u':/slides/media_playback_pause.png',
self.trUtf8('Start playing media'), self.onMediaPause)
self.Mediabar.addToolbarButton(
u'Media Stop', u':/slides/media_playback_stop.png',
u'Media Stop', u':/slides/media_playback_stop.png',
self.trUtf8('Start playing media'), self.onMediaStop)
if self.isLive:
self.blankButton = self.Mediabar.addToolbarButton(
u'Blank Screen', u':/slides/slide_blank.png',
self.trUtf8('Blank Screen'), self.onBlankDisplay, True)
self.themeButton = self.Mediabar.addToolbarButton(
u'Display Theme', u':/slides/slide_theme.png',
self.trUtf8('Theme Screen'), self.onThemeDisplay, True)
self.hideButton = self.Mediabar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png',
self.trUtf8('Hide Screen'), self.onHideDisplay, True)
if not self.isLive:
self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.seekSlider.setObjectName(u'seekSlider')
self.Mediabar.addToolbarWidget(
u'Seek Slider', self.seekSlider)
self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider')
@ -243,13 +266,15 @@ class SlideController(QtGui.QWidget):
self.SongMenu.setText(self.trUtf8('Go to Verse'))
self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu)
self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'), self.Toolbar))
self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'),
self.Toolbar))
self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
# Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter)
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Label))
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Label))
self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel)
self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken)
self.PreviewFrame.setObjectName(u'PreviewFrame')
@ -294,34 +319,56 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
if isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay)
Receiver.send_message(u'request_spin_delay')
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
self.receiveSpinDelay)
if isLive:
self.Toolbar.makeWidgetsInvisible(self.image_list)
self.Toolbar.makeWidgetsInvisible(self.loopList)
else:
self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
self.Toolbar.makeWidgetsInvisible(self.songEditList)
self.Mediabar.setVisible(False)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'stop_display_loop'), self.onStopLoop)
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
self.onStopLoop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_first' % prefix), self.onSlideSelectedFirst)
QtCore.SIGNAL(u'slidecontroller_%s_first' % self.typePrefix),
self.onSlideSelectedFirst)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_next' % prefix), self.onSlideSelectedNext)
QtCore.SIGNAL(u'slidecontroller_%s_next' % self.typePrefix),
self.onSlideSelectedNext)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_previous' % prefix), self.onSlideSelectedPrevious)
QtCore.SIGNAL(u'slidecontroller_%s_previous' % self.typePrefix),
self.onSlideSelectedPrevious)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_next_noloop' % prefix), self.onSlideSelectedNextNoloop)
QtCore.SIGNAL(u'slidecontroller_%s_next_noloop' % self.typePrefix),
self.onSlideSelectedNextNoloop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_previous_noloop' % prefix),
QtCore.SIGNAL(u'slidecontroller_%s_previous_noloop' %
self.typePrefix),
self.onSlideSelectedPreviousNoloop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_last' % prefix), self.onSlideSelectedLast)
QtCore.SIGNAL(u'slidecontroller_%s_last' % self.typePrefix),
self.onSlideSelectedLast)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_change' % prefix), self.onSlideChange)
QtCore.SIGNAL(u'slidecontroller_%s_change' % self.typePrefix),
self.onSlideChange)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_set' % self.typePrefix),
self.onSlideSelectedIndex)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_blank' % self.typePrefix),
self.onSlideBlank)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.typePrefix),
self.onSlideUnblank)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.typePrefix),
self.onTextRequest)
QtCore.QObject.connect(self.Splitter,
QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.refreshServiceItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_slide_cache' % self.typePrefix), self.slideCache)
def widthChanged(self):
"""
@ -330,8 +377,7 @@ class SlideController(QtGui.QWidget):
"""
width = self.parent.ControlSplitter.sizes()[self.split]
height = width * self.parent.RenderManager.screen_ratio
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
self.PreviewListWidget.setColumnWidth(0, width)
#Sort out image hights (Songs , bibles excluded)
if self.serviceItem and not self.serviceItem.is_text():
for framenumber, frame in enumerate(self.serviceItem.get_frames()):
@ -372,21 +418,20 @@ class SlideController(QtGui.QWidget):
self.Toolbar.setVisible(True)
self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
self.Toolbar.makeWidgetsInvisible(self.image_list)
self.Toolbar.makeWidgetsInvisible(self.loopList)
if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.image_list)
if item.is_song() and \
str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \
and len(self.slideList) > 0:
self.Toolbar.makeWidgetsInvisible(self.loopList)
if QtCore.QSettings().value(
self.parent.songsSettingsSection + u'/show songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
self.Toolbar.makeWidgetsVisible([u'Song Menu'])
elif item.is_image():
#Not sensible to allow loops with 1 frame
if len(item.get_frames()) > 1:
self.Toolbar.makeWidgetsVisible(self.image_list)
elif item.is_media():
if item.is_capable(ItemCapabilities.AllowsLoop) and \
len(item.get_frames()) > 1:
self.Toolbar.makeWidgetsVisible(self.loopList)
if item.is_media():
self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True)
self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio)
#self.volumeSlider.setAudioOutput(self.mainDisplay.videoDisplay.audio)
def enablePreviewToolBar(self, item):
"""
@ -394,9 +439,9 @@ class SlideController(QtGui.QWidget):
"""
self.Toolbar.setVisible(True)
self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
if item.edit_enabled and item.from_plugin:
self.Toolbar.makeWidgetsVisible(self.song_edit_list)
self.Toolbar.makeWidgetsInvisible(self.songEditList)
if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin:
self.Toolbar.makeWidgetsVisible(self.songEditList)
elif item.is_media():
self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True)
@ -454,20 +499,19 @@ class SlideController(QtGui.QWidget):
Loads a ServiceItem into the system from ServiceManager
Display the slide number passed
"""
log.debug(u'processsManagerItem')
log.debug(u'processManagerItem')
self.onStopLoop()
#If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command():
self.onMediaStop()
if serviceItem.is_media():
self.onMediaStart(serviceItem)
elif serviceItem.is_command():
if self.isLive:
blanked = self.blankButton.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), \
[serviceItem.title, serviceItem.get_frame_path(),
serviceItem.get_frame_title(), slideno, self.isLive, blanked])
if self.isLive:
blanked = self.blankButton.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno])
self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at
@ -476,34 +520,37 @@ class SlideController(QtGui.QWidget):
self.serviceItem = serviceItem
self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0)
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
self.PreviewListWidget.setColumnWidth(0, width)
if self.isLive:
self.SongMenu.menu().clear()
row = 0
text = []
for framenumber, frame in enumerate(self.serviceItem.get_frames()):
self.PreviewListWidget.setRowCount(
self.PreviewListWidget.rowCount() + 1)
rowitem = QtGui.QTableWidgetItem()
item = QtGui.QTableWidgetItem()
slide_height = 0
slideHeight = 0
#It is a based Text Render
if self.serviceItem.is_text():
if self.isLive and frame[u'verseTag'] is not None:
if frame[u'verseTag'] is not None:
#only load the slot once
bits = frame[u'verseTag'].split(u':')
tag = None
#If verse handle verse number else tag only
if bits[0] == self.trUtf8('Verse'):
tag = u'%s%s' % (bits[0][0], bits[1][0:] )
row = bits[1][0:]
if bits[0] == self.trUtf8('Verse') or \
bits[0] == self.trUtf8('Chorus'):
tag = u'%s\n%s' % (bits[0][0], bits[1][0:] )
tag1 = u'%s%s' % (bits[0][0], bits[1][0:] )
row = tag
else:
tag = bits[0]
tag1 = tag
row = bits[0][0:1]
if tag not in self.slideList:
self.slideList[tag] = framenumber
self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag),
self.onSongBarHandler)
if self.isLive:
if tag1 not in self.slideList:
self.slideList[tag1] = framenumber
self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag1),
self.onSongBarHandler)
else:
row += 1
item.setText(frame[u'text'])
@ -515,19 +562,18 @@ class SlideController(QtGui.QWidget):
self.parent.RenderManager.height)
label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 1, label)
slide_height = width * self.parent.RenderManager.screen_ratio
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
slideHeight = width * self.parent.RenderManager.screen_ratio
row += 1
rowitem.setText(unicode(row))
self.PreviewListWidget.setItem(framenumber, 0, rowitem)
self.PreviewListWidget.setItem(framenumber, 1, item)
if slide_height != 0:
self.PreviewListWidget.setRowHeight(framenumber, slide_height)
text.append(unicode(row))
self.PreviewListWidget.setItem(framenumber, 0, item)
if slideHeight != 0:
self.PreviewListWidget.setRowHeight(framenumber, slideHeight)
self.PreviewListWidget.setVerticalHeaderLabels(text)
if self.serviceItem.is_text():
self.PreviewListWidget.resizeRowsToContents()
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1,
self.PreviewListWidget.viewport().size().width() - self.labelWidth )
self.PreviewListWidget.setColumnWidth(0,
self.PreviewListWidget.viewport().size().width())
if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
else:
@ -535,9 +581,33 @@ class SlideController(QtGui.QWidget):
self.enableToolBar(serviceItem)
self.onSlideSelected()
self.PreviewListWidget.setFocus()
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem])
if self.serviceItem.is_text():
st = SlideThread(
self, self.typePrefix, len(self.serviceItem.get_frames()))
st.start()
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()):
dataItem = {}
if self.serviceItem.is_text():
dataItem[u'tag'] = unicode(frame[u'verseTag'])
dataItem[u'text'] = unicode(frame[u'text'])
else:
dataItem[u'tag'] = unicode(framenumber)
dataItem[u'text'] = u''
dataItem[u'selected'] = \
(self.PreviewListWidget.currentRow() == framenumber)
data.append(dataItem)
Receiver.send_message(u'slidecontroller_%s_text_response'
% self.typePrefix, data)
#Screen event methods
def onSlideSelectedFirst(self):
@ -546,60 +616,120 @@ class SlideController(QtGui.QWidget):
"""
if not self.serviceItem:
return
Receiver.send_message(u'%s_first' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
Receiver.send_message(u'%s_first'% \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview()
else:
self.PreviewListWidget.selectRow(0)
self.onSlideSelected()
def onBlankDisplay(self, force=False):
def onSlideSelectedIndex(self, message):
"""
Go to the requested slide
"""
index = int(message[0])
if not self.serviceItem:
return
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, index])
if self.serviceItem.is_command():
self.updatePreview()
else:
self.PreviewListWidget.selectRow(index)
self.onSlideSelected()
def onSlideBlank(self):
"""
Handle the slidecontroller blank event
"""
self.onBlankDisplay(True)
def onSlideUnblank(self):
"""
Handle the slidecontroller unblank event
"""
self.onBlankDisplay(False)
def onBlankDisplay(self, checked):
"""
Handle the blank screen button
"""
log.debug(u'onBlankDisplay %d' % force)
if force:
self.blankButton.setChecked(True)
self.blankScreen(HideMode.Blank, self.blankButton.isChecked())
self.parent.generalConfig.set_config(u'screen blank',
self.blankButton.isChecked())
log.debug(u'onBlankDisplay %d' % checked)
self.hideButton.setChecked(False)
self.themeButton.setChecked(False)
QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(checked))
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
self.blankPlugin(True)
else:
Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False)
def onThemeDisplay(self, force=False):
def onThemeDisplay(self, checked):
"""
Handle the Theme screen button
"""
log.debug(u'onThemeDisplay %d' % force)
if force:
self.themeButton.setChecked(True)
self.blankScreen(HideMode.Theme, self.themeButton.isChecked())
log.debug(u'onThemeDisplay %d' % checked)
self.blankButton.setChecked(False)
self.hideButton.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
self.blankPlugin(True)
else:
Receiver.send_message(u'maindisplay_show')
self.blankPlugin(False)
def onHideDisplay(self, force=False):
def onHideDisplay(self, checked):
"""
Handle the Hide screen button
"""
log.debug(u'onHideDisplay %d' % force)
if force:
self.themeButton.setChecked(True)
if self.hideButton.isChecked():
self.parent.mainDisplay.hideDisplay()
log.debug(u'onHideDisplay %d' % checked)
self.blankButton.setChecked(False)
self.themeButton.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.hidePlugin(True)
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.
"""
if self.serviceItem is not None:
if self.serviceItem.is_command():
if blanked:
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower())
else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
if blank:
Receiver.send_message(u'%s_blank'
% self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
else:
self.parent.mainDisplay.blankDisplay(blankType, blanked)
else:
self.parent.mainDisplay.blankDisplay(blankType, blanked)
Receiver.send_message(u'%s_unblank'
% self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
def 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 slideCache(self, slide):
"""
Generate a slide cache item rendered and ready for use
in the background.
"""
self.serviceItem.get_rendered_frame(int(slide))
def onSlideSelected(self):
"""
@ -609,9 +739,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow()
self.selectedRow = 0
if row > -1 and row < self.PreviewListWidget.rowCount():
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, row])
if self.serviceItem.is_command() and self.isLive:
Receiver.send_message(u'%s_slide'% \
self.serviceItem.name.lower(), u'%s:%s' % (row, self.isLive))
self.updatePreview()
else:
before = time.time()
@ -620,13 +750,18 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
else:
if isinstance(frame[u'main'], basestring):
self.SlidePreview.setPixmap(QtGui.QPixmap(frame[u'main']))
self.SlidePreview.setPixmap(
QtGui.QPixmap(frame[u'main']))
else:
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
log.log(15, u'Slide Rendering took %4s' % (time.time() - before))
self.SlidePreview.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main']))
log.log(
15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive:
self.parent.mainDisplay.frameView(frame, True)
self.mainDisplay.frameView(frame, True)
self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)
def onSlideChange(self, row):
"""
@ -634,6 +769,8 @@ class SlideController(QtGui.QWidget):
"""
self.PreviewListWidget.selectRow(row)
self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)
def updatePreview(self):
rm = self.parent.RenderManager
@ -663,9 +800,9 @@ class SlideController(QtGui.QWidget):
"""
if not self.serviceItem:
return
Receiver.send_message(u'%s_next' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
Receiver.send_message(u'%s_next' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview()
else:
row = self.PreviewListWidget.currentRow() + 1
@ -687,9 +824,9 @@ class SlideController(QtGui.QWidget):
"""
if not self.serviceItem:
return
Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
Receiver.send_message(
u'%s_previous'% self.serviceItem.name.lower(), self.isLive)
self.updatePreview()
else:
row = self.PreviewListWidget.currentRow() - 1
@ -707,9 +844,9 @@ class SlideController(QtGui.QWidget):
"""
if not self.serviceItem:
return
Receiver.send_message(u'%s_last' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
Receiver.send_message(u'%s_last' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview()
else:
self.PreviewListWidget.selectRow(
@ -728,7 +865,9 @@ class SlideController(QtGui.QWidget):
"""
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):
"""
@ -738,9 +877,12 @@ class SlideController(QtGui.QWidget):
self.onSlideSelectedNext()
def onEditSong(self):
"""
From the preview display requires the service Item to be editied
"""
self.songEdit = True
Receiver.send_message(u'%s_edit' % self.serviceItem.name, u'P:%s' %
self.serviceItem.editId )
Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
u'P:%s' % self.serviceItem.editId)
def onGoLive(self):
"""
@ -752,34 +894,51 @@ class SlideController(QtGui.QWidget):
self.serviceItem, row)
def onMediaStart(self, item):
"""
Respond to the arrival of a media service item
"""
log.debug(u'SlideController onMediaStart')
if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \
[item.title, item.get_frame_path(),
item.get_frame_title(), self.isLive, self.blankButton.isChecked()])
Receiver.send_message(u'videodisplay_start',
[item, self.blankButton.isChecked()])
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
file = os.path.join(item.service_item_path, item.get_frame_title())
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.seekSlider.setMediaObject(self.mediaObject)
self.seekSlider.show()
self.onMediaPlay()
def onMediaPause(self):
"""
Respond to the Pause from the media Toolbar
"""
log.debug(u'SlideController onMediaPause')
if self.isLive:
Receiver.send_message(u'%s_pause'% self.serviceItem.name.lower())
Receiver.send_message(u'videodisplay_pause')
else:
self.mediaObject.pause()
def onMediaPlay(self):
"""
Respond to the Play from the media Toolbar
"""
log.debug(u'SlideController onMediaPlay')
if self.isLive:
Receiver.send_message(u'%s_play'% self.serviceItem.name.lower(), self.isLive)
Receiver.send_message(u'videodisplay_play')
else:
self.SlidePreview.hide()
self.video.show()
self.mediaObject.play()
def onMediaStop(self):
"""
Respond to the Stop from the media Toolbar
"""
log.debug(u'SlideController onMediaStop')
if self.isLive:
Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive)
Receiver.send_message(u'videodisplay_stop')
else:
self.mediaObject.stop()
self.video.hide()

View File

@ -1,160 +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 sys
import os
import os.path
import logging
from PyQt4 import QtGui
from openlp.core.ui import ServiceManager
from openlp.plugins.images.lib import ImageServiceItem
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..', '..')))
logging.basicConfig(filename='test_service_manager.log', level=logging.INFO,
filemode='w')
# # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
# def whoami(depth=1):
# return sys._getframe(depth).f_code.co_name
global app
global log
log = logging.getLogger(u'TestServiceManager')
class TestServiceManager_base:
def __init__(self):
pass
def setup_class(self):
log.info( "class setup" + unicode(self))
try:
if app is None:
app = QtGui.QApplication([])
except UnboundLocalError:
app = QtGui.QApplication([])
def teardown_class(self):
pass
def setup_method(self, method):
log.info(u'Setup method:' + unicode(method))
self.expected_answer = "Don't know yet"
self.answer = None
self.s = ServiceManager(None)
log.info(u'--------------- Setup Done -------------')
def teardown_method(self, method):
self.s = None
def select_row(self, row):
# now select the line we just added
# first get the index
i = QModelIndex(self.s.service_data.index(0,0))
# make a selection of it
self.sm = QItemSelectionModel(self.s.service_data)
self.sm.select(i, QItemSelectionModel.ClearAndSelect)
log.info(unicode(self.sm.selectedIndexes()))
self.s.TreeView.setSelectionModel(self.sm)
log.info(u'Selected indexes = ' + unicode(
self.s.TreeView.selectedIndexes()))
def test_easy(self):
log.info(u'test_easy')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
log.info(u'done')
def test_2items_as_separate_items(self):
# If nothing is selected when item is added, a new base service item
# is added
log.info(u'test_2items_as_separate_items')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
item = ImageServiceItem(None)
item.add(u'test2.gif')
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[3] == "test2.gif"
assert lines[4] == "test3.gif"
log.info(u'done')
def test_2items_merged(self):
# If the first object is selected when item is added it should be
# extended
log.info(u'test_2items_merged')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
self.select_row(0)
log.info(u'Selected indexes = ' + unicode(
self.s.TreeView.selectedIndexes()))
item = ImageServiceItem(None)
item.add(u'test2.gif')
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2] == "test2.gif"
assert lines[3] == "test3.gif"
log.info(u'done')
# more tests to do:
# add different types of service item
# move up, down
# move to top, bottom
# new and save as
# deleting items
if __name__ == "__main__":
t=TestServiceManager_base()
t.setup_class()
t.setup_method(None)
t.test_easy()
t.teardown_method(None)
print "Pass"
log.info(u'Pass')

View File

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

View File

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

View File

@ -43,9 +43,10 @@ class AppLocation(object):
ConfigDir = 2
DataDir = 3
PluginsDir = 4
VersionDir = 5
@staticmethod
def get_directory(dir_type):
def get_directory(dir_type=1):
"""
Return the appropriate directory according to the directory type.
@ -63,7 +64,8 @@ class AppLocation(object):
else:
try:
from xdg import BaseDirectory
path = os.path.join(BaseDirectory.xdg_config_home, u'openlp')
path = os.path.join(
BaseDirectory.xdg_config_home, u'openlp')
except ImportError:
path = os.path.join(os.getenv(u'HOME'), u'.openlp')
return path
@ -83,39 +85,57 @@ class AppLocation(object):
elif dir_type == AppLocation.PluginsDir:
plugin_path = None
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
if sys.platform == u'win32':
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.join(app_path, u'plugins')
else:
plugin_path = os.path.join(app_path, u'openlp', u'plugins')
elif sys.platform == u'darwin':
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.join(app_path, u'plugins')
else:
plugin_path = os.path.join(
os.path.split(openlp.__file__)[0], u'plugins')
return plugin_path
elif dir_type == AppLocation.VersionDir:
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.abspath(os.path.split(sys.argv[0])[0])
else:
plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path
@staticmethod
def get_data_path():
path = AppLocation.get_directory(AppLocation.DataDir)
if not os.path.exists(path):
os.makedirs(path)
return path
@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(config, current_version):
def check_latest_version(current_version):
"""
Check the latest version of OpenLP against the version file on the OpenLP
site.
``config``
The OpenLP config object.
``current_version``
The current version of OpenLP.
"""
version_string = current_version[u'full']
#set to prod in the distribution confif file.
last_test = config.get_config(u'last version test', datetime.now().date())
#set to prod in the distribution config file.
settings = QtCore.QSettings()
settings.beginGroup(u'general')
last_test = unicode(settings.value(u'last version test',
QtCore.QVariant(datetime.now().date())).toString())
this_test = unicode(datetime.now().date())
config.set_config(u'last version test', this_test)
settings.setValue(u'last version test', QtCore.QVariant(this_test))
settings.endGroup()
if last_test != this_test:
version_string = u''
if current_version[u'build']:
req = urllib2.Request(u'http://www.openlp.org/files/dev_version.txt')
req = urllib2.Request(
u'http://www.openlp.org/files/dev_version.txt')
else:
req = urllib2.Request(u'http://www.openlp.org/files/version.txt')
req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full'])
@ -147,7 +167,23 @@ def variant_to_unicode(variant):
string = string_to_unicode(string)
return string
from registry import Registry
from confighelper import ConfigHelper
def add_actions(target, actions):
"""
Adds multiple actions to a menu or toolbar in one command.
__all__ = [u'Registry', u'ConfigHelper', u'AppLocation', u'check_latest_version']
``target``
The menu or toolbar to add actions to.
``actions``
The actions to be added. An action consisting of the keyword 'None'
will result in a separator being inserted into the target.
"""
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
from languagemanager import LanguageManager
__all__ = [u'AppLocation', u'check_latest_version', u'add_actions', u'LanguageManager']

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

@ -0,0 +1,111 @@
# -*- 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
from PyQt4 import QtCore, QtGui
from openlp.core.utils import AppLocation
from openlp.core.lib import translate
log = logging.getLogger()
class LanguageManager(object):
"""
Helper for Language selection
"""
__qmList__ = None
AutoLanguage = False
@staticmethod
def get_translator(language):
if LanguageManager.AutoLanguage :
language = QtCore.QLocale.system().name()
lang_Path = AppLocation.get_directory(AppLocation.AppDir)
lang_Path = os.path.join(lang_Path, u'resources', u'i18n')
appTranslator = QtCore.QTranslator()
if appTranslator.load("openlp_" + language, lang_Path):
return appTranslator
@staticmethod
def find_qm_files():
trans_dir = AppLocation.get_directory(AppLocation.AppDir)
trans_dir = QtCore.QDir(os.path.join(trans_dir, u'resources', u'i18n'))
fileNames = trans_dir.entryList(QtCore.QStringList("*.qm"),
QtCore.QDir.Files, QtCore.QDir.Name)
for i in fileNames:
fileNames.replaceInStrings(i, trans_dir.filePath(i))
return fileNames
@staticmethod
def language_name(qmFile):
translator = QtCore.QTranslator()
translator.load(qmFile)
return translator.translate(u'MainWindow', u'English')
@staticmethod
def get_language():
settings = QtCore.QSettings(u'OpenLP', u'OpenLP')
language = unicode(settings.value(
u'general/language', QtCore.QVariant(u'[en]')).toString())
log.info(u'Language file: \'%s\' Loaded from conf file' % language)
regEx = QtCore.QRegExp("^\[(.*)\]")
if regEx.exactMatch(language):
LanguageManager.AutoLanguage = True
language = regEx.cap(1)
return language
@staticmethod
def set_language(action):
actionName = u'%s' % action.objectName()
qmList = LanguageManager.get_qm_list()
if LanguageManager.AutoLanguage :
language = u'[%s]' % qmList[actionName]
else:
language = u'%s' % qmList[actionName]
QtCore.QSettings().setValue(
u'general/language', QtCore.QVariant(language))
log.info(u'Language file: \'%s\' written to conf file' % language)
QtGui.QMessageBox.information(None,
translate('LanguageManager', 'Language'),
translate('LanguageManager',
'After restart new Language settings will be used.'))
@staticmethod
def init_qm_list():
LanguageManager.__qmList__ = {}
qmFiles = LanguageManager.find_qm_files()
for i, qmf in enumerate(qmFiles):
regEx = QtCore.QRegExp("^.*openlp_(.*).qm")
if regEx.exactMatch(qmf):
langName = regEx.cap(1)
LanguageManager.__qmList__[u'%#2i %s' % (i+1,
LanguageManager.language_name(qmf))] = langName
@staticmethod
def get_qm_list():
if LanguageManager.__qmList__ == None:
LanguageManager.init_qm_list()
return LanguageManager.__qmList__

View File

@ -1,130 +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, key)
def get_value(self, section, key, default=None):
"""
Get a single value from the registry.
"""
try:
if self.config.get(section, key):
return self.config.get(section, key)
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, key, unicode(value))
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, key)
return self._save()
except:
return False
def has_section(self, section):
"""
Check if a section exists.
"""
return self.config.has_section(section)
def create_section(self, section):
"""
Create a new section in the registry.
"""
try:
self.config.add_section(section)
return self._save()
except:
return False
def delete_section(self, section):
"""
Delete a section (including all values).
"""
try:
self.config.remove_section(section)
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.orm import scoped_session, sessionmaker, mapper
from openlp.core.lib import PluginConfig
from openlp.core.lib import SettingsManager
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.models import *
class BaseModel(object):
@ -111,9 +112,8 @@ def init_models(url):
class MigrateBibles():
def __init__(self, display):
self.display = display
self.config = PluginConfig(u'Bibles')
self.data_path = self.config.get_data_path()
self.database_files = self.config.get_files(u'sqlite')
self.data_path = AppLocation.get_section_data_path(u'bibles')
self.database_files = SettingsManager.get_files(u'bibles', u'.sqlite')
print self.database_files
def progress(self, text):

View File

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

View File

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

View File

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

View File

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

View File

@ -24,64 +24,123 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_AlertDialog(object):
def setupUi(self, AlertForm):
AlertForm.setObjectName(u'AlertDialog')
AlertForm.resize(430, 320)
def setupUi(self, AlertDialog):
AlertDialog.setObjectName(u'AlertDialog')
AlertDialog.resize(567, 440)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
AlertForm.setWindowIcon(icon)
self.AlertFormLayout = QtGui.QVBoxLayout(AlertForm)
self.AlertFormLayout.setSpacing(8)
self.AlertFormLayout.setMargin(8)
self.AlertFormLayout.setObjectName(u'AlertFormLayout')
self.AlertEntryWidget = QtGui.QWidget(AlertForm)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.AlertEntryWidget.sizePolicy().hasHeightForWidth())
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)
AlertDialog.setWindowIcon(icon)
self.AlertDialogLayout = QtGui.QVBoxLayout(AlertDialog)
self.AlertDialogLayout.setSpacing(8)
self.AlertDialogLayout.setMargin(8)
self.AlertDialogLayout.setObjectName(u'AlertDialogLayout')
self.AlertTextLayout = QtGui.QFormLayout()
self.AlertTextLayout.setContentsMargins(0, 0, -1, -1)
self.AlertTextLayout.setSpacing(8)
self.AlertTextLayout.setObjectName(u'AlertTextLayout')
self.AlertEntryLabel = QtGui.QLabel(AlertDialog)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.AlertEntryLabel.sizePolicy().hasHeightForWidth())
self.AlertEntryLabel.setSizePolicy(sizePolicy)
self.AlertEntryLabel.setObjectName(u'AlertEntryLabel')
self.verticalLayout.addWidget(self.AlertEntryLabel)
self.AlertEntryEditItem = QtGui.QLineEdit(self.AlertEntryWidget)
self.AlertEntryEditItem.setObjectName(u'AlertEntryEditItem')
self.verticalLayout.addWidget(self.AlertEntryEditItem)
self.AlertListWidget = QtGui.QListWidget(self.AlertEntryWidget)
self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.AlertEntryLabel)
self.AlertParameter = QtGui.QLabel(AlertDialog)
self.AlertParameter.setObjectName(u'AlertParameter')
self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.AlertParameter)
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.AlertDialogLayout.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.setObjectName(u'AlertListWidget')
self.verticalLayout.addWidget(self.AlertListWidget)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
spacerItem = QtGui.QSpacerItem(181, 38, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.DisplayButton = QtGui.QPushButton(self.AlertEntryWidget)
self.ManagementLayout.addWidget(self.AlertListWidget)
self.ManageButtonLayout = QtGui.QVBoxLayout()
self.ManageButtonLayout.setSpacing(8)
self.ManageButtonLayout.setObjectName(u'ManageButtonLayout')
self.NewButton = QtGui.QPushButton(AlertDialog)
icon1 = QtGui.QIcon()
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.AlertDialogLayout.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.horizontalLayout.addWidget(self.DisplayButton)
self.CancelButton = QtGui.QPushButton(self.AlertEntryWidget)
self.CancelButton.setObjectName(u'CancelButton')
self.horizontalLayout.addWidget(self.CancelButton)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.AlertFormLayout.addWidget(self.AlertEntryWidget)
self.AlertButtonLayout.addWidget(self.DisplayButton)
self.DisplayCloseButton = QtGui.QPushButton(AlertDialog)
self.DisplayCloseButton.setIcon(icon4)
self.DisplayCloseButton.setObjectName(u'DisplayCloseButton')
self.AlertButtonLayout.addWidget(self.DisplayCloseButton)
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.AlertDialogLayout.addLayout(self.AlertButtonLayout)
self.AlertEntryLabel.setBuddy(self.AlertTextEdit)
self.AlertParameter.setBuddy(self.ParameterEdit)
self.retranslateUi(AlertForm)
QtCore.QObject.connect(self.CancelButton, QtCore.SIGNAL(u'clicked()'), self.close)
QtCore.QMetaObject.connectSlotsByName(AlertForm)
self.retranslateUi(AlertDialog)
QtCore.QObject.connect(self.CloseButton, QtCore.SIGNAL(u'clicked()'), AlertDialog.close)
QtCore.QMetaObject.connectSlotsByName(AlertDialog)
AlertDialog.setTabOrder(self.AlertTextEdit, self.ParameterEdit)
AlertDialog.setTabOrder(self.ParameterEdit, self.AlertListWidget)
AlertDialog.setTabOrder(self.AlertListWidget, self.NewButton)
AlertDialog.setTabOrder(self.NewButton, self.SaveButton)
AlertDialog.setTabOrder(self.SaveButton, self.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(translate('AlertForm', 'Alert Message'))
self.AlertEntryLabel.setText(translate('AlertForm', 'Alert &text:'))
self.AlertParameter.setText(translate('AlertForm', '&Parameter(s):'))
self.NewButton.setText(translate('AlertForm', '&New'))
self.SaveButton.setText(translate('AlertForm', '&Save'))
self.DeleteButton.setText(translate('AlertForm', '&Delete'))
self.DisplayButton.setText(translate('AlertForm', 'Displ&ay'))
self.DisplayCloseButton.setText(translate('AlertForm', 'Display && Cl&ose'))
self.CloseButton.setText(translate('AlertForm', '&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.parent = parent
self.history_required = True
self.item_id = None
QtGui.QDialog.__init__(self, None)
self.setupUi(self)
QtCore.QObject.connect(self.DisplayButton,
QtCore.SIGNAL(u'clicked()'),
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&)'),
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.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onDoubleClick)
@ -60,20 +72,57 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
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.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
def onDisplayClicked(self):
self.triggerAlert(unicode(self.AlertEntryEditItem.text()))
if self.parent.alertsTab.save_history and self.history_required:
if self.triggerAlert(unicode(self.AlertTextEdit.text())):
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.text = unicode(self.AlertEntryEditItem.text())
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
self.history_required = False
self.AlertTextEdit.setText(u'')
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):
#Data has changed by editing it so potential storage
self.history_required = True
#Data has changed by editing it so potential storage required
self.SaveButton.setEnabled(True)
def onDoubleClick(self):
"""
@ -83,7 +132,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
for item in items:
bitem = self.AlertListWidget.item(item.row())
self.triggerAlert(bitem.text())
self.history_required = False
self.AlertTextEdit.setText(bitem.text())
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(True)
def onSingleClick(self):
"""
@ -93,8 +145,14 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
items = self.AlertListWidget.selectedIndexes()
for item in items:
bitem = self.AlertListWidget.item(item.row())
self.AlertEntryEditItem.setText(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 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 alertstab import AlertsTab
from manager import DBManager

View File

@ -40,21 +40,20 @@ class AlertsManager(QtCore.QObject):
def __init__(self, parent):
QtCore.QObject.__init__(self)
self.parent = parent
self.screen = None
self.timer_id = 0
self.alertList = []
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'flush_alert'), self.generateAlert)
QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'alert_text'), self.displayAlert)
QtCore.SIGNAL(u'alerts_text'), self.onAlertText)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'screen_changed'), self.screenChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.screenChanged)
QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
def screenChanged(self):
log.debug(u'screen changed')
self.screen = self.parent.maindisplay.screen
self.alertTab = self.parent.alertsTab
self.screen = self.parent.maindisplay.screens.current
self.font = QtGui.QFont()
self.font.setFamily(self.alertTab.font_face)
self.font.setBold(True)
@ -64,10 +63,23 @@ class AlertsManager(QtCore.QObject):
if self.alertTab.location == 0:
self.alertScreenPosition = 0
else:
self.alertScreenPosition = self.screen[u'size'].height() - self.alertHeight
self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition
self.parent.maindisplay.setAlertSize(self.alertScreenPosition, self.alertHeight)
self.alertScreenPosition = self.screen[u'size'].height() \
- self.alertHeight
self.alertHeight = self.screen[u'size'].height() \
- self.alertScreenPosition
self.parent.maindisplay.setAlertSize(self.alertScreenPosition,\
self.alertHeight)
def onAlertText(self, message):
"""
Called via a alerts_text event. Message is single element array
containing text
"""
if message:
self.displayAlert(message[0])
else:
self.displayAlert(u'')
def displayAlert(self, text=u''):
"""
Called from the Alert Tab to display an alert
@ -76,12 +88,14 @@ class AlertsManager(QtCore.QObject):
display text
"""
log.debug(u'display alert called %s' % text)
self.parent.maindisplay.parent.StatusBar.showMessage(u'')
if not self.screen:
self.screenChanged()
self.alertList.append(text)
if self.timer_id != 0 or self.parent.maindisplay.mediaLoaded:
self.parent.maindisplay.parent.StatusBar.showMessage(\
self.trUtf8(u'Alert message created and delayed'))
if self.timer_id != 0:
Receiver.send_message(u'maindisplay_status_text',
self.trUtf8(u'Alert message created and delayed'))
return
Receiver.send_message(u'maindisplay_status_text', u'')
self.generateAlert()
def generateAlert(self):
@ -113,6 +127,7 @@ class AlertsManager(QtCore.QObject):
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event):
log.debug(u'timer event')
if event.timerId() == self.timer_id:
self.parent.maindisplay.addAlertImage(None, True)
self.killTimer(self.timer_id)

View File

@ -25,17 +25,16 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool
from openlp.plugins.alerts.lib.models import AlertItem
from openlp.core.lib import SettingsTab
class AlertsTab(SettingsTab):
"""
AlertsTab is the alerts settings tab in the settings dialog.
"""
def __init__(self, parent, section=None):
def __init__(self, parent):
self.parent = parent
self.manager = parent.manager
SettingsTab.__init__(self, parent.name, section)
SettingsTab.__init__(self, parent.name)
def setupUi(self):
self.setObjectName(u'AlertsTab')
@ -135,22 +134,6 @@ class AlertsTab(SettingsTab):
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.LocationLayout.addItem(self.LocationSpacer)
self.FontLayout.addWidget(self.LocationWidget)
self.HistoryWidget = QtGui.QWidget(self.FontGroupBox)
self.HistoryWidget.setObjectName(u'HistoryWidget')
self.HistoryLayout = QtGui.QHBoxLayout(self.HistoryWidget)
self.HistoryLayout.setSpacing(8)
self.HistoryLayout.setMargin(0)
self.HistoryLayout.setObjectName(u'HistoryLayout')
self.HistoryLabel = QtGui.QLabel(self.HistoryWidget)
self.HistoryLabel.setObjectName(u'HistoryLabel')
self.HistoryLayout.addWidget(self.HistoryLabel)
self.HistoryCheckBox = QtGui.QCheckBox(self.HistoryWidget)
self.HistoryCheckBox.setObjectName(u'HistoryCheckBox')
self.HistoryLayout.addWidget(self.HistoryCheckBox)
self.HistorySpacer = QtGui.QSpacerItem(147, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.HistoryLayout.addItem(self.HistorySpacer)
self.FontLayout.addWidget(self.HistoryWidget)
self.SlideLeftLayout.addWidget(self.FontGroupBox)
self.SlideLeftSpacer = QtGui.QSpacerItem(20, 94,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
@ -187,48 +170,8 @@ class AlertsTab(SettingsTab):
self.SlideRightSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
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)
# Signals and slots
QtCore.QObject.connect(self.HistoryCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onHistoryCheckBoxChanged)
QtCore.QObject.connect(self.BackgroundColorButton,
QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
QtCore.QObject.connect(self.FontColorButton,
@ -241,27 +184,6 @@ class AlertsTab(SettingsTab):
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
QtCore.QObject.connect(self.FontSizeSpinBox,
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):
self.FontGroupBox.setTitle(self.trUtf8('Font'))
@ -273,16 +195,10 @@ class AlertsTab(SettingsTab):
self.TimeoutLabel.setText(self.trUtf8('Alert timeout:'))
self.TimeoutSpinBox.setSuffix(self.trUtf8('s'))
self.LocationLabel.setText(self.trUtf8('Location:'))
self.HistoryLabel.setText(self.trUtf8('Keep History:'))
self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))
self.FontPreview.setText(self.trUtf8('openlp.org'))
self.LocationComboBox.setItemText(0, self.trUtf8('Top'))
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):
self.bg_color = QtGui.QColorDialog.getColor(
@ -297,12 +213,6 @@ class AlertsTab(SettingsTab):
def onLocationComboBoxClicked(self, location):
self.location = location
def onHistoryCheckBoxChanged(self, check_state):
self.save_history = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
self.save_history = True
def onFontColorButtonClicked(self):
self.font_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.font_color), self).name()
@ -318,17 +228,20 @@ class AlertsTab(SettingsTab):
self.updateDisplay()
def load(self):
self.timeout = int(self.config.get_config(u'timeout', 5))
self.font_color = unicode(
self.config.get_config(u'font color', u'#ffffff'))
self.font_size = int(self.config.get_config(u'font size', 40))
self.bg_color = unicode(
self.config.get_config(u'background color', u'#660000'))
self.font_face = unicode(
self.config.get_config(u'font face', QtGui.QFont().family()))
self.location = int(self.config.get_config(u'location', 0))
self.save_history = str_to_bool(
self.config.get_config(u'save history', u'False'))
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
self.timeout = settings.value(u'timeout', QtCore.QVariant(5)).toInt()[0]
self.font_color = unicode(settings.value(
u'font color', QtCore.QVariant(u'#ffffff')).toString())
self.font_size = settings.value(
u'font size', QtCore.QVariant(40)).toInt()[0]
self.bg_color = unicode(settings.value(
u'background color', QtCore.QVariant(u'#660000')).toString())
self.font_face = unicode(settings.value(
u'font face', QtCore.QVariant(QtGui.QFont().family())).toString())
self.location = settings.value(
u'location', QtCore.QVariant(0)).toInt()[0]
settings.endGroup()
self.FontSizeSpinBox.setValue(self.font_size)
self.TimeoutSpinBox.setValue(self.timeout)
self.FontColorButton.setStyleSheet(
@ -336,91 +249,27 @@ class AlertsTab(SettingsTab):
self.BackgroundColorButton.setStyleSheet(
u'background-color: %s' % self.bg_color)
self.LocationComboBox.setCurrentIndex(self.location)
self.HistoryCheckBox.setChecked(self.save_history)
font = QtGui.QFont()
font.setFamily(self.font_face)
self.FontComboBox.setCurrentFont(font)
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):
self.EditButton.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):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
self.font_face = self.FontComboBox.currentFont().family()
self.config.set_config(u'background color', unicode(self.bg_color))
self.config.set_config(u'font color', unicode(self.font_color))
self.config.set_config(u'font size', unicode(self.font_size))
self.config.set_config(u'font face', unicode(self.font_face))
self.config.set_config(u'timeout', unicode(self.timeout))
self.config.set_config(u'location',
unicode(self.LocationComboBox.currentIndex()))
self.config.set_config(u'save history', unicode(self.save_history))
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
settings.setValue(u'location',
QtCore.QVariant(self.LocationComboBox.currentIndex()))
settings.endGroup()
def updateDisplay(self):
font = QtGui.QFont()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,15 +28,15 @@ import time
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, str_to_bool, \
BaseListWithDnD
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
ItemCapabilities
from openlp.plugins.bibles.forms import ImportWizardForm
log = logging.getLogger(__name__)
class BibleListView(BaseListWithDnD):
"""
Drag and drop capable list for Bibles.
Custom list view descendant, required for drag and drop.
"""
def __init__(self, parent=None):
self.PluginName = u'Bibles'
@ -54,17 +54,15 @@ class BibleMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title):
self.PluginNameShort = u'Bible'
self.ConfigSection = title
self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView
self.servicePath = None
self.lastReference = []
self.addToServiceItem = True
MediaManagerItem.__init__(self, parent, icon, title)
# place to store the search results
self.search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpreloadbibles'), self.reloadBibles)
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
def _decodeQtObject(self, listobj, key):
obj = listobj[QtCore.QString(key)]
@ -258,11 +256,11 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(self.QuickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_showprogress'), self.onSearchProgressShow)
QtCore.SIGNAL(u'bibles_showprogress'), self.onSearchProgressShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_hideprogress'), self.onSearchProgressHide)
QtCore.SIGNAL(u'bibles_hideprogress'), self.onSearchProgressHide)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_nobook'), self.onNoBookFound)
QtCore.SIGNAL(u'bibles_nobook'), self.onNoBookFound)
def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self)
@ -277,8 +275,8 @@ class BibleMediaItem(MediaManagerItem):
self.SearchProgress.setObjectName(u'SearchProgress')
def configUpdated(self):
if str_to_bool(
self.parent.config.get_config(u'dual bibles', u'False')):
if QtCore.QSettings().value(self.settingsSection + u'/dual bibles',
QtCore.QVariant(False)).toBool():
self.AdvancedSecondBibleLabel.setVisible(True)
self.AdvancedSecondBibleComboBox.setVisible(True)
self.QuickSecondVersionLabel.setVisible(True)
@ -323,7 +321,7 @@ class BibleMediaItem(MediaManagerItem):
def setQuickMessage(self, text):
self.QuickMessage.setText(text)
self.AdvancedMessage.setText(text)
Receiver.send_message(u'process_events')
Receiver.send_message(u'openlp_process_events')
#minor delay to get the events processed
time.sleep(0.1)
@ -339,13 +337,14 @@ class BibleMediaItem(MediaManagerItem):
# load bibles into the combo boxes
first = True
for bible in bibles:
self.QuickVersionComboBox.addItem(bible)
self.QuickSecondBibleComboBox.addItem(bible)
self.AdvancedVersionComboBox.addItem(bible)
self.AdvancedSecondBibleComboBox.addItem(bible)
if first:
first = False
self.initialiseBible(bible)
if bible:
self.QuickVersionComboBox.addItem(bible)
self.QuickSecondBibleComboBox.addItem(bible)
self.AdvancedVersionComboBox.addItem(bible)
self.AdvancedSecondBibleComboBox.addItem(bible)
if first:
first = False
self.initialiseBible(bible)
def onListViewResize(self, width, height):
self.SearchProgress.setGeometry(self.ListView.geometry().x(),
@ -354,7 +353,7 @@ class BibleMediaItem(MediaManagerItem):
def onSearchProgressShow(self):
self.SearchProgress.setVisible(True)
Receiver.send_message(u'process_events')
Receiver.send_message(u'openlp_process_events')
#self.SearchProgress.setMinimum(0)
#self.SearchProgress.setMaximum(2)
#self.SearchProgress.setValue(1)
@ -382,7 +381,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedBookComboBox.itemData(item).toInt()[0])
def onImportClick(self):
self.bibleimportform = ImportWizardForm(self, self.parent.config,
self.bibleimportform = ImportWizardForm(self,
self.parent.manager, self.parent)
self.bibleimportform.exec_()
self.reloadBibles()
@ -440,7 +439,7 @@ class BibleMediaItem(MediaManagerItem):
if self.search_results:
self.displayResults(bible)
def generateSlideData(self, service_item):
def generateSlideData(self, service_item, item=None):
log.debug(u'generating slide data')
items = self.ListView.selectedIndexes()
if len(items) == 0:
@ -449,7 +448,9 @@ class BibleMediaItem(MediaManagerItem):
raw_slides = []
raw_footer = []
bible_text = u''
service_item.auto_preview_allowed = True
service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions)
#If we want to use a 2nd translation / version
bible2 = u''
if self.SearchTabWidget.currentIndex() == 0:
@ -518,7 +519,7 @@ class BibleMediaItem(MediaManagerItem):
else:
service_item.theme = self.parent.settings_tab.bible_theme
#if we are verse per slide we have already been added
if self.parent.settings_tab.layout_style != 0:
if self.parent.settings_tab.layout_style != 0 and not bible2:
raw_slides.append(bible_text)
for slide in raw_slides:
service_item.add_from_text(slide[:30], slide)
@ -608,4 +609,4 @@ class BibleMediaItem(MediaManagerItem):
def searchByReference(self, bible, search):
log.debug(u'searchByReference %s, %s', bible, search)
self.search_results = self.parent.manager.get_verses(bible, search)
self.search_results = self.parent.manager.get_verses(bible, search)

View File

@ -49,7 +49,7 @@ class OpenSongBible(BibleDB):
raise KeyError(u'You have to supply a file name to import from.')
self.filename = kwargs['filename']
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_bible_import'), self.stop_import)
QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import)
def stop_import(self):
"""
@ -92,7 +92,7 @@ class OpenSongBible(BibleDB):
int(verse.attrib[u'n']),
unicode(verse.text)
)
Receiver.send_message(u'process_events')
Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\
db_book.name, chapter.attrib[u'n'])))
@ -108,3 +108,5 @@ class OpenSongBible(BibleDB):
return False
else:
return success

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