This commit is contained in:
Mattias Põldaru 2012-03-06 21:58:51 +02:00
commit 1488eb8244
231 changed files with 29322 additions and 9575 deletions

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -5,8 +5,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -32,7 +32,7 @@ import logging
import os.path import os.path
import types import types
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui, Qt
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -43,6 +43,26 @@ class MediaType(object):
Audio = 1 Audio = 1
Video = 2 Video = 2
class SlideLimits(object):
"""
Provides an enumeration for behaviour of OpenLP at the end limits of each
service item when pressing the up/down arrow keys
"""
End = 1
Wrap = 2
Next = 3
class ServiceItemAction(object):
"""
Provides an enumeration for the required action moving between service
items by left/right arrow keys
"""
Previous = 1
PreviousLastSlide = 2
Next = 3
def translate(context, text, comment=None, def translate(context, text, comment=None,
encoding=QtCore.QCoreApplication.CodecForTr, n=-1, encoding=QtCore.QCoreApplication.CodecForTr, n=-1,
translate=QtCore.QCoreApplication.translate): translate=QtCore.QCoreApplication.translate):
@ -298,6 +318,34 @@ def check_directory_exists(dir):
except IOError: except IOError:
pass pass
def create_separated_list(stringlist):
"""
Returns a string that represents a join of a list of strings with a
localized separator. This function corresponds to
QLocale::createSeparatedList which was introduced in Qt 4.8 and implements
the algorithm from http://www.unicode.org/reports/tr35/#ListPatterns
``stringlist``
List of unicode strings
"""
if Qt.PYQT_VERSION_STR >= u'4.9' and Qt.qVersion() >= u'4.8':
return unicode(QtCore.QLocale().createSeparatedList(stringlist))
if not stringlist:
return u''
elif len(stringlist) == 1:
return stringlist[0]
elif len(stringlist) == 2:
return unicode(translate('OpenLP.core.lib', '%1 and %2',
'Locale list separator: 2 items').arg(stringlist[0], stringlist[1]))
else:
merged = unicode(translate('OpenLP.core.lib', '%1, and %2',
u'Locale list separator: end').arg(stringlist[-2], stringlist[-1]))
for index in reversed(range(1, len(stringlist) - 2)):
merged = unicode(translate('OpenLP.core.lib', '%1, %2',
u'Locale list separator: middle').arg(stringlist[index], merged))
return unicode(translate('OpenLP.core.lib', '%1, %2',
u'Locale list separator: start').arg(stringlist[0], merged))
from eventreceiver import Receiver from eventreceiver import Receiver
from listwidgetwithdnd import ListWidgetWithDnD from listwidgetwithdnd import ListWidgetWithDnD
from formattingtags import FormattingTags from formattingtags import FormattingTags

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -199,6 +199,10 @@ class Manager(object):
urlquote(unicode(settings.value(u'db password').toString())), urlquote(unicode(settings.value(u'db password').toString())),
urlquote(unicode(settings.value(u'db hostname').toString())), urlquote(unicode(settings.value(u'db hostname').toString())),
urlquote(unicode(settings.value(u'db database').toString()))) urlquote(unicode(settings.value(u'db database').toString())))
if db_type == u'mysql':
db_encoding = unicode(
settings.value(u'db encoding', u'utf8').toString())
self.db_url += u'?charset=%s' % urlquote(db_encoding)
settings.endGroup() settings.endGroup()
if upgrade_mod: if upgrade_mod:
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod) db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
@ -239,6 +243,17 @@ class Manager(object):
self.session.commit() self.session.commit()
self.is_dirty = True self.is_dirty = True
return True return True
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue - "MySQL has gone away"')
self.session.rollback()
self.session.add(object_instance)
if commit:
self.session.commit()
self.is_dirty = True
return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Object save failed') log.exception(u'Object save failed')
@ -260,6 +275,17 @@ class Manager(object):
self.session.commit() self.session.commit()
self.is_dirty = True self.is_dirty = True
return True return True
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
self.session.add_all(object_list)
if commit:
self.session.commit()
self.is_dirty = True
return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Object list save failed') log.exception(u'Object list save failed')
@ -278,7 +304,15 @@ class Manager(object):
if not key: if not key:
return object_class() return object_class()
else: else:
return self.session.query(object_class).get(key) try:
return self.session.query(object_class).get(key)
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
return self.session.query(object_class).get(key)
def get_object_filtered(self, object_class, filter_clause): def get_object_filtered(self, object_class, filter_clause):
""" """
@ -290,7 +324,15 @@ class Manager(object):
``filter_clause`` ``filter_clause``
The criteria to select the object by The criteria to select the object by
""" """
return self.session.query(object_class).filter(filter_clause).first() try:
return self.session.query(object_class).filter(filter_clause).first()
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
return self.session.query(object_class).filter(filter_clause).first()
def get_all_objects(self, object_class, filter_clause=None, def get_all_objects(self, object_class, filter_clause=None,
order_by_ref=None): order_by_ref=None):
@ -311,10 +353,18 @@ class Manager(object):
if filter_clause is not None: if filter_clause is not None:
query = query.filter(filter_clause) query = query.filter(filter_clause)
if isinstance(order_by_ref, list): if isinstance(order_by_ref, list):
return query.order_by(*order_by_ref).all() query = query.order_by(*order_by_ref)
elif order_by_ref is not None: elif order_by_ref is not None:
return query.order_by(order_by_ref).all() query = query.order_by(order_by_ref)
return query.all() try:
return query.all()
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
return query.all()
def get_object_count(self, object_class, filter_clause=None): def get_object_count(self, object_class, filter_clause=None):
""" """
@ -330,7 +380,15 @@ class Manager(object):
query = self.session.query(object_class) query = self.session.query(object_class)
if filter_clause is not None: if filter_clause is not None:
query = query.filter(filter_clause) query = query.filter(filter_clause)
return query.count() try:
return query.count()
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
return query.count()
def delete_object(self, object_class, key): def delete_object(self, object_class, key):
""" """
@ -349,6 +407,16 @@ class Manager(object):
self.session.commit() self.session.commit()
self.is_dirty = True self.is_dirty = True
return True return True
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
self.session.delete(object_instance)
self.session.commit()
self.is_dirty = True
return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Failed to delete object') log.exception(u'Failed to delete object')
@ -378,6 +446,19 @@ class Manager(object):
self.session.commit() self.session.commit()
self.is_dirty = True self.is_dirty = True
return True return True
except OperationalError:
# This exception clause is for users running MySQL which likes
# to terminate connections on its own without telling anyone.
# See bug #927473
log.exception(u'Probably a MySQL issue, "MySQL has gone away"')
self.session.rollback()
query = self.session.query(object_class)
if filter_clause is not None:
query = query.filter(filter_clause)
query.delete(synchronize_session=False)
self.session.commit()
self.is_dirty = True
return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Failed to delete %s records', object_class.__name__) log.exception(u'Failed to delete %s records', object_class.__name__)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -111,6 +111,9 @@ class EventReceiver(QtCore.QObject):
``slidecontroller_live_spin_delay`` ``slidecontroller_live_spin_delay``
Pushes out the loop delay. Pushes out the loop delay.
``slidecontroller_update_slide_limits``
Updates the slide_limits variable from the saved settings.
``slidecontroller_live_stop_loop`` ``slidecontroller_live_stop_loop``
Stop the loop on the main display. Stop the loop on the main display.

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -45,6 +45,7 @@ HTMLSRC = u"""
padding: 0; padding: 0;
border: 0; border: 0;
overflow: hidden; overflow: hidden;
-webkit-user-select: none;
} }
body { body {
%s; %s;
@ -129,10 +130,10 @@ sup {
var match = /-webkit-text-fill-color:[^;\"]+/gi; var match = /-webkit-text-fill-color:[^;\"]+/gi;
if(timer != null) if(timer != null)
clearTimeout(timer); clearTimeout(timer);
/* /*
QtWebkit bug with outlines and justify causing outline alignment QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround, problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario. but only in this scenario.
*/ */
var txt = document.getElementById('lyricsmain'); var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){ if(window.getComputedStyle(txt).textAlign == 'justify'){
@ -141,7 +142,7 @@ sup {
txt = outline; txt = outline;
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
newtext = newtext.replace(/(\s|&nbsp;)+(?![^<]*>)/g, newtext = newtext.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) { function(match) {
return '</span>' + match + '<span>'; return '</span>' + match + '<span>';
}); });
newtext = '<span>' + newtext + '</span>'; newtext = '<span>' + newtext + '</span>';
@ -288,6 +289,9 @@ def build_background_css(item, width, height):
background = u'background-color: black' background = u'background-color: black'
if theme: if theme:
if theme.background_type == \ if theme.background_type == \
BackgroundType.to_string(BackgroundType.Transparent):
background = u''
elif theme.background_type == \
BackgroundType.to_string(BackgroundType.Solid): BackgroundType.to_string(BackgroundType.Solid):
background = u'background-color: %s' % theme.background_color background = u'background-color: %s' % theme.background_color
else: else:

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -35,6 +35,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \ from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, context_menu_action, \ from openlp.core.lib.ui import UiStrings, context_menu_action, \
context_menu_separator, critical_error_message_box context_menu_separator, critical_error_message_box
@ -301,6 +302,40 @@ class MediaManagerItem(QtGui.QWidget):
QtCore.SIGNAL('customContextMenuRequested(QPoint)'), QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
self.contextMenu) self.contextMenu)
def addSearchToToolBar(self):
"""
Creates a search field with button and related signal handling.
"""
self.searchWidget = QtGui.QWidget(self)
self.searchWidget.setObjectName(u'searchWidget')
self.searchLayout = QtGui.QVBoxLayout(self.searchWidget)
self.searchLayout.setObjectName(u'searchLayout')
self.searchTextLayout = QtGui.QFormLayout()
self.searchTextLayout.setObjectName(u'searchTextLayout')
self.searchTextLabel = QtGui.QLabel(self.searchWidget)
self.searchTextLabel.setObjectName(u'searchTextLabel')
self.searchTextEdit = SearchEdit(self.searchWidget)
self.searchTextEdit.setObjectName(u'searchTextEdit')
self.searchTextLabel.setBuddy(self.searchTextEdit)
self.searchTextLayout.addRow(self.searchTextLabel, self.searchTextEdit)
self.searchLayout.addLayout(self.searchTextLayout)
self.searchButtonLayout = QtGui.QHBoxLayout()
self.searchButtonLayout.setObjectName(u'searchButtonLayout')
self.searchButtonLayout.addStretch()
self.searchTextButton = QtGui.QPushButton(self.searchWidget)
self.searchTextButton.setObjectName(u'searchTextButton')
self.searchButtonLayout.addWidget(self.searchTextButton)
self.searchLayout.addLayout(self.searchButtonLayout)
self.pageLayout.addWidget(self.searchWidget)
# Signals and slots
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextButton,
QtCore.SIGNAL(u'pressed()'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onSearchTextEditChanged)
def addCustomContextActions(self): def addCustomContextActions(self):
""" """
Implement this method in your descendent media manager item to Implement this method in your descendent media manager item to

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -100,6 +100,7 @@ class BackgroundType(object):
Solid = 0 Solid = 0
Gradient = 1 Gradient = 1
Image = 2 Image = 2
Transparent = 3
@staticmethod @staticmethod
def to_string(background_type): def to_string(background_type):
@ -112,6 +113,8 @@ class BackgroundType(object):
return u'gradient' return u'gradient'
elif background_type == BackgroundType.Image: elif background_type == BackgroundType.Image:
return u'image' return u'image'
elif background_type == BackgroundType.Transparent:
return u'transparent'
@staticmethod @staticmethod
def from_string(type_string): def from_string(type_string):
@ -124,6 +127,8 @@ class BackgroundType(object):
return BackgroundType.Gradient return BackgroundType.Gradient
elif type_string == u'image': elif type_string == u'image':
return BackgroundType.Image return BackgroundType.Image
elif type_string == u'transparent':
return BackgroundType.Transparent
class BackgroundGradientType(object): class BackgroundGradientType(object):
@ -246,7 +251,7 @@ class ThemeXML(object):
Add a transparent background. Add a transparent background.
""" """
background = self.theme_xml.createElement(u'background') background = self.theme_xml.createElement(u'background')
background.setAttribute(u'mode', u'transparent') background.setAttribute(u'type', u'transparent')
self.theme.appendChild(background) self.theme.appendChild(background)
def add_background_solid(self, bkcolor): def add_background_solid(self, bkcolor):
@ -487,25 +492,25 @@ class ThemeXML(object):
return return
xml_iter = theme_xml.getiterator() xml_iter = theme_xml.getiterator()
for element in xml_iter: for element in xml_iter:
parent = element.getparent()
master = u'' master = u''
if element.tag == u'background':
if element.attrib:
for attr in element.attrib:
self._create_attr(element.tag, attr, \
element.attrib[attr])
parent = element.getparent()
if parent is not None: if parent is not None:
if element.getparent().tag == u'font': if parent.tag == u'font':
master = element.getparent().tag + u'_' + \ master = parent.tag + u'_' + parent.attrib[u'type']
element.getparent().attrib[u'type']
# set up Outline and Shadow Tags and move to font_main # set up Outline and Shadow Tags and move to font_main
if element.getparent().tag == u'display': if parent.tag == u'display':
if element.tag.startswith(u'shadow') or \ if element.tag.startswith(u'shadow') or \
element.tag.startswith(u'outline'): element.tag.startswith(u'outline'):
self._create_attr(u'font_main', element.tag, self._create_attr(u'font_main', element.tag,
element.text) element.text)
master = element.getparent().tag master = parent.tag
if element.getparent().tag == u'background': if parent.tag == u'background':
master = element.getparent().tag master = parent.tag
if element.getparent().attrib:
for attr in element.getparent().attrib:
self._create_attr(master, attr, \
element.getparent().attrib[attr])
if master: if master:
self._create_attr(master, element.tag, element.text) self._create_attr(master, element.tag, element.text)
if element.attrib: if element.attrib:
@ -599,9 +604,13 @@ class ThemeXML(object):
self.background_start_color, self.background_start_color,
self.background_end_color, self.background_end_color,
self.background_direction) self.background_direction)
else: elif self.background_type == \
BackgroundType.to_string(BackgroundType.Image):
filename = os.path.split(self.background_filename)[1] filename = os.path.split(self.background_filename)[1]
self.add_background_image(filename, self.background_border_color) self.add_background_image(filename, self.background_border_color)
elif self.background_type == \
BackgroundType.to_string(BackgroundType.Transparent):
self.add_background_transparent()
self.add_font(self.font_main_name, self.add_font(self.font_main_name,
self.font_main_color, self.font_main_color,
self.font_main_size, self.font_main_size,

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -93,6 +93,7 @@ class UiStrings(object):
self.New = translate('OpenLP.Ui', 'New') self.New = translate('OpenLP.Ui', 'New')
self.NewService = translate('OpenLP.Ui', 'New Service') self.NewService = translate('OpenLP.Ui', 'New Service')
self.NewTheme = translate('OpenLP.Ui', 'New Theme') self.NewTheme = translate('OpenLP.Ui', 'New Theme')
self.NextTrack = translate('OpenLP.Ui', 'Next Track')
self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -126,7 +126,8 @@ class Ui_AboutDialog(object):
u'Tim "TRB143" Bentley (Fedora and Android)', u'Tim "TRB143" Bentley (Fedora and Android)',
u'Matthias "matthub" Hub (Mac OS X)', u'Matthias "matthub" Hub (Mac OS X)',
u'Stevan "ElderP" Pettit (Windows)', u'Stevan "ElderP" Pettit (Windows)',
u'Raoul "superfly" Snyman (Ubuntu)'] u'Raoul "superfly" Snyman (Ubuntu)',
u'Garrett "floft" Wilson (Arch Linux)']
translators = { translators = {
u'af': [u'Johan "nuvolari" Mynhardt'], u'af': [u'Johan "nuvolari" Mynhardt'],
u'de': [u'Patrick "madmuffin" Br\xfcckner', u'de': [u'Patrick "madmuffin" Br\xfcckner',
@ -226,8 +227,8 @@ class Ui_AboutDialog(object):
self.aboutNotebook.indexOf(self.creditsTab), self.aboutNotebook.indexOf(self.creditsTab),
translate('OpenLP.AboutForm', 'Credits')) translate('OpenLP.AboutForm', 'Credits'))
copyright = unicode(translate('OpenLP.AboutForm', copyright = unicode(translate('OpenLP.AboutForm',
'Copyright \xa9 2004-2011 %s\n' 'Copyright \xa9 2004-2012 %s\n'
'Portions copyright \xa9 2004-2011 %s')) % (u'Raoul Snyman', 'Portions copyright \xa9 2004-2012 %s')) % (u'Raoul Snyman',
u'Tim Bentley, Jonathan Corwin, Michael Gorven, Gerald Britton, ' u'Tim Bentley, Jonathan Corwin, Michael Gorven, Gerald Britton, '
u'Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin K\xf6hler, ' u'Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin K\xf6hler, '
u'Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias ' u'Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias '

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -27,10 +27,13 @@
""" """
The :mod:`advancedtab` provides an advanced settings facility. The :mod:`advancedtab` provides an advanced settings facility.
""" """
from datetime import datetime, timedelta
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, build_icon from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
from openlp.core.lib import SlideLimits
from openlp.core.utils import get_images_filter from openlp.core.utils import get_images_filter
class AdvancedTab(SettingsTab): class AdvancedTab(SettingsTab):
@ -42,11 +45,26 @@ class AdvancedTab(SettingsTab):
""" """
Initialise the settings tab Initialise the settings tab
""" """
advancedTranslated = translate('OpenLP.AdvancedTab', 'Advanced') self.displayChanged = False
self.default_image = u':/graphics/openlp-splash-screen.png' # 7 stands for now, 0 to 6 is Monday to Sunday.
self.default_color = u'#ffffff' self.defaultServiceDay = 7
# 11 o'clock is the most popular time for morning service.
self.defaultServiceHour = 11
self.defaultServiceMinute = 0
self.defaultServiceName = unicode(translate('OpenLP.AdvancedTab',
'Service %Y-%m-%d %H-%M',
'This is the default default service name template, which can be '
'found under Advanced in Settings, Configure OpenLP. Please do not '
'include any of the following characters: /\\?*|<>\[\]":+\n'
'You can use any of the directives as shown on page '
'http://docs.python.org/library/datetime.html'
'#strftime-strptime-behavior , but if possible, please keep '
'the resulting string sortable by name.'))
self.defaultImage = u':/graphics/openlp-splash-screen.png'
self.defaultColor = u'#ffffff'
self.icon_path = u':/system/system_settings.png' self.icon_path = u':/system/system_settings.png'
SettingsTab.__init__(self, parent, u'Advanced', advancedTranslated) advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced')
SettingsTab.__init__(self, parent, u'Advanced', advanced_translated)
def setupUi(self): def setupUi(self):
""" """
@ -83,7 +101,61 @@ class AdvancedTab(SettingsTab):
u'enableAutoCloseCheckBox') u'enableAutoCloseCheckBox')
self.uiLayout.addRow(self.enableAutoCloseCheckBox) self.uiLayout.addRow(self.enableAutoCloseCheckBox)
self.leftLayout.addWidget(self.uiGroupBox) self.leftLayout.addWidget(self.uiGroupBox)
# Default service name
self.serviceNameGroupBox = QtGui.QGroupBox(self.leftColumn)
self.serviceNameGroupBox.setObjectName(u'serviceNameGroupBox')
self.serviceNameLayout = QtGui.QFormLayout(
self.serviceNameGroupBox)
self.serviceNameCheckBox = QtGui.QCheckBox(
self.serviceNameGroupBox)
self.serviceNameCheckBox.setObjectName(u'serviceNameCheckBox')
self.serviceNameLayout.setObjectName(u'serviceNameLayout')
self.serviceNameLayout.addRow(self.serviceNameCheckBox)
self.serviceNameTimeLabel = QtGui.QLabel(self.serviceNameGroupBox)
self.serviceNameTimeLabel.setObjectName(u'serviceNameTimeLabel')
self.serviceNameDay = QtGui.QComboBox(
self.serviceNameGroupBox)
self.serviceNameDay.addItems(
[u'', u'', u'', u'', u'', u'', u'', u''])
self.serviceNameDay.setObjectName(
u'serviceNameDay')
self.serviceNameTime = QtGui.QTimeEdit(self.serviceNameGroupBox)
self.serviceNameTime.setObjectName(u'serviceNameTime')
self.serviceNameTimeHBox = QtGui.QHBoxLayout()
self.serviceNameTimeHBox.setObjectName(u'serviceNameTimeHBox')
self.serviceNameTimeHBox.addWidget(self.serviceNameDay)
self.serviceNameTimeHBox.addWidget(self.serviceNameTime)
self.serviceNameLayout.addRow(self.serviceNameTimeLabel,
self.serviceNameTimeHBox)
self.serviceNameLabel = QtGui.QLabel(self.serviceNameGroupBox)
self.serviceNameLabel.setObjectName(u'serviceNameLabel')
self.serviceNameEdit = QtGui.QLineEdit(self.serviceNameGroupBox)
self.serviceNameEdit.setObjectName(u'serviceNameEdit')
self.serviceNameEdit.setValidator(QtGui.QRegExpValidator(
QtCore.QRegExp(r'[^/\\?*|<>\[\]":+]+'), self))
self.serviceNameRevertButton = QtGui.QToolButton(
self.serviceNameGroupBox)
self.serviceNameRevertButton.setObjectName(
u'serviceNameRevertButton')
self.serviceNameRevertButton.setIcon(
build_icon(u':/general/general_revert.png'))
self.serviceNameHBox = QtGui.QHBoxLayout()
self.serviceNameHBox.setObjectName(u'serviceNameHBox')
self.serviceNameHBox.addWidget(self.serviceNameEdit)
self.serviceNameHBox.addWidget(self.serviceNameRevertButton)
self.serviceNameLayout.addRow(self.serviceNameLabel,
self.serviceNameHBox)
self.serviceNameExampleLabel = QtGui.QLabel(
self.serviceNameGroupBox)
self.serviceNameExampleLabel.setObjectName(
u'serviceNameExampleLabel')
self.serviceNameExample = QtGui.QLabel(self.serviceNameGroupBox)
self.serviceNameExample.setObjectName(u'serviceNameExample')
self.serviceNameLayout.addRow(self.serviceNameExampleLabel,
self.serviceNameExample)
self.leftLayout.addWidget(self.serviceNameGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
# Default Image
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn) self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox') self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
self.defaultImageLayout = QtGui.QFormLayout(self.defaultImageGroupBox) self.defaultImageLayout = QtGui.QFormLayout(self.defaultImageGroupBox)
@ -114,7 +186,8 @@ class AdvancedTab(SettingsTab):
self.defaultImageLayout.addRow(self.defaultFileLabel, self.defaultImageLayout.addRow(self.defaultFileLabel,
self.defaultFileLayout) self.defaultFileLayout)
self.rightLayout.addWidget(self.defaultImageGroupBox) self.rightLayout.addWidget(self.defaultImageGroupBox)
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn) # Hide mouse
self.hideMouseGroupBox = QtGui.QGroupBox(self.rightColumn)
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox') self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox) self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
self.hideMouseLayout.setObjectName(u'hideMouseLayout') self.hideMouseLayout.setObjectName(u'hideMouseLayout')
@ -122,14 +195,76 @@ class AdvancedTab(SettingsTab):
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox') self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
self.hideMouseLayout.addWidget(self.hideMouseCheckBox) self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
self.rightLayout.addWidget(self.hideMouseGroupBox) self.rightLayout.addWidget(self.hideMouseGroupBox)
# Service Item Slide Limits
self.slideGroupBox = QtGui.QGroupBox(self.rightColumn)
self.slideGroupBox.setObjectName(u'slideGroupBox')
self.slideLayout = QtGui.QFormLayout(self.slideGroupBox)
self.slideLayout.setLabelAlignment(
QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
self.slideLayout.setFormAlignment(
QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
self.slideLayout.setObjectName(u'slideLayout')
self.endSlideRadioButton = QtGui.QRadioButton(self.slideGroupBox)
self.endSlideRadioButton.setObjectName(u'endSlideRadioButton')
self.endSlideLabel = QtGui.QLabel(self.slideGroupBox)
self.endSlideLabel.setWordWrap(True)
self.endSlideLabel.setObjectName(u'endSlideLabel')
self.slideLayout.addRow(self.endSlideRadioButton, self.endSlideLabel)
self.wrapSlideRadioButton = QtGui.QRadioButton(self.slideGroupBox)
self.wrapSlideRadioButton.setObjectName(u'wrapSlideRadioButton')
self.wrapSlideLabel = QtGui.QLabel(self.slideGroupBox)
self.wrapSlideLabel.setWordWrap(True)
self.wrapSlideLabel.setObjectName(u'wrapSlideLabel')
self.slideLayout.addRow(self.wrapSlideRadioButton,
self.wrapSlideLabel)
self.nextItemRadioButton = QtGui.QRadioButton(self.slideGroupBox)
self.nextItemRadioButton.setChecked(True)
self.nextItemRadioButton.setObjectName(u'nextItemRadioButton')
self.nextItemLabel = QtGui.QLabel(self.slideGroupBox)
self.nextItemLabel.setWordWrap(True)
self.nextItemLabel.setObjectName(u'nextItemLabel')
self.slideLayout.addRow(self.nextItemRadioButton,
self.nextItemLabel)
self.rightLayout.addWidget(self.slideGroupBox)
self.x11GroupBox = QtGui.QGroupBox(self.leftColumn)
self.x11GroupBox.setObjectName(u'x11GroupBox')
self.x11Layout = QtGui.QVBoxLayout(self.x11GroupBox)
self.x11Layout.setObjectName(u'x11Layout')
self.x11BypassCheckBox = QtGui.QCheckBox(self.x11GroupBox)
self.x11BypassCheckBox.setObjectName(u'x11BypassCheckBox')
self.x11Layout.addWidget(self.x11BypassCheckBox)
self.rightLayout.addWidget(self.x11GroupBox)
self.rightLayout.addStretch() self.rightLayout.addStretch()
self.shouldUpdateServiceNameExample = False
QtCore.QObject.connect(self.serviceNameCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.serviceNameCheckBoxToggled)
QtCore.QObject.connect(self.serviceNameDay,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onServiceNameDayChanged)
QtCore.QObject.connect(self.serviceNameTime,
QtCore.SIGNAL(u'timeChanged(QTime)'),
self.updateServiceNameExample)
QtCore.QObject.connect(self.serviceNameEdit,
QtCore.SIGNAL(u'textChanged(QString)'),
self.updateServiceNameExample)
QtCore.QObject.connect(self.serviceNameRevertButton,
QtCore.SIGNAL(u'pressed()'),
self.onServiceNameRevertButtonPressed)
QtCore.QObject.connect(self.defaultColorButton, QtCore.QObject.connect(self.defaultColorButton,
QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
QtCore.QObject.connect(self.defaultBrowseButton, QtCore.QObject.connect(self.defaultBrowseButton,
QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
QtCore.QObject.connect(self.defaultRevertButton, QtCore.QObject.connect(self.defaultRevertButton,
QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed)
QtCore.QObject.connect(self.x11BypassCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onX11BypassCheckBoxToggled)
QtCore.QObject.connect(self.endSlideRadioButton,
QtCore.SIGNAL(u'pressed()'), self.onEndSlideButtonPressed)
QtCore.QObject.connect(self.wrapSlideRadioButton,
QtCore.SIGNAL(u'pressed()'), self.onWrapSlideButtonPressed)
QtCore.QObject.connect(self.nextItemRadioButton,
QtCore.SIGNAL(u'pressed()'), self.onnextItemButtonPressed)
def retranslateUi(self): def retranslateUi(self):
""" """
@ -151,6 +286,40 @@ class AdvancedTab(SettingsTab):
'Expand new service items on creation')) 'Expand new service items on creation'))
self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab', self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab',
'Enable application exit confirmation')) 'Enable application exit confirmation'))
self.serviceNameGroupBox.setTitle(
translate('OpenLP.AdvancedTab', 'Default Service Name'))
self.serviceNameCheckBox.setText(
translate('OpenLP.AdvancedTab', 'Enable default service name'))
self.serviceNameTimeLabel.setText(
translate('OpenLP.AdvancedTab', 'Date and Time:'))
self.serviceNameDay.setItemText(0,
translate('OpenLP.AdvancedTab', 'Monday'))
self.serviceNameDay.setItemText(1,
translate('OpenLP.AdvancedTab', 'Tuesday'))
self.serviceNameDay.setItemText(2,
translate('OpenLP.AdvancedTab', 'Wednesday'))
self.serviceNameDay.setItemText(3,
translate('OpenLP.AdvancedTab', 'Thurdsday'))
self.serviceNameDay.setItemText(4,
translate('OpenLP.AdvancedTab', 'Friday'))
self.serviceNameDay.setItemText(5,
translate('OpenLP.AdvancedTab', 'Saturday'))
self.serviceNameDay.setItemText(6,
translate('OpenLP.AdvancedTab', 'Sunday'))
self.serviceNameDay.setItemText(7,
translate('OpenLP.AdvancedTab', 'Now'))
self.serviceNameTime.setToolTip(translate('OpenLP.AdvancedTab',
'Time when usual service starts.'))
self.serviceNameLabel.setText(
translate('OpenLP.AdvancedTab', 'Name:'))
self.serviceNameEdit.setToolTip(translate('OpenLP.AdvancedTab',
'Consult the OpenLP manual for usage.'))
self.serviceNameRevertButton.setToolTip(unicode(
translate('OpenLP.AdvancedTab',
'Revert to the default service name "%s".')) %
self.defaultServiceName)
self.serviceNameExampleLabel.setText(translate('OpenLP.AdvancedTab',
'Example:'))
self.hideMouseGroupBox.setTitle(translate('OpenLP.AdvancedTab', self.hideMouseGroupBox.setTitle(translate('OpenLP.AdvancedTab',
'Mouse Cursor')) 'Mouse Cursor'))
self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab', self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab',
@ -167,6 +336,29 @@ class AdvancedTab(SettingsTab):
'Browse for an image file to display.')) 'Browse for an image file to display.'))
self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab', self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
'Revert to the default OpenLP logo.')) 'Revert to the default OpenLP logo.'))
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab',
'X11'))
self.x11BypassCheckBox.setText(translate('OpenLP.AdvancedTab',
'Bypass X11 Window Manager'))
# Slide Limits
self.slideGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Service Item Slide Limits'))
self.endSlideRadioButton.setText(
translate('OpenLP.GeneralTab', '&End Slide'))
self.endSlideLabel.setText(
translate('OpenLP.GeneralTab', 'Up and down arrow keys '
'stop at the top and bottom slides of each Service Item.'))
self.wrapSlideRadioButton.setText(
translate('OpenLP.GeneralTab', '&Wrap Slide'))
self.wrapSlideLabel.setText(
translate('OpenLP.GeneralTab', 'Up and down arrow keys '
'wrap around at the top and bottom slides of each Service Item.'))
self.nextItemRadioButton.setText(
translate('OpenLP.GeneralTab', '&Next Item'))
self.nextItemLabel.setText(
translate('OpenLP.GeneralTab', 'Up and down arrow keys '
'advance to the the next or previous Service Item from the '
'top and bottom slides of each Service Item.'))
def load(self): def load(self):
""" """
@ -198,14 +390,39 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(True)).toBool()) QtCore.QVariant(True)).toBool())
self.hideMouseCheckBox.setChecked( self.hideMouseCheckBox.setChecked(
settings.value(u'hide mouse', QtCore.QVariant(False)).toBool()) settings.value(u'hide mouse', QtCore.QVariant(False)).toBool())
self.default_color = settings.value(u'default color', self.serviceNameDay.setCurrentIndex(
settings.value(u'default service day',
QtCore.QVariant(self.defaultServiceDay)).toInt()[0])
self.serviceNameTime.setTime(QtCore.QTime(
settings.value(u'default service hour',
self.defaultServiceHour).toInt()[0],
settings.value(u'default service minute',
self.defaultServiceMinute).toInt()[0]))
self.shouldUpdateServiceNameExample = True
self.serviceNameEdit.setText(settings.value(u'default service name',
self.defaultServiceName).toString())
default_service_enabled = settings.value(u'default service enabled',
QtCore.QVariant(True)).toBool()
self.serviceNameCheckBox.setChecked(default_service_enabled)
self.serviceNameCheckBoxToggled(default_service_enabled)
self.x11BypassCheckBox.setChecked(
settings.value(u'x11 bypass wm', QtCore.QVariant(True)).toBool())
self.defaultColor = settings.value(u'default color',
QtCore.QVariant(u'#ffffff')).toString() QtCore.QVariant(u'#ffffff')).toString()
self.defaultFileEdit.setText(settings.value(u'default image', self.defaultFileEdit.setText(settings.value(u'default image',
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\ QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
.toString()) .toString())
self.slide_limits = settings.value(
u'slide limits', QtCore.QVariant(SlideLimits.End)).toInt()[0]
if self.slide_limits == SlideLimits.End:
self.endSlideRadioButton.setChecked(True)
elif self.slide_limits == SlideLimits.Wrap:
self.wrapSlideRadioButton.setChecked(True)
else:
self.nextItemRadioButton.setChecked(True)
settings.endGroup() settings.endGroup()
self.defaultColorButton.setStyleSheet( self.defaultColorButton.setStyleSheet(
u'background-color: %s' % self.default_color) u'background-color: %s' % self.defaultColor)
def save(self): def save(self):
""" """
@ -213,6 +430,21 @@ class AdvancedTab(SettingsTab):
""" """
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
settings.setValue(u'default service enabled',
self.serviceNameCheckBox.isChecked())
service_name = unicode(self.serviceNameEdit.text())
preset_is_valid = self.generateServiceNameExample()[0]
if service_name == self.defaultServiceName or not preset_is_valid:
settings.remove(u'default service name')
self.serviceNameEdit.setText(service_name)
else:
settings.setValue(u'default service name', service_name)
settings.setValue(u'default service day',
self.serviceNameDay.currentIndex())
settings.setValue(u'default service hour',
self.serviceNameTime.time().hour())
settings.setValue(u'default service minute',
self.serviceNameTime.time().minute())
settings.setValue(u'recent file count', settings.setValue(u'recent file count',
QtCore.QVariant(self.recentSpinBox.value())) QtCore.QVariant(self.recentSpinBox.value()))
settings.setValue(u'save current plugin', settings.setValue(u'save current plugin',
@ -227,17 +459,67 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked())) QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
settings.setValue(u'hide mouse', settings.setValue(u'hide mouse',
QtCore.QVariant(self.hideMouseCheckBox.isChecked())) QtCore.QVariant(self.hideMouseCheckBox.isChecked()))
settings.setValue(u'default color', self.default_color) settings.setValue(u'x11 bypass wm',
QtCore.QVariant(self.x11BypassCheckBox.isChecked()))
settings.setValue(u'default color', self.defaultColor)
settings.setValue(u'default image', self.defaultFileEdit.text()) settings.setValue(u'default image', self.defaultFileEdit.text())
settings.setValue(u'slide limits', QtCore.QVariant(self.slide_limits))
settings.endGroup() settings.endGroup()
if self.displayChanged:
Receiver.send_message(u'config_screen_changed')
self.displayChanged = False
Receiver.send_message(u'slidecontroller_update_slide_limits')
def serviceNameCheckBoxToggled(self, default_service_enabled):
self.serviceNameDay.setEnabled(default_service_enabled)
time_enabled = default_service_enabled and \
self.serviceNameDay.currentIndex() is not 7
self.serviceNameTime.setEnabled(time_enabled)
self.serviceNameEdit.setEnabled(default_service_enabled)
self.serviceNameRevertButton.setEnabled(default_service_enabled)
def generateServiceNameExample(self):
preset_is_valid = True
if self.serviceNameDay.currentIndex() == 7:
time = datetime.now()
else:
now = datetime.now()
day_delta = self.serviceNameDay.currentIndex() - now.weekday()
if day_delta < 0:
day_delta += 7
time = now + timedelta(days=day_delta)
time = time.replace(hour = self.serviceNameTime.time().hour(),
minute = self.serviceNameTime.time().minute())
try:
service_name_example = time.strftime(unicode(
self.serviceNameEdit.text()))
except ValueError:
preset_is_valid = False
service_name_example = translate('OpenLP.AdvancedTab',
'Syntax error.')
return preset_is_valid, service_name_example
def updateServiceNameExample(self, returned_value):
if not self.shouldUpdateServiceNameExample:
return
name_example = self.generateServiceNameExample()[1]
self.serviceNameExample.setText(name_example)
def onServiceNameDayChanged(self, service_day):
self.serviceNameTime.setEnabled(service_day is not 7)
self.updateServiceNameExample(None)
def onServiceNameRevertButtonPressed(self):
self.serviceNameEdit.setText(self.defaultServiceName)
self.serviceNameEdit.setFocus()
def onDefaultColorButtonPressed(self): def onDefaultColorButtonPressed(self):
new_color = QtGui.QColorDialog.getColor( new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.default_color), self) QtGui.QColor(self.defaultColor), self)
if new_color.isValid(): if new_color.isValid():
self.default_color = new_color.name() self.defaultColor = new_color.name()
self.defaultColorButton.setStyleSheet( self.defaultColorButton.setStyleSheet(
u'background-color: %s' % self.default_color) u'background-color: %s' % self.defaultColor)
def onDefaultBrowseButtonPressed(self): def onDefaultBrowseButtonPressed(self):
file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(), file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(),
@ -252,3 +534,21 @@ class AdvancedTab(SettingsTab):
def onDefaultRevertButtonPressed(self): def onDefaultRevertButtonPressed(self):
self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png') self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
self.defaultFileEdit.setFocus() self.defaultFileEdit.setFocus()
def onX11BypassCheckBoxToggled(self, checked):
"""
Toggle X11 bypass flag on maindisplay depending on check box state.
``checked``
The state of the check box (boolean).
"""
self.displayChanged = True
def onEndSlideButtonPressed(self):
self.slide_limits = SlideLimits.End
def onWrapSlideButtonPressed(self):
self.slide_limits = SlideLimits.Wrap
def onnextItemButtonPressed(self):
self.slide_limits = SlideLimits.Next

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -32,7 +32,7 @@ import platform
import sqlalchemy import sqlalchemy
import BeautifulSoup import BeautifulSoup
from lxml import etree from lxml import etree
from PyQt4 import Qt, QtCore, QtGui from PyQt4 import Qt, QtCore, QtGui, QtWebKit
try: try:
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
@ -77,6 +77,11 @@ try:
UNO_VERSION = node.getByName(u'ooSetupVersion') UNO_VERSION = node.getByName(u'ooSetupVersion')
except ImportError: except ImportError:
UNO_VERSION = u'-' UNO_VERSION = u'-'
try:
WEBKIT_VERSION = QtWebKit.qWebKitVersion()
except AttributeError:
WEBKIT_VERSION = u'-'
from openlp.core.lib import translate, SettingsManager from openlp.core.lib import translate, SettingsManager
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
@ -111,6 +116,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
u'Qt4: %s\n' % Qt.qVersion() + \ u'Qt4: %s\n' % Qt.qVersion() + \
u'Phonon: %s\n' % PHONON_VERSION + \ u'Phonon: %s\n' % PHONON_VERSION + \
u'PyQt4: %s\n' % Qt.PYQT_VERSION_STR + \ u'PyQt4: %s\n' % Qt.PYQT_VERSION_STR + \
u'QtWebkit: %s\n' % WEBKIT_VERSION + \
u'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \ u'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \
u'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \ u'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \
u'BeautifulSoup: %s\n' % BeautifulSoup.__version__ + \ u'BeautifulSoup: %s\n' % BeautifulSoup.__version__ + \

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -41,7 +41,7 @@ class Ui_FileRenameDialog(object):
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0) self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog) self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
self.fileNameEdit.setValidator(QtGui.QRegExpValidator( self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self)) QtCore.QRegExp(r'[^/\\?*|<>\[\]":+%]+'), self))
self.fileNameEdit.setObjectName(u'fileNameEdit') self.fileNameEdit.setObjectName(u'fileNameEdit')
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1) self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True) self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -29,6 +29,7 @@ import io
import logging import logging
import os import os
import sys import sys
import time
import urllib import urllib
import urllib2 import urllib2
from tempfile import gettempdir from tempfile import gettempdir
@ -43,6 +44,29 @@ from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class ThemeScreenshotThread(QtCore.QThread):
"""
This thread downloads the theme screenshots.
"""
def __init__(self, parent):
QtCore.QThread.__init__(self, parent)
def run(self):
themes = self.parent().config.get(u'themes', u'files')
themes = themes.split(u',')
config = self.parent().config
for theme in themes:
title = config.get(u'theme_%s' % theme, u'title')
filename = config.get(u'theme_%s' % theme, u'filename')
screenshot = config.get(u'theme_%s' % theme, u'screenshot')
urllib.urlretrieve(u'%s%s' % (self.parent().web, screenshot),
os.path.join(gettempdir(), u'openlp', screenshot))
item = QtGui.QListWidgetItem(title, self.parent().themesListWidget)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(filename))
item.setCheckState(QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
""" """
This is the Theme Import Wizard, which allows easy creation and editing of This is the Theme Import Wizard, which allows easy creation and editing of
@ -125,21 +149,9 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
item.setCheckState(0, QtCore.Qt.Unchecked) item.setCheckState(0, QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
self.biblesTreeWidget.expandAll() self.biblesTreeWidget.expandAll()
themes = self.config.get(u'themes', u'files') # Download the theme screenshots.
themes = themes.split(u',') self.themeScreenshotThread = ThemeScreenshotThread(self)
for theme in themes: self.themeScreenshotThread.start()
title = self.config.get(u'theme_%s' % theme, u'title')
filename = self.config.get(u'theme_%s' % theme, u'filename')
screenshot = self.config.get(u'theme_%s' % theme, u'screenshot')
urllib.urlretrieve(u'%s%s' % (self.web, screenshot),
os.path.join(gettempdir(), u'openlp', screenshot))
item = QtGui.QListWidgetItem(title, self.themesListWidget)
item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(filename))
item.setIcon(build_icon(
os.path.join(gettempdir(), u'openlp', screenshot)))
item.setCheckState(QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
def nextId(self): def nextId(self):
@ -156,6 +168,14 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
return -1 return -1
elif self.currentId() == FirstTimePage.NoInternet: elif self.currentId() == FirstTimePage.NoInternet:
return FirstTimePage.Progress return FirstTimePage.Progress
elif self.currentId() == FirstTimePage.Themes:
Receiver.send_message(u'cursor_busy')
while not self.themeScreenshotThread.isFinished():
time.sleep(0.1)
# Build the screenshot icons, as this can not be done in the thread.
self._buildThemeScreenshots()
Receiver.send_message(u'cursor_normal')
return FirstTimePage.Defaults
else: else:
return self.currentId() + 1 return self.currentId() + 1
@ -172,7 +192,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
if self.hasRunWizard: if self.hasRunWizard:
self.noInternetLabel.setText(self.noInternetText) self.noInternetLabel.setText(self.noInternetText)
else: else:
self.noInternetLabel.setText(self.noInternetText + self.noInternetLabel.setText(self.noInternetText +
self.cancelWizardText) self.cancelWizardText)
elif pageId == FirstTimePage.Defaults: elif pageId == FirstTimePage.Defaults:
self.themeComboBox.clear() self.themeComboBox.clear()
@ -264,6 +284,23 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
if self.downloadCanceled: if self.downloadCanceled:
os.remove(fpath) os.remove(fpath)
def _buildThemeScreenshots(self):
"""
This method builds the theme screenshots' icons for all items in the
``self.themesListWidget``.
"""
themes = self.config.get(u'themes', u'files')
themes = themes.split(u',')
for theme in themes:
filename = self.config.get(u'theme_%s' % theme, u'filename')
screenshot = self.config.get(u'theme_%s' % theme, u'screenshot')
for index in xrange(self.themesListWidget.count()):
item = self.themesListWidget.item(index)
if item.data(QtCore.Qt.UserRole) == QtCore.QVariant(filename):
break
item.setIcon(build_icon(
os.path.join(gettempdir(), u'openlp', screenshot)))
def _getFileSize(self, url): def _getFileSize(self, url):
site = urllib.urlopen(url) site = urllib.urlopen(url)
meta = site.info() meta = site.info()
@ -273,7 +310,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
increment = (count * block_size) - self.previous_size increment = (count * block_size) - self.previous_size
self._incrementProgressBar(None, increment) self._incrementProgressBar(None, increment)
self.previous_size = count * block_size self.previous_size = count * block_size
def _incrementProgressBar(self, status_text, increment=1): def _incrementProgressBar(self, status_text, increment=1):
""" """
Update the wizard progress page. Update the wizard progress page.
@ -421,6 +458,8 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
if self.displayComboBox.currentIndex() != -1: if self.displayComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'General/monitor', QtCore.QSettings().setValue(u'General/monitor',
QtCore.QVariant(self.displayComboBox.currentIndex())) QtCore.QVariant(self.displayComboBox.currentIndex()))
self.screens.set_current_display(
self.displayComboBox.currentIndex())
# Set Global Theme # Set Global Theme
if self.themeComboBox.currentIndex() != -1: if self.themeComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'themes/global theme', QtCore.QSettings().setValue(u'themes/global theme',

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -97,9 +97,6 @@ class GeneralTab(SettingsTab):
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox) self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox') self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox) self.settingsLayout.addRow(self.autoPreviewCheckBox)
self.enableLoopCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.enableLoopCheckBox.setObjectName(u'enableLoopCheckBox')
self.settingsLayout.addRow(self.enableLoopCheckBox)
# Moved here from image tab # Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox) self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName(u'timeoutLabel') self.timeoutLabel.setObjectName(u'timeoutLabel')
@ -178,6 +175,9 @@ class GeneralTab(SettingsTab):
self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox) self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.startPausedCheckBox.setObjectName(u'startPausedCheckBox') self.startPausedCheckBox.setObjectName(u'startPausedCheckBox')
self.audioLayout.addWidget(self.startPausedCheckBox) self.audioLayout.addWidget(self.startPausedCheckBox)
self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
self.audioLayout.addWidget(self.repeatListCheckBox)
self.rightLayout.addWidget(self.audioGroupBox) self.rightLayout.addWidget(self.audioGroupBox)
self.rightLayout.addStretch() self.rightLayout.addStretch()
# Signals and slots # Signals and slots
@ -231,8 +231,6 @@ class GeneralTab(SettingsTab):
'Unblank display when adding new live item')) 'Unblank display when adding new live item'))
self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab', self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab',
'Automatically preview next item in service')) 'Automatically preview next item in service'))
self.enableLoopCheckBox.setText(translate('OpenLP.GeneralTab',
'Enable slide wrap-around'))
self.timeoutLabel.setText(translate('OpenLP.GeneralTab', self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
'Timed slide interval:')) 'Timed slide interval:'))
self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec')) self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
@ -256,6 +254,8 @@ class GeneralTab(SettingsTab):
translate('OpenLP.GeneralTab', 'Background Audio')) translate('OpenLP.GeneralTab', 'Background Audio'))
self.startPausedCheckBox.setText( self.startPausedCheckBox.setText(
translate('OpenLP.GeneralTab', 'Start background audio paused')) translate('OpenLP.GeneralTab', 'Start background audio paused'))
self.repeatListCheckBox.setText(
translate('OpenLP.GeneralTab', 'Repeat track list'))
def load(self): def load(self):
""" """
@ -289,8 +289,6 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(True)).toBool()) QtCore.QVariant(True)).toBool())
self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview', self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview',
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.enableLoopCheckBox.setChecked(settings.value(u'enable slide loop',
QtCore.QVariant(True)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay', self.timeoutSpinBox.setValue(settings.value(u'loop delay',
QtCore.QVariant(5)).toInt()[0]) QtCore.QVariant(5)).toInt()[0])
self.overrideCheckBox.setChecked(settings.value(u'override position', self.overrideCheckBox.setChecked(settings.value(u'override position',
@ -305,12 +303,15 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0]) QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
self.startPausedCheckBox.setChecked(settings.value( self.startPausedCheckBox.setChecked(settings.value(
u'audio start paused', QtCore.QVariant(True)).toBool()) u'audio start paused', QtCore.QVariant(True)).toBool())
self.repeatListCheckBox.setChecked(settings.value(
u'audio repeat list', QtCore.QVariant(False)).toBool())
settings.endGroup() settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.display_changed = False self.display_changed = False
settings.beginGroup(self.settingsSection)
def save(self): def save(self):
""" """
@ -336,8 +337,6 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.autoUnblankCheckBox.isChecked())) QtCore.QVariant(self.autoUnblankCheckBox.isChecked()))
settings.setValue(u'auto preview', settings.setValue(u'auto preview',
QtCore.QVariant(self.autoPreviewCheckBox.isChecked())) QtCore.QVariant(self.autoPreviewCheckBox.isChecked()))
settings.setValue(u'enable slide loop',
QtCore.QVariant(self.enableLoopCheckBox.isChecked()))
settings.setValue(u'loop delay', settings.setValue(u'loop delay',
QtCore.QVariant(self.timeoutSpinBox.value())) QtCore.QVariant(self.timeoutSpinBox.value()))
settings.setValue(u'ccli number', settings.setValue(u'ccli number',
@ -358,6 +357,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.overrideCheckBox.isChecked())) QtCore.QVariant(self.overrideCheckBox.isChecked()))
settings.setValue(u'audio start paused', settings.setValue(u'audio start paused',
QtCore.QVariant(self.startPausedCheckBox.isChecked())) QtCore.QVariant(self.startPausedCheckBox.isChecked()))
settings.setValue(u'audio repeat list',
QtCore.QVariant(self.repeatListCheckBox.isChecked()))
settings.endGroup() settings.endGroup()
# On save update the screens as well # On save update the screens as well
self.postSetUp(True) self.postSetUp(True)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -28,13 +28,16 @@
The :mod:`maindisplay` module provides the functionality to display screens The :mod:`maindisplay` module provides the functionality to display screens
and play multimedia within OpenLP. and play multimedia within OpenLP.
""" """
import cgi
import logging import logging
import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \ from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
translate, PluginManager translate, PluginManager, expand_tags
from openlp.core.lib.theme import BackgroundType
from openlp.core.ui import HideMode, ScreenList, AlertLocation from openlp.core.ui import HideMode, ScreenList, AlertLocation
@ -60,7 +63,12 @@ class Display(QtGui.QGraphicsView):
self.controller = controller self.controller = controller
self.screen = {} self.screen = {}
self.plugins = PluginManager.get_instance().plugins self.plugins = PluginManager.get_instance().plugins
self.setViewport(QtOpenGL.QGLWidget()) # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
# OpenGL. Only white blank screen is shown on the 2nd monitor all the
# time. We need to investigate more how to use OpenGL properly on Mac OS
# X.
if sys.platform != 'darwin':
self.setViewport(QtOpenGL.QGLWidget())
def setup(self): def setup(self):
""" """
@ -74,6 +82,10 @@ class Display(QtGui.QGraphicsView):
self.screen[u'size'].width(), self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.webView.settings().setAttribute( self.webView.settings().setAttribute(
QtWebKit.QWebSettings.PluginsEnabled, True) QtWebKit.QWebSettings.PluginsEnabled, True)
palette = self.webView.palette()
palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent)
self.webView.page().setPalette(palette)
self.webView.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
self.page = self.webView.page() self.page = self.webView.page()
self.frame = self.page.mainFrame() self.frame = self.page.mainFrame()
if self.isLive and log.getEffectiveLevel() == logging.DEBUG: if self.isLive and log.getEffectiveLevel() == logging.DEBUG:
@ -120,10 +132,19 @@ class MainDisplay(Display):
self.audioPlayer = None self.audioPlayer = None
self.firstTime = True self.firstTime = True
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | \
QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.WindowStaysOnTopHint
QtCore.Qt.X11BypassWindowManagerHint) if QtCore.QSettings().value(u'advanced/x11 bypass wm',
QtCore.QVariant(True)).toBool():
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
# FIXME: QtCore.Qt.SplashScreen is workaround to make display screen
# stay always on top on Mac OS X. For details see bug 906926.
# It needs more investigation to fix it properly.
if sys.platform == 'darwin':
windowFlags |= QtCore.Qt.SplashScreen
self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(False)
if self.isLive: if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay) QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay)
@ -134,6 +155,14 @@ class MainDisplay(Display):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configChanged) QtCore.SIGNAL(u'config_updated'), self.configChanged)
def setTransparency(self, enabled):
if enabled:
self.setAutoFillBackground(False)
else:
self.setAttribute(QtCore.Qt.WA_NoSystemBackground, False)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, enabled)
self.repaint()
def cssChanged(self): def cssChanged(self):
""" """
We may need to rebuild the CSS on the live display. We may need to rebuild the CSS on the live display.
@ -222,16 +251,17 @@ class MainDisplay(Display):
The text to be displayed. The text to be displayed.
""" """
log.debug(u'alert to display') log.debug(u'alert to display')
# First we convert <>& marks to html variants, then apply
# formattingtags, finally we double all backslashes for JavaScript.
text_prepared = expand_tags(cgi.escape(text)) \
.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')
if self.height() != self.screen[u'size'].height() or \ if self.height() != self.screen[u'size'].height() or \
not self.isVisible(): not self.isVisible():
shrink = True shrink = True
js = u'show_alert("%s", "%s")' % ( js = u'show_alert("%s", "%s")' % (text_prepared, u'top')
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'),
u'top')
else: else:
shrink = False shrink = False
js = u'show_alert("%s", "")' % ( js = u'show_alert("%s", "")' % text_prepared
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
height = self.frame.evaluateJavaScript(js) height = self.frame.evaluateJavaScript(js)
if shrink: if shrink:
if text: if text:
@ -332,13 +362,7 @@ class MainDisplay(Display):
self.setVisible(True) self.setVisible(True)
else: else:
self.setVisible(True) self.setVisible(True)
preview = QtGui.QPixmap(self.screen[u'size'].width(), return QtGui.QPixmap.grabWidget(self)
self.screen[u'size'].height())
painter = QtGui.QPainter(preview)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
self.frame.render(painter)
painter.end()
return preview
def buildHtml(self, serviceItem, image=None): def buildHtml(self, serviceItem, image=None):
""" """
@ -364,6 +388,8 @@ class MainDisplay(Display):
# replace the background # replace the background
background = self.imageManager. \ background = self.imageManager. \
get_image_bytes(self.override[u'image']) get_image_bytes(self.override[u'image'])
self.setTransparency(self.serviceItem.themedata.background_type ==
BackgroundType.to_string(BackgroundType.Transparent))
if self.serviceItem.themedata.background_filename: if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \ self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name) get_image_bytes(self.serviceItem.themedata.theme_name)
@ -402,6 +428,11 @@ class MainDisplay(Display):
Store the images so they can be replaced when required Store the images so they can be replaced when required
""" """
log.debug(u'hideDisplay mode = %d', mode) log.debug(u'hideDisplay mode = %d', mode)
if self.screens.display_count == 1:
# Only make visible if setting enabled
if not QtCore.QSettings().value(u'general/display on monitor',
QtCore.QVariant(True)).toBool():
return
if mode == HideMode.Screen: if mode == HideMode.Screen:
self.frame.evaluateJavaScript(u'show_blank("desktop");') self.frame.evaluateJavaScript(u'show_blank("desktop");')
self.setVisible(False) self.setVisible(False)
@ -422,6 +453,11 @@ class MainDisplay(Display):
Make the stored images None to release memory. Make the stored images None to release memory.
""" """
log.debug(u'showDisplay') log.debug(u'showDisplay')
if self.screens.display_count == 1:
# Only make visible if setting enabled
if not QtCore.QSettings().value(u'general/display on monitor',
QtCore.QVariant(True)).toBool():
return
self.frame.evaluateJavaScript('show_blank("show");') self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden(): if self.isHidden():
self.setVisible(True) self.setVisible(True)
@ -459,11 +495,15 @@ class AudioPlayer(QtCore.QObject):
QtCore.QObject.__init__(self, parent) QtCore.QObject.__init__(self, parent)
self.currentIndex = -1 self.currentIndex = -1
self.playlist = [] self.playlist = []
self.repeat = False
self.mediaObject = Phonon.MediaObject() self.mediaObject = Phonon.MediaObject()
self.mediaObject.setTickInterval(100)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject) Phonon.createPath(self.mediaObject, self.audioObject)
QtCore.QObject.connect(self.mediaObject, QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish) QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onFinished)
def __del__(self): def __del__(self):
""" """
@ -482,6 +522,14 @@ class AudioPlayer(QtCore.QObject):
if len(self.playlist) > self.currentIndex: if len(self.playlist) > self.currentIndex:
self.mediaObject.enqueue(self.playlist[self.currentIndex]) self.mediaObject.enqueue(self.playlist[self.currentIndex])
def onFinished(self):
if self.repeat:
log.debug(u'Repeat is enabled... here we go again!')
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.currentIndex = -1
self.play()
def connectVolumeSlider(self, slider): def connectVolumeSlider(self, slider):
slider.setAudioOutput(self.audioObject) slider.setAudioOutput(self.audioObject)
@ -529,3 +577,27 @@ class AudioPlayer(QtCore.QObject):
for filename in filenames: for filename in filenames:
self.playlist.append(Phonon.MediaSource(filename)) self.playlist.append(Phonon.MediaSource(filename))
def next(self):
if not self.repeat and self.currentIndex + 1 == len(self.playlist):
return
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.currentIndex += 1
if self.repeat and self.currentIndex == len(self.playlist):
self.currentIndex = 0
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.mediaObject.enqueue(self.playlist[self.currentIndex])
if isPlaying:
self.mediaObject.play()
def goTo(self, index):
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.currentIndex = index
self.mediaObject.enqueue(self.playlist[self.currentIndex])
if isPlaying:
self.mediaObject.play()
def connectSlot(self, signal, slot):
QtCore.QObject.connect(self.mediaObject, signal, slot)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -38,6 +38,7 @@ from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
PluginManager, Receiver, translate, ImageManager, PluginStatus PluginManager, Receiver, translate, ImageManager, PluginStatus
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \ from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
icon_action, shortcut_action icon_action, shortcut_action
from openlp.core.lib import SlideLimits
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm, FormattingTagForm ShortcutListForm, FormattingTagForm
@ -1059,7 +1060,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
export_settings.endGroup() export_settings.endGroup()
# Write all the sections and keys. # Write all the sections and keys.
for section_key in keys: for section_key in keys:
section, key = section_key.split(u'/')
key_value = settings.value(section_key) key_value = settings.value(section_key)
export_settings.setValue(section_key, key_value) export_settings.setValue(section_key, key_value)
export_settings.sync() export_settings.sync()
@ -1307,6 +1307,19 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Load the main window settings. Load the main window settings.
""" """
log.debug(u'Loading QSettings') log.debug(u'Loading QSettings')
# Migrate Wrap Settings to Slide Limits Settings
if QtCore.QSettings().contains(self.generalSettingsSection +
u'/enable slide loop'):
if QtCore.QSettings().value(self.generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool():
QtCore.QSettings().setValue(self.advancedlSettingsSection +
u'/slide limits', QtCore.QVariant(SlideLimits.Wrap))
else:
QtCore.QSettings().setValue(self.advancedlSettingsSection +
u'/slide limits', QtCore.QVariant(SlideLimits.End))
QtCore.QSettings().remove(self.generalSettingsSection +
u'/enable slide loop')
Receiver.send_message(u'slidecontroller_update_slide_limits')
settings = QtCore.QSettings() settings = QtCore.QSettings()
# Remove obsolete entries. # Remove obsolete entries.
settings.remove(u'custom slide') settings.remove(u'custom slide')

View File

@ -100,8 +100,7 @@ class MediaController(object):
Register each media Player controller (Webkit, Phonon, etc) and store Register each media Player controller (Webkit, Phonon, etc) and store
for later use for later use
""" """
if controller.check_available(): self.mediaPlayers[controller.name] = controller
self.mediaPlayers[controller.name] = controller
def check_available_media_players(self): def check_available_media_players(self):
""" """
@ -134,7 +133,8 @@ class MediaController(object):
QtCore.QVariant(u'webkit')).toString()) QtCore.QVariant(u'webkit')).toString())
savedPlayers = playerSettings.split(u',') savedPlayers = playerSettings.split(u',')
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers \ invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers \
if not mediaPlayer in self.mediaPlayers] if not mediaPlayer in self.mediaPlayers or \
not self.mediaPlayers[mediaPlayer].check_available()]
if len(invalidMediaPlayers) > 0: if len(invalidMediaPlayers) > 0:
for invalidPlayer in invalidMediaPlayers: for invalidPlayer in invalidMediaPlayers:
savedPlayers.remove(invalidPlayer) savedPlayers.remove(invalidPlayer)
@ -219,6 +219,7 @@ class MediaController(object):
# Build the seekSlider. # Build the seekSlider.
controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal) controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
controller.seekSlider.setMaximum(1000) controller.seekSlider.setMaximum(1000)
controller.seekSlider.setTracking(False)
controller.seekSlider.setToolTip(translate( controller.seekSlider.setToolTip(translate(
'OpenLP.SlideController', 'Video position.')) 'OpenLP.SlideController', 'Video position.'))
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
@ -231,6 +232,7 @@ class MediaController(object):
controller.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove) controller.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove)
controller.volumeSlider.setMinimum(0) controller.volumeSlider.setMinimum(0)
controller.volumeSlider.setMaximum(100) controller.volumeSlider.setMaximum(100)
controller.volumeSlider.setTracking(True)
controller.volumeSlider.setToolTip(translate( controller.volumeSlider.setToolTip(translate(
'OpenLP.SlideController', 'Audio Volume.')) 'OpenLP.SlideController', 'Audio Volume.'))
controller.volumeSlider.setValue(controller.media_info.volume) controller.volumeSlider.setValue(controller.media_info.volume)
@ -242,9 +244,9 @@ class MediaController(object):
controller.mediabar.setVisible(False) controller.mediabar.setVisible(False)
# Signals # Signals
QtCore.QObject.connect(controller.seekSlider, QtCore.QObject.connect(controller.seekSlider,
QtCore.SIGNAL(u'sliderMoved(int)'), controller.sendToPlugins) QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
QtCore.QObject.connect(controller.volumeSlider, QtCore.QObject.connect(controller.volumeSlider,
QtCore.SIGNAL(u'sliderMoved(int)'), controller.sendToPlugins) QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
def setup_special_controls(self, controller, control_panel): def setup_special_controls(self, controller, control_panel):
""" """
@ -276,6 +278,10 @@ class MediaController(object):
def set_controls_visible(self, controller, value): def set_controls_visible(self, controller, value):
# Generic controls # Generic controls
controller.mediabar.setVisible(value) controller.mediabar.setVisible(value)
if controller.isLive and controller.display:
if self.curDisplayMediaPlayer and value:
if self.curDisplayMediaPlayer[controller.display] != self.mediaPlayers[u'webkit']:
controller.display.setTransparency(False)
# Special controls: Here media type specific Controls will be enabled # Special controls: Here media type specific Controls will be enabled
# (e.g. for DVD control, ...) # (e.g. for DVD control, ...)
# TODO # TODO
@ -316,7 +322,8 @@ class MediaController(object):
controller.media_info.start_time = 0 controller.media_info.start_time = 0
controller.media_info.end_time = 0 controller.media_info.end_time = 0
else: else:
controller.media_info.start_time = display.serviceItem.start_time controller.media_info.start_time = \
display.serviceItem.start_time
controller.media_info.end_time = display.serviceItem.end_time controller.media_info.end_time = display.serviceItem.end_time
elif controller.previewDisplay: elif controller.previewDisplay:
display = controller.previewDisplay display = controller.previewDisplay
@ -478,6 +485,7 @@ class MediaController(object):
Responds to the request to reset a loaded video Responds to the request to reset a loaded video
""" """
log.debug(u'video_reset') log.debug(u'video_reset')
self.set_controls_visible(controller, False)
for display in self.curDisplayMediaPlayer.keys(): for display in self.curDisplayMediaPlayer.keys():
if display.controller == controller: if display.controller == controller:
display.override = {} display.override = {}
@ -486,7 +494,6 @@ class MediaController(object):
display.frame.evaluateJavaScript(u'show_video( \ display.frame.evaluateJavaScript(u'show_video( \
"setBackBoard", null, null, null,"hidden");') "setBackBoard", null, null, null,"hidden");')
del self.curDisplayMediaPlayer[display] del self.curDisplayMediaPlayer[display]
self.set_controls_visible(controller, False)
def video_hide(self, msg): def video_hide(self, msg):
""" """

View File

@ -51,6 +51,7 @@ ADDITIONAL_EXT = {
u'video/x-matroska': [u'.mpv', u'.mkv'], u'video/x-matroska': [u'.mpv', u'.mkv'],
u'video/x-wmv': [u'.wmv'], u'video/x-wmv': [u'.wmv'],
u'video/x-mpg': [u'.mpg'], u'video/x-mpg': [u'.mpg'],
u'video/mpeg' : [u'.mp4', u'.mts'],
u'video/x-ms-wmv': [u'.wmv']} u'video/x-ms-wmv': [u'.wmv']}
@ -153,7 +154,7 @@ class PhononPlayer(MediaPlayer):
int(display.mediaObject.totalTime()/1000) int(display.mediaObject.totalTime()/1000)
controller.seekSlider.setMaximum(controller.media_info.length*1000) controller.seekSlider.setMaximum(controller.media_info.length*1000)
self.state = MediaState.Playing self.state = MediaState.Playing
display.phononWidget.raise_() display.phononWidget.raise_()
return True return True
else: else:
return False return False

6274
openlp/core/ui/media/vlc.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 sys, os
from datetime import datetime
try:
import vlc
vlc_available = bool(vlc.get_default_instance())
except (ImportError, NameError):
vlc_available = False
except OSError, e:
if sys.platform.startswith('win'):
if isinstance(e, WindowsError) and e.winerror == 126:
vlc_available = False
else:
raise
else:
raise
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver
from openlp.core.lib.mediaplayer import MediaPlayer
from openlp.core.ui.media import MediaState
log = logging.getLogger(__name__)
AUDIO_EXT = [
u'*.mp3'
, u'*.wav'
, u'*.ogg'
]
VIDEO_EXT = [
u'*.3gp'
, u'*.asf', u'*.wmv'
, u'*.au'
, u'*.avi'
, u'*.flv'
, u'*.mov'
, u'*.mp4'
, u'*.ogm'
, u'*.mkv', u'*.mka'
, u'*.ts', u'*.mpg'
, u'*.mpg', u'*.mp2'
, u'*.nsc'
, u'*.nsv'
, u'*.nut'
, u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv'
, u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid'
, u'*.tta', u'*.tac'
, u'*.ty'
, u'*.dts'
, u'*.xa'
, u'*.iso'
, u'*.vob'
]
class VlcPlayer(MediaPlayer):
"""
A specialised version of the MediaPlayer class, which provides a QtWebKit
display.
"""
def __init__(self, parent):
MediaPlayer.__init__(self, parent, u'vlc')
self.parent = parent
self.canFolder = True
self.audio_extensions_list = AUDIO_EXT
self.video_extensions_list = VIDEO_EXT
def setup(self, display):
display.vlcWidget = QtGui.QFrame(display)
# creating a basic vlc instance
command_line_options = u'--no-video-title-show'
if not display.hasAudio:
command_line_options += u' --no-audio --no-video-title-show'
if QtCore.QSettings().value(u'advanced/hide mouse',
QtCore.QVariant(False)).toBool() and \
display.controller.isLive:
command_line_options += u' --mouse-hide-timeout=0'
display.vlcInstance = vlc.Instance(command_line_options)
display.vlcInstance.set_log_verbosity(2)
# creating an empty vlc media player
display.vlcMediaPlayer = display.vlcInstance.media_player_new()
display.vlcWidget.resize(display.size())
display.vlcWidget.raise_()
display.vlcWidget.hide()
# the media player has to be 'connected' to the QFrame
# (otherwise a video would be displayed in it's own window)
# this is platform specific!
# you have to give the id of the QFrame (or similar object) to
# vlc, different platforms have different functions for this
if sys.platform == "win32": # for Windows
display.vlcMediaPlayer.set_hwnd(int(display.vlcWidget.winId()))
elif sys.platform == "darwin": # for MacOS
display.vlcMediaPlayer.set_agl(int(display.vlcWidget.winId()))
else:
# for Linux using the X Server
display.vlcMediaPlayer.set_xwindow(int(display.vlcWidget.winId()))
self.hasOwnWidget = True
def check_available(self):
return vlc_available
def load(self, display):
log.debug(u'load vid in Vlc Controller')
controller = display.controller
volume = controller.media_info.volume
file_path = str(
controller.media_info.file_info.absoluteFilePath().toUtf8())
path = os.path.normcase(file_path)
# create the media
display.vlcMedia = display.vlcInstance.media_new_path(path)
# put the media in the media player
display.vlcMediaPlayer.set_media(display.vlcMedia)
# parse the metadata of the file
display.vlcMedia.parse()
self.volume(display, volume)
return True
def media_state_wait(self, display, mediaState):
"""
Wait for the video to change its state
Wait no longer than 60 seconds. (loading an iso file needs a long time)
"""
start = datetime.now()
while not mediaState == display.vlcMedia.get_state():
if display.vlcMedia.get_state() == vlc.State.Error:
return False
Receiver.send_message(u'openlp_process_events')
if (datetime.now() - start).seconds > 60:
return False
return True
def resize(self, display):
display.vlcWidget.resize(display.size())
def play(self, display):
controller = display.controller
start_time = 0
if controller.media_info.start_time > 0:
start_time = controller.media_info.start_time
display.vlcMediaPlayer.play()
if self.media_state_wait(display, vlc.State.Playing):
if start_time > 0:
self.seek(display, controller.media_info.start_time * 1000)
controller.media_info.length = \
int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
controller.seekSlider.setMaximum(controller.media_info.length * 1000)
self.state = MediaState.Playing
display.vlcWidget.raise_()
return True
else:
return False
def pause(self, display):
if display.vlcMedia.get_state() != vlc.State.Playing:
return
display.vlcMediaPlayer.pause()
if self.media_state_wait(display, vlc.State.Paused):
self.state = MediaState.Paused
def stop(self, display):
display.vlcMediaPlayer.stop()
self.state = MediaState.Stopped
def volume(self, display, vol):
if display.hasAudio:
display.vlcMediaPlayer.audio_set_volume(vol)
def seek(self, display, seekVal):
if display.vlcMediaPlayer.is_seekable():
display.vlcMediaPlayer.set_time(seekVal)
def reset(self, display):
display.vlcMediaPlayer.stop()
display.vlcWidget.setVisible(False)
self.state = MediaState.Off
def set_visible(self, display, status):
if self.hasOwnWidget:
display.vlcWidget.setVisible(status)
def update_ui(self, display):
controller = display.controller
if controller.media_info.end_time > 0:
if display.vlcMediaPlayer.get_time() > \
controller.media_info.end_time * 1000:
self.stop(display)
self.set_visible(display, False)
if not controller.seekSlider.isSliderDown():
controller.seekSlider.setSliderPosition( \
display.vlcMediaPlayer.get_time())

View File

@ -294,7 +294,7 @@ class WebkitPlayer(MediaPlayer):
def load(self, display): def load(self, display):
log.debug(u'load vid in Webkit Controller') log.debug(u'load vid in Webkit Controller')
controller = display.controller controller = display.controller
if display.hasAudio: if display.hasAudio and not controller.media_info.is_background:
volume = controller.media_info.volume volume = controller.media_info.volume
vol = float(volume) / float(100) vol = float(volume) / float(100)
else: else:

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -222,6 +222,21 @@ class ScreenList(object):
log.debug(u'reset_current_display') log.debug(u'reset_current_display')
self.set_current_display(self.current[u'number']) self.set_current_display(self.current[u'number'])
def which_screen(self, window):
"""
Return the screen number that the centre of the passed window is in.
``window``
A QWidget we are finding the location of.
"""
x = window.x() + (window.width() / 2)
y = window.y() + (window.height() / 2)
for screen in self.screen_list:
size = screen[u'size']
if x >= size.x() and x <= (size.x() + size.width()) \
and y >= size.y() and y <= (size.y() + size.height()):
return screen[u'number']
def _load_screen_settings(self): def _load_screen_settings(self):
""" """
Loads the screen size and the monitor number from the settings. Loads the screen size and the monitor number from the settings.

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -31,6 +31,7 @@ import os
import shutil import shutil
import zipfile import zipfile
from tempfile import mkstemp from tempfile import mkstemp
from datetime import datetime, timedelta
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -43,8 +44,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator, find_and_set_in_combo_box context_menu_action, context_menu_separator, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceform import PrintServiceForm from openlp.core.ui.printserviceform import PrintServiceForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, split_filename
split_filename
from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.utils.actions import ActionList, CategoryOrder
class ServiceManagerList(QtGui.QTreeWidget): class ServiceManagerList(QtGui.QTreeWidget):
@ -596,7 +596,10 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.finishedProgressBar() self.mainwindow.finishedProgressBar()
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
if success: if success:
shutil.copy(temp_file_name, path_file_name) try:
shutil.copy(temp_file_name, path_file_name)
except:
return self.saveFileAs()
self.mainwindow.addRecentFile(path_file_name) self.mainwindow.addRecentFile(path_file_name)
self.setModified(False) self.setModified(False)
try: try:
@ -610,10 +613,44 @@ class ServiceManager(QtGui.QWidget):
Get a file name and then call :func:`ServiceManager.saveFile` to Get a file name and then call :func:`ServiceManager.saveFile` to
save the file. save the file.
""" """
default_service_enabled = QtCore.QSettings().value(
u'advanced/default service enabled', QtCore.QVariant(True)).toBool()
if default_service_enabled:
service_day = QtCore.QSettings().value(
u'advanced/default service day', 7).toInt()[0]
if service_day == 7:
time = datetime.now()
else:
service_hour = QtCore.QSettings().value(
u'advanced/default service hour', 11).toInt()[0]
service_minute = QtCore.QSettings().value(
u'advanced/default service minute', 0).toInt()[0]
now = datetime.now()
day_delta = service_day - now.weekday()
if day_delta < 0:
day_delta += 7
time = now + timedelta(days=day_delta)
time = time.replace(hour=service_hour, minute=service_minute)
default_pattern = unicode(QtCore.QSettings().value(
u'advanced/default service name',
translate('OpenLP.AdvancedTab',
'Service %Y-%m-%d %H-%M',
'This is the default default service name template, which can '
'be found under Advanced in Settings, Configure OpenLP. '
'Please do not include any of the following characters: '
'/\\?*|<>\[\]":+\n'
'You can use any of the directives as shown on page '
'http://docs.python.org/library/datetime.html'
'#strftime-strptime-behavior , but if possible, please keep '
'the resulting string sortable by name.')).toString())
default_filename = time.strftime(default_pattern)
else:
default_filename = u''
directory = unicode(SettingsManager.get_last_dir(
self.mainwindow.servicemanagerSettingsSection))
path = os.path.join(directory, default_filename)
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
UiStrings().SaveService, UiStrings().SaveService, path,
SettingsManager.get_last_dir(
self.mainwindow.servicemanagerSettingsSection),
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
if not fileName: if not fileName:
return False return False
@ -636,8 +673,11 @@ class ServiceManager(QtGui.QWidget):
try: try:
zip = zipfile.ZipFile(fileName) zip = zipfile.ZipFile(fileName)
for zipinfo in zip.infolist(): for zipinfo in zip.infolist():
ucsfile = file_is_unicode(zipinfo.filename) try:
if not ucsfile: ucsfile = zipinfo.filename.decode(u'utf-8')
except UnicodeDecodeError:
log.exception(u'Filename "%s" is not valid UTF-8' %
zipinfo.filename.decode(u'utf-8', u'replace'))
critical_error_message_box( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.\n' 'File is not a valid service.\n'
@ -821,7 +861,7 @@ class ServiceManager(QtGui.QWidget):
lookFor = 1 lookFor = 1
serviceIterator += 1 serviceIterator += 1
def previousItem(self): def previousItem(self, message):
""" """
Called by the SlideController to select the previous service item. Called by the SlideController to select the previous service item.
""" """
@ -829,15 +869,26 @@ class ServiceManager(QtGui.QWidget):
return return
selected = self.serviceManagerList.selectedItems()[0] selected = self.serviceManagerList.selectedItems()[0]
prevItem = None prevItem = None
prevItemLastSlide = None
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
while serviceIterator.value(): while serviceIterator.value():
if serviceIterator.value() == selected: if serviceIterator.value() == selected:
if prevItem: if message == u'last slide' and prevItemLastSlide:
pos = prevItem.data(0, QtCore.Qt.UserRole).toInt()[0]
check_expanded = self.serviceItems[pos - 1][u'expanded']
self.serviceManagerList.setCurrentItem(prevItemLastSlide)
if not check_expanded:
self.serviceManagerList.collapseItem(prevItem)
self.makeLive()
self.serviceManagerList.setCurrentItem(prevItem)
elif prevItem:
self.serviceManagerList.setCurrentItem(prevItem) self.serviceManagerList.setCurrentItem(prevItem)
self.makeLive() self.makeLive()
return return
if serviceIterator.value().parent() is None: if serviceIterator.value().parent() is None:
prevItem = serviceIterator.value() prevItem = serviceIterator.value()
if serviceIterator.value().parent() is prevItem:
prevItemLastSlide = serviceIterator.value()
serviceIterator += 1 serviceIterator += 1
def onSetItem(self, message): def onSetItem(self, message):

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -344,8 +344,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
if category.name is None: if category.name is None:
continue continue
for action in category.actions: for action in category.actions:
if self.changedActions .has_key(action): if action in self.changedActions:
old_shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
action.setShortcuts(self.changedActions[action]) action.setShortcuts(self.changedActions[action])
self.action_list.update_shortcut_map(action, old_shortcuts)
settings.setValue( settings.setValue(
action.objectName(), QtCore.QVariant(action.shortcuts())) action.objectName(), QtCore.QVariant(action.shortcuts()))
settings.endGroup() settings.endGroup()
@ -452,7 +455,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
those shortcuts which are not saved yet but already assigned (as changes those shortcuts which are not saved yet but already assigned (as changes
are applied when closing the dialog). are applied when closing the dialog).
""" """
if self.changedActions.has_key(action): if action in self.changedActions:
return self.changedActions[action] return self.changedActions[action]
return action.shortcuts() return action.shortcuts()

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -33,8 +33,9 @@ from collections import deque
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \ from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem translate, build_icon, build_html, PluginManager, ServiceItem
from openlp.core.lib.ui import UiStrings, shortcut_action from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.lib import SlideLimits, ServiceItemAction
from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList
from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.utils.actions import ActionList, CategoryOrder
@ -45,9 +46,10 @@ class SlideList(QtGui.QTableWidget):
Customised version of QTableWidget which can respond to keyboard Customised version of QTableWidget which can respond to keyboard
events. events.
""" """
def __init__(self, parent=None, name=None): def __init__(self, parent=None):
QtGui.QTableWidget.__init__(self, parent.controller) QtGui.QTableWidget.__init__(self, parent.controller)
class Controller(QtGui.QWidget): class Controller(QtGui.QWidget):
""" """
Controller is a general controller widget. Controller is a general controller widget.
@ -82,8 +84,11 @@ class SlideController(Controller):
""" """
Controller.__init__(self, parent, isLive) Controller.__init__(self, parent, isLive)
self.screens = ScreenList.get_instance() self.screens = ScreenList.get_instance()
self.ratio = float(self.screens.current[u'size'].width()) / \ try:
float(self.screens.current[u'size'].height()) self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height())
except ZeroDivisionError:
self.ratio = 1
self.imageManager = self.parent().imageManager self.imageManager = self.parent().imageManager
self.mediaController = self.parent().mediaController self.mediaController = self.parent().mediaController
self.loopList = [ self.loopList = [
@ -95,13 +100,15 @@ class SlideController(Controller):
u'Edit Song', u'Edit Song',
] ]
self.nextPreviousList = [ self.nextPreviousList = [
u'Previous Slide', u'Previous Slide',
u'Next Slide' u'Next Slide'
] ]
self.timer_id = 0 self.timer_id = 0
self.songEdit = False self.songEdit = False
self.selectedRow = 0 self.selectedRow = 0
self.serviceItem = None self.serviceItem = None
self.slide_limits = None
self.updateSlideLimits()
self.panel = QtGui.QWidget(parent.controlSplitter) self.panel = QtGui.QWidget(parent.controlSplitter)
self.slideList = {} self.slideList = {}
# Layout for holding panel # Layout for holding panel
@ -114,8 +121,8 @@ class SlideController(Controller):
self.typeLabel.setText(UiStrings().Live) self.typeLabel.setText(UiStrings().Live)
self.split = 1 self.split = 1
self.typePrefix = u'live' self.typePrefix = u'live'
self.keypress_queue = deque() self.keypress_queue = deque()
self.keypress_loop = False self.keypress_loop = False
else: else:
self.typeLabel.setText(UiStrings().Preview) self.typeLabel.setText(UiStrings().Preview)
self.split = 0 self.split = 0
@ -187,7 +194,7 @@ class SlideController(Controller):
translate('OpenLP.SlideController', 'Hide'), self.toolbar)) translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen', self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
[QtCore.Qt.Key_Period], self.onBlankDisplay, [QtCore.Qt.Key_Period], self.onBlankDisplay,
u':/slides/slide_blank.png', False, u':/slides/slide_blank.png', False,
unicode(UiStrings().LiveToolbar)) unicode(UiStrings().LiveToolbar))
self.blankScreen.setText( self.blankScreen.setText(
translate('OpenLP.SlideController', 'Blank Screen')) translate('OpenLP.SlideController', 'Blank Screen'))
@ -271,13 +278,48 @@ class SlideController(Controller):
self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu) self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
self.songMenu.setMenu(QtGui.QMenu( self.songMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Go To'), self.toolbar)) translate('OpenLP.SlideController', 'Go To'), self.toolbar))
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
# Stuff for items with background audio. # Stuff for items with background audio.
self.audioPauseItem = self.toolbar.addToolbarButton( self.audioPauseItem = QtGui.QToolButton(self.toolbar)
u'Pause Audio', u':/slides/media_playback_pause.png', self.audioPauseItem.setIcon(
translate('OpenLP.SlideController', 'Pause audio.'), QtGui.QIcon(u':/slides/media_playback_pause.png'))
self.onAudioPauseClicked, True) self.audioPauseItem.setText(translate('OpenLP.SlideController',
'Pause audio.'))
self.audioPauseItem.setCheckable(True)
self.toolbar.addToolbarWidget(u'Pause Audio', self.audioPauseItem)
QtCore.QObject.connect(self.audioPauseItem,
QtCore.SIGNAL(u'clicked(bool)'), self.onAudioPauseClicked)
self.audioPauseItem.setVisible(False) self.audioPauseItem.setVisible(False)
self.audioMenu = QtGui.QMenu(
translate('OpenLP.SlideController', 'Background Audio'),
self.toolbar)
self.nextTrackItem = shortcut_action(self.audioMenu,
u'nextTrackItem', [], self.onNextTrackClicked,
u':/slides/media_playback_next.png',
category=unicode(UiStrings().LiveToolbar))
self.nextTrackItem.setText(
translate('OpenLP.SlideController', 'Next Track'))
self.audioMenu.addAction(self.nextTrackItem)
self.trackMenu = self.audioMenu.addMenu(
translate('OpenLP.SlideController', 'Tracks'))
self.audioPauseItem.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.audioPauseItem.setMenu(self.audioMenu)
self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar)
self.audioTimeLabel.setAlignment(
QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter)
self.audioTimeLabel.setStyleSheet(
u'background-color: palette(background); '
u'border-top-color: palette(shadow); '
u'border-left-color: palette(shadow); '
u'border-bottom-color: palette(light); '
u'border-right-color: palette(light); '
u'border-radius: 3px; border-style: inset; '
u'border-width: 1; font-family: monospace; margin: 2px;'
)
self.audioTimeLabel.setObjectName(u'audioTimeLabel')
self.toolbar.addToolbarWidget(
u'Time Remaining', self.audioTimeLabel)
self.toolbar.makeWidgetsInvisible([u'Song Menu', u'Pause Audio',
u'Time Remaining'])
# Screen preview area # Screen preview area
self.previewFrame = QtGui.QFrame(self.splitter) self.previewFrame = QtGui.QFrame(self.splitter)
self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio)) self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
@ -412,6 +454,9 @@ class SlideController(Controller):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'), QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
self.receiveSpinDelay) self.receiveSpinDelay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_toggle_display'),
self.toggleDisplay)
self.toolbar.makeWidgetsInvisible(self.loopList) self.toolbar.makeWidgetsInvisible(self.loopList)
else: else:
QtCore.QObject.connect(self.previewListWidget, QtCore.QObject.connect(self.previewListWidget,
@ -447,6 +492,9 @@ class SlideController(Controller):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.typePrefix), QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.typePrefix),
self.onSlideUnblank) self.onSlideUnblank)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_update_slide_limits'),
self.updateSlideLimits)
def slideShortcutActivated(self): def slideShortcutActivated(self):
""" """
@ -532,7 +580,7 @@ class SlideController(Controller):
# Reset the shortcut. # Reset the shortcut.
self.current_shortcut = u'' self.current_shortcut = u''
def setPreviewHotkeys(self, parent=None): def setPreviewHotkeys(self):
self.previousItem.setObjectName(u'previousItemPreview') self.previousItem.setObjectName(u'previousItemPreview')
self.nextItem.setObjectName(u'nextItemPreview') self.nextItem.setObjectName(u'nextItemPreview')
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
@ -570,18 +618,33 @@ class SlideController(Controller):
self.display.setVisible(False) self.display.setVisible(False)
self.mediaController.video_stop([self]) self.mediaController.video_stop([self])
def toggleDisplay(self, action):
"""
Toggle the display settings triggered from remote messages.
"""
if action == u'blank' or action == u'hide':
self.onBlankDisplay(True)
elif action == u'theme':
self.onThemeDisplay(True)
elif action == u'desktop':
self.onHideDisplay(True)
elif action == u'show':
self.onBlankDisplay(False)
self.onThemeDisplay(False)
self.onHideDisplay(False)
def servicePrevious(self): def servicePrevious(self):
""" """
Live event to select the previous service item from the service manager. Live event to select the previous service item from the service manager.
""" """
self.keypress_queue.append(u'previous') self.keypress_queue.append(ServiceItemAction.Previous)
self._process_queue() self._process_queue()
def serviceNext(self): def serviceNext(self):
""" """
Live event to select the next service item from the service manager. Live event to select the next service item from the service manager.
""" """
self.keypress_queue.append(u'next') self.keypress_queue.append(ServiceItemAction.Next)
self._process_queue() self._process_queue()
def _process_queue(self): def _process_queue(self):
@ -592,8 +655,12 @@ class SlideController(Controller):
if len(self.keypress_queue): if len(self.keypress_queue):
while len(self.keypress_queue) and not self.keypress_loop: while len(self.keypress_queue) and not self.keypress_loop:
self.keypress_loop = True self.keypress_loop = True
if self.keypress_queue.popleft() == u'previous': keypressCommand = self.keypress_queue.popleft()
if keypressCommand == ServiceItemAction.Previous:
Receiver.send_message('servicemanager_previous_item') Receiver.send_message('servicemanager_previous_item')
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
# Go to the last slide of the previous item
Receiver.send_message('servicemanager_previous_item', u'last slide')
else: else:
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
self.keypress_loop = False self.keypress_loop = False
@ -611,15 +678,20 @@ class SlideController(Controller):
self.display.setup() self.display.setup()
if self.isLive: if self.isLive:
self.__addActionsToWidget(self.display) self.__addActionsToWidget(self.display)
self.display.audioPlayer.connectSlot(
QtCore.SIGNAL(u'tick(qint64)'), self.onAudioTimeRemaining)
# The SlidePreview's ratio. # The SlidePreview's ratio.
self.ratio = float(self.screens.current[u'size'].width()) / \ try:
float(self.screens.current[u'size'].height()) self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height())
except ZeroDivisionError:
self.ratio = 1
self.mediaController.setup_display(self.display) self.mediaController.setup_display(self.display)
self.previewSizeChanged() self.previewSizeChanged()
self.previewDisplay.setup() self.previewDisplay.setup()
serviceItem = ServiceItem() serviceItem = ServiceItem()
self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.webView.setHtml(build_html(serviceItem,
self.previewDisplay.screen, None, self.isLive, None, self.previewDisplay.screen, None, self.isLive,
plugins=PluginManager.get_instance().plugins)) plugins=PluginManager.get_instance().plugins))
self.mediaController.setup_display(self.previewDisplay) self.mediaController.setup_display(self.previewDisplay)
if self.serviceItem: if self.serviceItem:
@ -682,6 +754,14 @@ class SlideController(Controller):
""" """
self.delaySpinBox.setValue(int(value)) self.delaySpinBox.setValue(int(value))
def updateSlideLimits(self):
"""
Updates the Slide Limits variable from the settings.
"""
self.slide_limits = QtCore.QSettings().value(
self.parent().advancedlSettingsSection + u'/slide limits',
QtCore.QVariant(SlideLimits.End)).toInt()[0]
def enableToolBar(self, item): def enableToolBar(self, item):
""" """
Allows the toolbars to be reconfigured based on Controller Type Allows the toolbars to be reconfigured based on Controller Type
@ -818,10 +898,23 @@ class SlideController(Controller):
self.display.audioPlayer.reset() self.display.audioPlayer.reset()
self.setAudioItemsVisibility(False) self.setAudioItemsVisibility(False)
self.audioPauseItem.setChecked(False) self.audioPauseItem.setChecked(False)
# If the current item has background audio
if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio): if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug(u'Starting to play...') log.debug(u'Starting to play...')
self.display.audioPlayer.addToPlaylist( self.display.audioPlayer.addToPlaylist(
self.serviceItem.background_audio) self.serviceItem.background_audio)
self.trackMenu.clear()
for counter in range(len(self.serviceItem.background_audio)):
action = self.trackMenu.addAction(os.path.basename(
self.serviceItem.background_audio[counter]))
action.setData(counter)
QtCore.QObject.connect(action,
QtCore.SIGNAL(u'triggered(bool)'),
self.onTrackTriggered)
self.display.audioPlayer.repeat = QtCore.QSettings().value(
self.parent().generalSettingsSection + \
u'/audio repeat list',
QtCore.QVariant(False)).toBool()
if QtCore.QSettings().value( if QtCore.QSettings().value(
self.parent().generalSettingsSection + \ self.parent().generalSettingsSection + \
u'/audio start paused', u'/audio start paused',
@ -873,7 +966,7 @@ class SlideController(Controller):
self.slideList[unicode(row)] = row - 1 self.slideList[unicode(row)] = row - 1
text.append(unicode(row)) text.append(unicode(row))
self.previewListWidget.setItem(framenumber, 0, item) self.previewListWidget.setItem(framenumber, 0, item)
if slideHeight != 0: if not slideHeight:
self.previewListWidget.setRowHeight(framenumber, slideHeight) self.previewListWidget.setRowHeight(framenumber, slideHeight)
self.previewListWidget.setVerticalHeaderLabels(text) self.previewListWidget.setVerticalHeaderLabels(text)
if self.serviceItem.is_text(): if self.serviceItem.is_text():
@ -938,7 +1031,8 @@ class SlideController(Controller):
display_type = QtCore.QSettings().value( display_type = QtCore.QSettings().value(
self.parent().generalSettingsSection + u'/screen blank', self.parent().generalSettingsSection + u'/screen blank',
QtCore.QVariant(u'')).toString() QtCore.QVariant(u'')).toString()
if not self.display.primary: if self.screens.which_screen(self.window()) != \
self.screens.which_screen(self.display):
# Order done to handle initial conversion # Order done to handle initial conversion
if display_type == u'themed': if display_type == u'themed':
self.onThemeDisplay(True) self.onThemeDisplay(True)
@ -949,7 +1043,7 @@ class SlideController(Controller):
else: else:
Receiver.send_message(u'live_display_show') Receiver.send_message(u'live_display_show')
else: else:
Receiver.send_message(u'live_display_hide', HideMode.Screen) self.liveEscape()
def onSlideBlank(self): def onSlideBlank(self):
""" """
@ -1074,7 +1168,7 @@ class SlideController(Controller):
else: else:
Receiver.send_message(u'live_display_show') Receiver.send_message(u'live_display_show')
def onSlideSelected(self, start=False): def onSlideSelected(self):
""" """
Slide selected in controller Slide selected in controller
""" """
@ -1158,10 +1252,14 @@ class SlideController(Controller):
row = self.previewListWidget.currentRow() + 1 row = self.previewListWidget.currentRow() + 1
if row == self.previewListWidget.rowCount(): if row == self.previewListWidget.rowCount():
if wrap is None: if wrap is None:
wrap = QtCore.QSettings().value( if self.slide_limits == SlideLimits.Wrap:
self.parent().generalSettingsSection + row = 0
u'/enable slide loop', QtCore.QVariant(True)).toBool() elif self.isLive and self.slide_limits == SlideLimits.Next:
if wrap: self.serviceNext()
return
else:
row = self.previewListWidget.rowCount() - 1
elif wrap:
row = 0 row = 0
else: else:
row = self.previewListWidget.rowCount() - 1 row = self.previewListWidget.rowCount() - 1
@ -1181,9 +1279,12 @@ class SlideController(Controller):
else: else:
row = self.previewListWidget.currentRow() - 1 row = self.previewListWidget.currentRow() - 1
if row == -1: if row == -1:
if QtCore.QSettings().value(self.parent().generalSettingsSection if self.slide_limits == SlideLimits.Wrap:
+ u'/enable slide loop', QtCore.QVariant(True)).toBool():
row = self.previewListWidget.rowCount() - 1 row = self.previewListWidget.rowCount() - 1
elif self.isLive and self.slide_limits == SlideLimits.Next:
self.keypress_queue.append(ServiceItemAction.PreviousLastSlide)
self._process_queue()
return
else: else:
row = 0 row = 0
self.__checkUpdateSelectedSlide(row) self.__checkUpdateSelectedSlide(row)
@ -1263,7 +1364,12 @@ class SlideController(Controller):
self.onToggleLoop() self.onToggleLoop()
def setAudioItemsVisibility(self, visible): def setAudioItemsVisibility(self, visible):
self.audioPauseItem.setVisible(visible) if visible:
self.toolbar.makeWidgetsVisible(
[u'Song Menu', u'Pause Audio', u'Time Remaining'])
else:
self.toolbar.makeWidgetsInvisible(
[u'Song Menu', u'Pause Audio', u'Time Remaining'])
def onAudioPauseClicked(self, checked): def onAudioPauseClicked(self, checked):
if not self.audioPauseItem.isVisible(): if not self.audioPauseItem.isVisible():
@ -1374,3 +1480,17 @@ class SlideController(Controller):
return HideMode.Screen return HideMode.Screen
else: else:
return None return None
def onNextTrackClicked(self):
self.display.audioPlayer.next()
def onAudioTimeRemaining(self, time):
seconds = self.display.audioPlayer.mediaObject.remainingTime() // 1000
minutes = seconds // 60
seconds %= 60
self.audioTimeLabel.setText(u' %02d:%02d ' % (minutes, seconds))
def onTrackTriggered(self):
action = self.sender()
index = action.data().toInt()[0]
self.display.audioPlayer.goTo(index)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -359,11 +359,15 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.gradientEndButton.setStyleSheet(u'background-color: %s' % self.gradientEndButton.setStyleSheet(u'background-color: %s' %
self.theme.background_end_color) self.theme.background_end_color)
self.setField(u'background_type', QtCore.QVariant(1)) self.setField(u'background_type', QtCore.QVariant(1))
else: elif self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Image):
self.imageColorButton.setStyleSheet(u'background-color: %s' % self.imageColorButton.setStyleSheet(u'background-color: %s' %
self.theme.background_border_color) self.theme.background_border_color)
self.imageFileEdit.setText(self.theme.background_filename) self.imageFileEdit.setText(self.theme.background_filename)
self.setField(u'background_type', QtCore.QVariant(2)) self.setField(u'background_type', QtCore.QVariant(2))
elif self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Transparent):
self.setField(u'background_type', QtCore.QVariant(3))
if self.theme.background_direction == \ if self.theme.background_direction == \
BackgroundGradientType.to_string(BackgroundGradientType.Horizontal): BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
self.setField(u'gradient', QtCore.QVariant(0)) self.setField(u'gradient', QtCore.QVariant(0))

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -30,6 +30,7 @@ import zipfile
import shutil import shutil
import logging import logging
import locale import locale
import re
from xml.etree.ElementTree import ElementTree, XML from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -43,8 +44,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator context_menu_action, context_menu_separator
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
get_filesystem_encoding
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -147,6 +147,7 @@ class ThemeManager(QtGui.QWidget):
check_directory_exists(self.thumbPath) check_directory_exists(self.thumbPath)
self.themeForm.path = self.path self.themeForm.path = self.path
self.oldBackgroundImage = None self.oldBackgroundImage = None
self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
# Last little bits of setting up # Last little bits of setting up
self.configUpdated() self.configUpdated()
@ -524,44 +525,50 @@ class ThemeManager(QtGui.QWidget):
filexml = None filexml = None
try: try:
zip = zipfile.ZipFile(filename) zip = zipfile.ZipFile(filename)
themename = None xmlfile = filter(lambda name:
for file in zip.namelist(): os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
# Handle UTF-8 files if len(xmlfile) != 1:
ucsfile = file_is_unicode(file) log.exception(u'Theme contains "%s" XML files' % len(xmlfile))
if not ucsfile: raise Exception(u'validation')
# Handle native Unicode files from Windows xml_tree = ElementTree(element=XML(zip.read(xmlfile[0]))).getroot()
ucsfile = file v1_background = xml_tree.find(u'BackgroundType')
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) if v1_background is not None:
theme_dir = None (themename, filexml, outfile) = self.unzipVersion122(dir, zip,
if osfile.endswith(os.path.sep): xmlfile[0], xml_tree, v1_background, outfile)
theme_dir = os.path.join(dir, osfile) else:
check_directory_exists(theme_dir) themename = xml_tree.find(u'name').text.strip()
else: for name in zip.namelist():
fullpath = os.path.join(dir, osfile) try:
names = osfile.split(os.path.sep) uname = unicode(name, u'utf-8')
if len(names) > 1: except UnicodeDecodeError:
# not preview file log.exception(u'Theme file contains non utf-8 filename'
if themename is None: u' "%s"' % name.decode(u'utf-8', u'replace'))
themename = names[0] raise Exception(u'validation')
if theme_dir is None: uname = unicode(QtCore.QDir.toNativeSeparators(uname))
theme_dir = os.path.join(dir, names[0]) splitname = uname.split(os.path.sep)
check_directory_exists(theme_dir) if splitname[-1] == u'' or len(splitname) == 1:
if os.path.splitext(ucsfile)[1].lower() in [u'.xml']: # is directory or preview file
xml_data = zip.read(file) continue
xml_data = file_is_unicode(xml_data) fullname = os.path.join(dir, uname)
if not xml_data: check_directory_exists(os.path.dirname(fullname))
break if os.path.splitext(uname)[1].lower() == u'.xml':
filexml = self._checkVersionAndConvert(xml_data) filexml = unicode(zip.read(name), u'utf-8')
outfile = open(fullpath, u'w') outfile = open(fullname, u'w')
outfile.write(filexml.encode(u'utf-8')) outfile.write(filexml.encode(u'utf-8'))
else: else:
outfile = open(fullpath, u'wb') outfile = open(fullname, u'wb')
outfile.write(zip.read(file)) outfile.write(zip.read(name))
except (IOError, NameError, zipfile.BadZipfile): outfile.close()
critical_error_message_box( except (IOError, zipfile.BadZipfile):
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
log.exception(u'Importing theme from zip failed %s' % filename) log.exception(u'Importing theme from zip failed %s' % filename)
raise Exception(u'validation')
except Exception as info:
if unicode(info) == u'validation':
critical_error_message_box(translate('OpenLP.ThemeManager',
'Validation Error'), translate('OpenLP.ThemeManager',
'File is not a valid theme.'))
else:
raise
finally: finally:
# Close the files, to be able to continue creating the theme. # Close the files, to be able to continue creating the theme.
if zip: if zip:
@ -582,6 +589,36 @@ class ThemeManager(QtGui.QWidget):
log.exception(u'Theme file does not contain XML data %s' % log.exception(u'Theme file does not contain XML data %s' %
filename) filename)
def unzipVersion122(self, dir, zip, xmlfile, xml_tree, background, outfile):
"""
Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
this method, please keep in mind, that some parameters are redundant.
"""
themename = xml_tree.find(u'Name').text.strip()
themename = self.bad_v1_name_chars.sub(u'', themename)
themedir = os.path.join(dir, themename)
check_directory_exists(themedir)
filexml = unicode(zip.read(xmlfile), u'utf-8')
filexml = self._migrateVersion122(filexml)
outfile = open(os.path.join(themedir, themename + u'.xml'), u'w')
outfile.write(filexml.encode(u'utf-8'))
outfile.close()
if background.text.strip() == u'2':
imagename = xml_tree.find(u'BackgroundParameter1').text.strip()
# image file has same extension and is in subfolder
imagefile = filter(lambda name: os.path.splitext(name)[1].lower()
== os.path.splitext(imagename)[1].lower() and name.find(r'/'),
zip.namelist())
if len(imagefile) >= 1:
outfile = open(os.path.join(themedir, imagename), u'wb')
outfile.write(zip.read(imagefile[0]))
outfile.close()
else:
log.exception(u'Theme file does not contain image file "%s"' %
imagename.decode(u'utf-8', u'replace'))
raise Exception(u'validation')
return (themename, filexml, outfile)
def checkIfThemeExists(self, themeName): def checkIfThemeExists(self, themeName):
""" """
Check if theme already exists and displays error message Check if theme already exists and displays error message
@ -692,22 +729,6 @@ class ThemeManager(QtGui.QWidget):
image = os.path.join(self.path, theme + u'.png') image = os.path.join(self.path, theme + u'.png')
return image return image
def _checkVersionAndConvert(self, xml_data):
"""
Check if a theme is from OpenLP version 1
``xml_data``
Theme XML to check the version of
"""
log.debug(u'checkVersion1 ')
theme = xml_data.encode(u'ascii', u'xmlcharrefreplace')
tree = ElementTree(element=XML(theme)).getroot()
# look for old version 1 tags
if tree.find(u'BackgroundType') is None:
return xml_data
else:
return self._migrateVersion122(xml_data)
def _createThemeFromXml(self, themeXml, path): def _createThemeFromXml(self, themeXml, path):
""" """
Return a theme object using information parsed from XML Return a theme object using information parsed from XML
@ -772,7 +793,7 @@ class ThemeManager(QtGui.QWidget):
""" """
theme = Theme(xml_data) theme = Theme(xml_data)
newtheme = ThemeXML() newtheme = ThemeXML()
newtheme.theme_name = theme.Name newtheme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
if theme.BackgroundType == 0: if theme.BackgroundType == 0:
newtheme.background_type = \ newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Solid) BackgroundType.to_string(BackgroundType.Solid)
@ -792,10 +813,13 @@ class ThemeManager(QtGui.QWidget):
unicode(theme.BackgroundParameter1.name()) unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \ newtheme.background_end_color = \
unicode(theme.BackgroundParameter2.name()) unicode(theme.BackgroundParameter2.name())
else: elif theme.BackgroundType == 2:
newtheme.background_type = \ newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Image) BackgroundType.to_string(BackgroundType.Image)
newtheme.background_filename = unicode(theme.BackgroundParameter1) newtheme.background_filename = unicode(theme.BackgroundParameter1)
elif theme.BackgroundType == 3:
newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Transparent)
newtheme.font_main_name = theme.FontName newtheme.font_main_name = theme.FontName
newtheme.font_main_color = unicode(theme.FontColor.name()) newtheme.font_main_color = unicode(theme.FontColor.name())
newtheme.font_main_size = theme.FontProportion * 3 newtheme.font_main_size = theme.FontProportion * 3

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -54,7 +54,7 @@ class Ui_ThemeWizard(object):
self.backgroundLabel = QtGui.QLabel(self.backgroundPage) self.backgroundLabel = QtGui.QLabel(self.backgroundPage)
self.backgroundLabel.setObjectName(u'BackgroundLabel') self.backgroundLabel.setObjectName(u'BackgroundLabel')
self.backgroundComboBox = QtGui.QComboBox(self.backgroundPage) self.backgroundComboBox = QtGui.QComboBox(self.backgroundPage)
self.backgroundComboBox.addItems([u'', u'', u'']) self.backgroundComboBox.addItems([u'', u'', u'', u''])
self.backgroundComboBox.setObjectName(u'BackgroundComboBox') self.backgroundComboBox.setObjectName(u'BackgroundComboBox')
self.backgroundTypeLayout.addRow(self.backgroundLabel, self.backgroundTypeLayout.addRow(self.backgroundLabel,
self.backgroundComboBox) self.backgroundComboBox)
@ -126,6 +126,12 @@ class Ui_ThemeWizard(object):
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout) self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
self.imageLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer) self.imageLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer)
self.backgroundStack.addWidget(self.imageWidget) self.backgroundStack.addWidget(self.imageWidget)
self.transparentWidget = QtGui.QWidget(self.backgroundPage)
self.transparentWidget.setObjectName(u'TransparentWidget')
self.transparentLayout = QtGui.QFormLayout(self.transparentWidget)
self.transparentLayout.setMargin(0)
self.transparentLayout.setObjectName(u'TransparentLayout')
self.backgroundStack.addWidget(self.transparentWidget)
self.backgroundLayout.addLayout(self.backgroundStack) self.backgroundLayout.addLayout(self.backgroundStack)
themeWizard.addPage(self.backgroundPage) themeWizard.addPage(self.backgroundPage)
# Main Area Page # Main Area Page
@ -432,6 +438,8 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Gradient')) translate('OpenLP.ThemeWizard', 'Gradient'))
self.backgroundComboBox.setItemText( self.backgroundComboBox.setItemText(
BackgroundType.Image, UiStrings().Image) BackgroundType.Image, UiStrings().Image)
self.backgroundComboBox.setItemText(BackgroundType.Transparent,
translate('OpenLP.ThemeWizard', 'Transparent'))
self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:')) self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.gradientStartLabel.setText( self.gradientStartLabel.setText(
translate(u'OpenLP.ThemeWizard', 'Starting color:')) translate(u'OpenLP.ThemeWizard', 'Starting color:'))

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -47,7 +47,7 @@ class WizardStrings(object):
CCLI = u'CCLI/SongSelect' CCLI = u'CCLI/SongSelect'
CSV = u'CSV' CSV = u'CSV'
EW = u'EasyWorship' EW = u'EasyWorship'
ES = u'EasiSlides' ES = u'EasySlides'
FP = u'Foilpresenter' FP = u'Foilpresenter'
OL = u'OpenLyrics' OL = u'OpenLyrics'
OS = u'OpenSong' OS = u'OpenSong'

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -455,26 +455,6 @@ def get_web_page(url, header=None, update_openlp=False):
log.debug(page) log.debug(page)
return page return page
def file_is_unicode(filename):
"""
Checks if a file is valid unicode and returns the unicode decoded file or
None.
``filename``
File to check is valid unicode.
"""
if not filename:
return None
ucsfile = None
try:
ucsfile = filename.decode(u'utf-8')
except UnicodeDecodeError:
log.exception(u'Filename "%s" is not valid UTF-8' %
filename.decode(u'utf-8', u'replace'))
if not ucsfile:
return None
return ucsfile
def get_uno_command(): def get_uno_command():
""" """
Returns the UNO command to launch an openoffice.org instance. Returns the UNO command to launch an openoffice.org instance.
@ -507,5 +487,5 @@ from actions import ActionList
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version', __all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
u'add_actions', u'get_filesystem_encoding', u'LanguageManager', u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command', u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
u'get_uno_instance', u'delete_file', u'clean_filename'] u'delete_file', u'clean_filename']

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -188,6 +188,7 @@ class ActionList(object):
actions or categories. actions or categories.
""" """
instance = None instance = None
shortcut_map = {}
def __init__(self): def __init__(self):
self.categories = CategoryList() self.categories = CategoryList()
@ -224,17 +225,45 @@ class ActionList(object):
self.categories[category].actions.append(action) self.categories[category].actions.append(action)
else: else:
self.categories[category].actions.add(action, weight) self.categories[category].actions.add(action, weight)
if not category:
# Stop here, as this action is not configurable.
return
# Load the shortcut from the config. # Load the shortcut from the config.
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(u'shortcuts') settings.beginGroup(u'shortcuts')
shortcuts = settings.value(action.objectName(), shortcuts = settings.value(action.objectName(),
QtCore.QVariant(action.shortcuts())).toStringList() QtCore.QVariant(action.shortcuts())).toStringList()
settings.endGroup()
if not shortcuts:
action.setShortcuts([])
return
# We have to do this to ensure that the loaded shortcut list e. g.
# STRG+O (German) is converted to CTRL+O, which is only done when we
# convert the strings in this way (QKeySequence -> QString -> unicode).
shortcuts = map(QtGui.QKeySequence, shortcuts)
shortcuts = map(unicode, map(QtGui.QKeySequence.toString, shortcuts))
# Check the alternate shortcut first, to avoid problems when the
# alternate shortcut becomes the primary shortcut after removing the
# (initial) primary shortcut due to conflicts.
if len(shortcuts) == 2:
existing_actions = ActionList.shortcut_map.get(shortcuts[1], [])
# Check for conflicts with other actions considering the shortcut
# context.
if self._is_shortcut_available(existing_actions, action):
actions = ActionList.shortcut_map.get(shortcuts[1], [])
actions.append(action)
ActionList.shortcut_map[shortcuts[1]] = actions
else:
shortcuts.remove(shortcuts[1])
# Check the primary shortcut.
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
# Check for conflicts with other actions considering the shortcut
# context.
if self._is_shortcut_available(existing_actions, action):
actions = ActionList.shortcut_map.get(shortcuts[0], [])
actions.append(action)
ActionList.shortcut_map[shortcuts[0]] = actions
else:
shortcuts.remove(shortcuts[0])
action.setShortcuts( action.setShortcuts(
[QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) [QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
settings.endGroup()
def remove_action(self, action, category=None): def remove_action(self, action, category=None):
""" """
@ -242,7 +271,7 @@ class ActionList(object):
automatically removed. automatically removed.
``action`` ``action``
The QAction object to be removed. The ``QAction`` object to be removed.
``category`` ``category``
The name (unicode string) of the category, which contains the The name (unicode string) of the category, which contains the
@ -254,6 +283,15 @@ class ActionList(object):
# Remove empty categories. # Remove empty categories.
if len(self.categories[category].actions) == 0: if len(self.categories[category].actions) == 0:
self.categories.remove(category) self.categories.remove(category)
shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
for shortcut in shortcuts:
# Remove action from the list of actions which are using this
# shortcut.
ActionList.shortcut_map[shortcut].remove(action)
# Remove empty entries.
if not ActionList.shortcut_map[shortcut]:
del ActionList.shortcut_map[shortcut]
def add_category(self, name, weight): def add_category(self, name, weight):
""" """
@ -275,6 +313,60 @@ class ActionList(object):
return return
self.categories.add(name, weight) self.categories.add(name, weight)
def update_shortcut_map(self, action, old_shortcuts):
"""
Remove the action for the given ``old_shortcuts`` from the
``shortcut_map`` to ensure its up-to-dateness.
**Note**: The new action's shortcuts **must** be assigned to the given
``action`` **before** calling this method.
``action``
The action whose shortcuts are supposed to be updated in the
``shortcut_map``.
``old_shortcuts``
A list of unicode keysequences.
"""
for old_shortcut in old_shortcuts:
# Remove action from the list of actions which are using this
# shortcut.
ActionList.shortcut_map[old_shortcut].remove(action)
# Remove empty entries.
if not ActionList.shortcut_map[old_shortcut]:
del ActionList.shortcut_map[old_shortcut]
new_shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
# Add the new shortcuts to the map.
for new_shortcut in new_shortcuts:
existing_actions = ActionList.shortcut_map.get(new_shortcut, [])
existing_actions.append(action)
ActionList.shortcut_map[new_shortcut] = existing_actions
def _is_shortcut_available(self, existing_actions, action):
"""
Checks if the given ``action`` may use its assigned shortcut(s) or not.
Returns ``True`` or ``False.
``existing_actions``
A list of actions which already use a particular shortcut.
``action``
The action which wants to use a particular shortcut.
"""
for existing_action in existing_actions:
if action is existing_action:
continue
if existing_action.parent() is action.parent():
return False
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut,
QtCore.Qt.ApplicationShortcut]:
return False
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
QtCore.Qt.ApplicationShortcut]:
return False
return True
class CategoryOrder(object): class CategoryOrder(object):
""" """

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # # Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # # Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # # Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, # # Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon # # Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund # # Tibble, Carsten Tinggaard, Frode Woldsund #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, # # Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon # # Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund # # Tibble, Carsten Tinggaard, Frode Woldsund #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, # # Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon # # Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund # # Tibble, Carsten Tinggaard, Frode Woldsund #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, # # Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon # # Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund # # Tibble, Carsten Tinggaard, Frode Woldsund #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -31,8 +31,15 @@ plugin.
import logging import logging
import re import re
from PyQt4 import QtCore
from openlp.core.lib import translate
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
REFERENCE_MATCHES = {}
REFERENCE_SEPARATORS = {}
class LayoutStyle(object): class LayoutStyle(object):
""" """
An enumeration for bible screen layout styles. An enumeration for bible screen layout styles.
@ -52,39 +59,85 @@ class DisplayStyle(object):
Square = 3 Square = 3
def update_reference_separators():
"""
Updates separators and matches for parsing and formating scripture
references.
"""
default_separators = unicode(translate('BiblesPlugin',
':|v|V|verse|verses;;-|to;;,|and;;end',
'This are 4 values seperated each by two semicolons representing the '
'seperators for parsing references. This values are verse separators, '
'range separators, list separators and end mark. Alternative values '
'to be seperated by a vertical bar "|". In this case the first value '
'is the default and used for the display format. If a semicolon should '
'be used you have to give an alternative separator afterwards to allow '
'OpenLP correct splitting of the translation.')).split(u';;')
settings = QtCore.QSettings()
settings.beginGroup(u'bibles')
custom_separators = [
unicode(settings.value(u'verse separator').toString()),
unicode(settings.value(u'range separator').toString()),
unicode(settings.value(u'list separator').toString()),
unicode(settings.value(u'end separator').toString())]
settings.endGroup()
for index, role in enumerate([u'v', u'r', u'l', u'e']):
if custom_separators[index].strip(u'|') == u'':
source_string = default_separators[index].strip(u'|')
else:
source_string = custom_separators[index].strip(u'|')
while u'||' in source_string:
source_string = source_string.replace(u'||', u'|')
if role != u'e':
REFERENCE_SEPARATORS[u'sep_%s_display' % role] = \
source_string.split(u'|')[0]
# escape reserved characters
for character in u'\\.^$*+?{}[]()':
source_string = source_string.replace(character, u'\\' + character)
# add various unicode alternatives
source_string = source_string.replace(u'-',
u'(?:[-\u00AD\u2010\u2011\u2012\u2013\u2014\u2212\uFE63\uFF0D])')
source_string = source_string.replace(u',', u'(?:[,\u201A])')
REFERENCE_SEPARATORS[u'sep_%s' % role] = u'\s*(?:%s)\s*' % source_string
REFERENCE_SEPARATORS[u'sep_%s_default' % role] = \
default_separators[index]
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
range_regex = u'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?' \
u'(?P<from_verse>[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>' \
u'[0-9]+)%(sep_v)s)?(?P<to_verse>[0-9]+)|%(sep_e)s)?)?' % \
REFERENCE_SEPARATORS
REFERENCE_MATCHES[u'range'] = re.compile(u'^\s*%s\s*$' % range_regex,
re.UNICODE)
REFERENCE_MATCHES[u'range_separator'] = re.compile(
REFERENCE_SEPARATORS[u'sep_l'], re.UNICODE)
# full reference match: <book>(<range>(,(?!$)|(?=$)))+
REFERENCE_MATCHES[u'full'] = re.compile(
u'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
u'(?P<ranges>(?:%(range_regex)s(?:%(sep_l)s(?!\s*$)|(?=\s*$)))+)\s*$' \
% dict(REFERENCE_SEPARATORS.items() + [(u'range_regex', range_regex)]),
re.UNICODE)
def get_reference_separator(separator_type):
"""
Provides separators for parsing and formatting scripture references.
``separator_type``
The role and format of the separator.
"""
if len(REFERENCE_SEPARATORS) == 0:
update_reference_separators()
return REFERENCE_SEPARATORS[separator_type]
def get_reference_match(match_type): def get_reference_match(match_type):
""" """
Provides the regexes and matches to use while parsing strings for bible Provides matches for parsing scripture references strings.
references.
``match_type`` ``match_type``
The type of reference information trying to be extracted in this call. The type of match is ``range_separator``, ``range`` or ``full``.
""" """
local_separator = unicode(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end' if len(REFERENCE_MATCHES) == 0:
).split(u';;') # English update_reference_separators()
# local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde' return REFERENCE_MATCHES[match_type]
# ).split(u';;') # German
separators = {
u'sep_v_display': local_separator[0], u'sep_v': local_separator[1],
u'sep_r_display': local_separator[2], u'sep_r': local_separator[3],
u'sep_l_display': local_separator[4], u'sep_l': local_separator[5],
u'sep_e': local_separator[6]}
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
range_string = str(r'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?(?P<from_verse>'
r'[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?'
r'(?P<to_verse>[0-9]+)|%(sep_e)s)?)?') % separators
if match_type == u'range':
return re.compile(r'^\s*' + range_string + r'\s*$', re.UNICODE)
elif match_type == u'range_separator':
return re.compile(separators[u'sep_l'])
elif match_type == u'full':
# full reference match: <book>(<range>(,|(?=$)))+
return re.compile(str(r'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
r'(?P<ranges>(?:' + range_string + r'(?:%(sep_l)s|(?=\s*$)))+)\s*$')
% separators, re.UNICODE)
else:
return separators[match_type]
def parse_reference(reference): def parse_reference(reference):
""" """
@ -140,7 +193,7 @@ def parse_reference(reference):
If there is a range separator without further verse declaration the last If there is a range separator without further verse declaration the last
refered chapter is addressed until the end. refered chapter is addressed until the end.
``range_string`` is a regular expression which matches for verse range ``range_regex`` is a regular expression which matches for verse range
declarations: declarations:
``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?`` ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
@ -169,9 +222,9 @@ def parse_reference(reference):
are optional leading digits followed by non-digits. The group ends are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit. before the whitspace in front of the next digit.
``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$`` ``(?P<ranges>(?:%(range_regex)s(?:%(sep_l)s(?!\s*$)|(?=\s*$)))+)\s*$``
The second group contains all ``ranges``. This can be multiple The second group contains all ``ranges``. This can be multiple
declarations of a range_string separated by a list separator. declarations of range_regex separated by a list separator.
""" """
log.debug(u'parse_reference("%s")', reference) log.debug(u'parse_reference("%s")', reference)

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
@ -30,8 +30,9 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle
from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
update_reference_separators, get_reference_separator
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -90,6 +91,55 @@ class BiblesTab(SettingsTab):
self.changeNoteLabel.setObjectName(u'changeNoteLabel') self.changeNoteLabel.setObjectName(u'changeNoteLabel')
self.verseDisplayLayout.addRow(self.changeNoteLabel) self.verseDisplayLayout.addRow(self.changeNoteLabel)
self.leftLayout.addWidget(self.verseDisplayGroupBox) self.leftLayout.addWidget(self.verseDisplayGroupBox)
self.scriptureReferenceGroupBox = QtGui.QGroupBox(self.leftColumn)
self.scriptureReferenceGroupBox.setObjectName(
u'scriptureReferenceGroupBox')
self.scriptureReferenceLayout = QtGui.QGridLayout(
self.scriptureReferenceGroupBox)
self.verseSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.verseSeparatorCheckBox.setObjectName(u'verseSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.verseSeparatorCheckBox, 0,
0)
self.verseSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
# self.verseSeparatorLineEdit.setPalette
self.verseSeparatorLineEdit.setObjectName(u'verseSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.verseSeparatorLineEdit, 0,
1)
self.rangeSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.rangeSeparatorCheckBox.setObjectName(u'rangeSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.rangeSeparatorCheckBox, 1,
0)
self.rangeSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.rangeSeparatorLineEdit.setObjectName(u'rangeSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.rangeSeparatorLineEdit, 1,
1)
self.listSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.listSeparatorCheckBox.setObjectName(u'listSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.listSeparatorCheckBox, 2,
0)
self.listSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.listSeparatorLineEdit.setObjectName(u'listSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.listSeparatorLineEdit, 2,
1)
self.endSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.endSeparatorCheckBox.setObjectName(u'endSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.endSeparatorCheckBox, 3,
0)
self.endSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.endSeparatorLineEdit.setObjectName(u'endSeparatorLineEdit')
self.endSeparatorLineEdit.setValidator(QtGui.QRegExpValidator(
QtCore.QRegExp(r'[^0-9]*'), self.endSeparatorLineEdit))
self.scriptureReferenceLayout.addWidget(self.endSeparatorLineEdit, 3,
1)
self.leftLayout.addWidget(self.scriptureReferenceGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightColumn.setSizePolicy( self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
@ -110,6 +160,42 @@ class BiblesTab(SettingsTab):
QtCore.QObject.connect( QtCore.QObject.connect(
self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleSecondCheckBox) self.onBibleSecondCheckBox)
QtCore.QObject.connect(
self.verseSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onVerseSeparatorCheckBoxClicked)
QtCore.QObject.connect(
self.verseSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onVerseSeparatorLineEditEdited)
QtCore.QObject.connect(
self.verseSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onVerseSeparatorLineEditFinished)
QtCore.QObject.connect(
self.rangeSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onRangeSeparatorCheckBoxClicked)
QtCore.QObject.connect(
self.rangeSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onRangeSeparatorLineEditEdited)
QtCore.QObject.connect(
self.rangeSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onRangeSeparatorLineEditFinished)
QtCore.QObject.connect(
self.listSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onListSeparatorCheckBoxClicked)
QtCore.QObject.connect(
self.listSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onListSeparatorLineEditEdited)
QtCore.QObject.connect(
self.listSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onListSeparatorLineEditFinished)
QtCore.QObject.connect(
self.endSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onEndSeparatorCheckBoxClicked)
QtCore.QObject.connect(
self.endSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onEndSeparatorLineEditEdited)
QtCore.QObject.connect(
self.endSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onEndSeparatorLineEditFinished)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
@ -141,6 +227,36 @@ class BiblesTab(SettingsTab):
'Note:\nChanges do not affect verses already in the service.')) 'Note:\nChanges do not affect verses already in the service.'))
self.bibleSecondCheckBox.setText( self.bibleSecondCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Display second Bible verses')) translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
self.scriptureReferenceGroupBox.setTitle(
translate('BiblesPlugin.BiblesTab', 'Custom Scripture References'))
self.verseSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Verse Separator:'))
self.rangeSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Range Separator:'))
self.listSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'List Separator:'))
self.endSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'End Mark:'))
self.verseSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'verse separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.rangeSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'range separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.listSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'list separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.endSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'end marks may be defined.\nThey have to be separated by a '
'vertical bar "|".\nPlease clear this edit line to use the '
'default value.'))
def onBibleThemeComboBoxChanged(self): def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.bibleThemeComboBox.currentText() self.bible_theme = self.bibleThemeComboBox.currentText()
@ -163,6 +279,106 @@ class BiblesTab(SettingsTab):
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.second_bibles = True self.second_bibles = True
def onVerseSeparatorCheckBoxClicked(self, checked):
if checked:
self.verseSeparatorLineEdit.setFocus()
else:
self.verseSeparatorLineEdit.setText(
get_reference_separator(u'sep_v_default'))
self.verseSeparatorLineEdit.setPalette(
self.getGreyTextPalette(not checked))
def onVerseSeparatorLineEditEdited(self, text):
self.verseSeparatorCheckBox.setChecked(True)
self.verseSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
def onVerseSeparatorLineEditFinished(self):
if self.verseSeparatorLineEdit.isModified():
text = self.verseSeparatorLineEdit.text()
if text == get_reference_separator(u'sep_v_default') or \
text.remove(u'|').isEmpty():
self.verseSeparatorCheckBox.setChecked(False)
self.verseSeparatorLineEdit.setText(
get_reference_separator(u'sep_v_default'))
self.verseSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
def onRangeSeparatorCheckBoxClicked(self, checked):
if checked:
self.rangeSeparatorLineEdit.setFocus()
else:
self.rangeSeparatorLineEdit.setText(
get_reference_separator(u'sep_r_default'))
self.rangeSeparatorLineEdit.setPalette(
self.getGreyTextPalette(not checked))
def onRangeSeparatorLineEditEdited(self, text):
self.rangeSeparatorCheckBox.setChecked(True)
self.rangeSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
def onRangeSeparatorLineEditFinished(self):
if self.rangeSeparatorLineEdit.isModified():
text = self.rangeSeparatorLineEdit.text()
if text == get_reference_separator(u'sep_r_default') or \
text.remove(u'|').isEmpty():
self.rangeSeparatorCheckBox.setChecked(False)
self.rangeSeparatorLineEdit.setText(
get_reference_separator(u'sep_r_default'))
self.rangeSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
def onListSeparatorCheckBoxClicked(self, checked):
if checked:
self.listSeparatorLineEdit.setFocus()
else:
self.listSeparatorLineEdit.setText(
get_reference_separator(u'sep_l_default'))
self.listSeparatorLineEdit.setPalette(
self.getGreyTextPalette(not checked))
def onListSeparatorLineEditEdited(self, text):
self.listSeparatorCheckBox.setChecked(True)
self.listSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
def onListSeparatorLineEditFinished(self):
if self.listSeparatorLineEdit.isModified():
text = self.listSeparatorLineEdit.text()
if text == get_reference_separator(u'sep_l_default') or \
text.remove(u'|').isEmpty():
self.listSeparatorCheckBox.setChecked(False)
self.listSeparatorLineEdit.setText(
get_reference_separator(u'sep_l_default'))
self.listSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
def onEndSeparatorCheckBoxClicked(self, checked):
if checked:
self.endSeparatorLineEdit.setFocus()
else:
self.endSeparatorLineEdit.setText(
get_reference_separator(u'sep_e_default'))
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(not checked))
def onEndSeparatorLineEditEdited(self, text):
self.endSeparatorCheckBox.setChecked(True)
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
def onEndSeparatorLineEditFinished(self):
if self.endSeparatorLineEdit.isModified():
text = self.endSeparatorLineEdit.text()
if text == get_reference_separator(u'sep_e_default') or \
text.remove(u'|').isEmpty():
self.endSeparatorCheckBox.setChecked(False)
self.endSeparatorLineEdit.setText(
get_reference_separator(u'sep_e_default'))
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
def load(self): def load(self):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
@ -180,6 +396,58 @@ class BiblesTab(SettingsTab):
self.displayStyleComboBox.setCurrentIndex(self.display_style) self.displayStyleComboBox.setCurrentIndex(self.display_style)
self.layoutStyleComboBox.setCurrentIndex(self.layout_style) self.layoutStyleComboBox.setCurrentIndex(self.layout_style)
self.bibleSecondCheckBox.setChecked(self.second_bibles) self.bibleSecondCheckBox.setChecked(self.second_bibles)
verse_separator = unicode(settings.value(u'verse separator').toString())
if (verse_separator.strip(u'|') == u'') or \
(verse_separator == get_reference_separator(u'sep_v_default')):
self.verseSeparatorLineEdit.setText(
get_reference_separator(u'sep_v_default'))
self.verseSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
self.verseSeparatorCheckBox.setChecked(False)
else:
self.verseSeparatorLineEdit.setText(verse_separator)
self.verseSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
self.verseSeparatorCheckBox.setChecked(True)
range_separator = unicode(settings.value(u'range separator').toString())
if (range_separator.strip(u'|') == u'') or \
(range_separator == get_reference_separator(u'sep_r_default')):
self.rangeSeparatorLineEdit.setText(
get_reference_separator(u'sep_r_default'))
self.rangeSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
self.rangeSeparatorCheckBox.setChecked(False)
else:
self.rangeSeparatorLineEdit.setText(range_separator)
self.rangeSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
self.rangeSeparatorCheckBox.setChecked(True)
list_separator = unicode(settings.value(u'list separator').toString())
if (list_separator.strip(u'|') == u'') or \
(list_separator == get_reference_separator(u'sep_l_default')):
self.listSeparatorLineEdit.setText(
get_reference_separator(u'sep_l_default'))
self.listSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
self.listSeparatorCheckBox.setChecked(False)
else:
self.listSeparatorLineEdit.setText(list_separator)
self.listSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
self.listSeparatorCheckBox.setChecked(True)
end_separator = unicode(settings.value(u'end separator').toString())
if (end_separator.strip(u'|') == u'') or \
(end_separator == get_reference_separator(u'sep_e_default')):
self.endSeparatorLineEdit.setText(
get_reference_separator(u'sep_e_default'))
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(True))
self.endSeparatorCheckBox.setChecked(False)
else:
self.endSeparatorLineEdit.setText(end_separator)
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
self.endSeparatorCheckBox.setChecked(True)
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -193,6 +461,27 @@ class BiblesTab(SettingsTab):
QtCore.QVariant(self.layout_style)) QtCore.QVariant(self.layout_style))
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles)) settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme)) settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
if self.verseSeparatorCheckBox.isChecked():
settings.setValue(u'verse separator',
self.verseSeparatorLineEdit.text())
else:
settings.remove(u'verse separator')
if self.rangeSeparatorCheckBox.isChecked():
settings.setValue(u'range separator',
self.rangeSeparatorLineEdit.text())
else:
settings.remove(u'range separator')
if self.listSeparatorCheckBox.isChecked():
settings.setValue(u'list separator',
self.listSeparatorLineEdit.text())
else:
settings.remove(u'list separator')
if self.endSeparatorCheckBox.isChecked():
settings.setValue(u'end separator',
self.endSeparatorLineEdit.text())
else:
settings.remove(u'end separator')
update_reference_separators()
settings.endGroup() settings.endGroup()
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
@ -209,3 +498,15 @@ class BiblesTab(SettingsTab):
for theme in theme_list: for theme in theme_list:
self.bibleThemeComboBox.addItem(theme) self.bibleThemeComboBox.addItem(theme)
find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme) find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme)
def getGreyTextPalette(self, greyed):
"""
Returns a QPalette with greyed out text as used for placeholderText.
"""
palette = QtGui.QPalette()
color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Text)
if greyed:
color.setAlpha(128)
palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
return palette

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #

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