forked from openlp/openlp
r1922
This commit is contained in:
commit
f6067002c0
@ -21,3 +21,5 @@ openlp/core/resources.py.old
|
|||||||
*.qm
|
*.qm
|
||||||
resources/windows/warnOpenLP.txt
|
resources/windows/warnOpenLP.txt
|
||||||
openlp.cfg
|
openlp.cfg
|
||||||
|
.idea
|
||||||
|
openlp.pro
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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
|
||||||
|
@ -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,7 +33,8 @@ from urllib import quote_plus as urlquote
|
|||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
from sqlalchemy import Table, MetaData, Column, types, create_engine
|
from sqlalchemy import Table, MetaData, Column, types, create_engine
|
||||||
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError
|
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError, \
|
||||||
|
OperationalError
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
||||||
from sqlalchemy.pool import NullPool
|
from sqlalchemy.pool import NullPool
|
||||||
|
|
||||||
@ -199,6 +200,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 +244,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 +276,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,6 +305,14 @@ class Manager(object):
|
|||||||
if not key:
|
if not key:
|
||||||
return object_class()
|
return object_class()
|
||||||
else:
|
else:
|
||||||
|
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)
|
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,6 +325,14 @@ class Manager(object):
|
|||||||
``filter_clause``
|
``filter_clause``
|
||||||
The criteria to select the object by
|
The criteria to select the object by
|
||||||
"""
|
"""
|
||||||
|
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()
|
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,
|
||||||
@ -311,9 +354,17 @@ 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)
|
||||||
|
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()
|
return query.all()
|
||||||
|
|
||||||
def get_object_count(self, object_class, filter_clause=None):
|
def get_object_count(self, object_class, filter_clause=None):
|
||||||
@ -330,6 +381,14 @@ 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)
|
||||||
|
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()
|
return query.count()
|
||||||
|
|
||||||
def delete_object(self, object_class, key):
|
def delete_object(self, object_class, key):
|
||||||
@ -349,6 +408,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 +447,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__)
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -112,6 +112,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.
|
||||||
|
|
||||||
@ -214,6 +217,9 @@ class EventReceiver(QtCore.QObject):
|
|||||||
Ask the plugin to process an individual service item after it has been
|
Ask the plugin to process an individual service item after it has been
|
||||||
loaded.
|
loaded.
|
||||||
|
|
||||||
|
``{plugin}_config_updated``
|
||||||
|
The config has changed so tell the plugin about it.
|
||||||
|
|
||||||
``alerts_text``
|
``alerts_text``
|
||||||
Displays an alert message.
|
Displays an alert message.
|
||||||
|
|
||||||
|
@ -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, #
|
||||||
|
@ -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;
|
||||||
@ -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:
|
||||||
@ -454,13 +458,18 @@ def build_lyrics_format_css(theme, width, height):
|
|||||||
# fix tag incompatibilities
|
# fix tag incompatibilities
|
||||||
if theme.display_horizontal_align == HorizontalType.Justify:
|
if theme.display_horizontal_align == HorizontalType.Justify:
|
||||||
justify = u''
|
justify = u''
|
||||||
|
if theme.display_vertical_align == VerticalType.Bottom:
|
||||||
|
padding_bottom = u'0.5em'
|
||||||
|
else:
|
||||||
|
padding_bottom = u'0'
|
||||||
lyrics = u'%s word-wrap: break-word; ' \
|
lyrics = u'%s word-wrap: break-word; ' \
|
||||||
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
||||||
'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
|
'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
|
||||||
'padding: 0; padding-left: %spx; width: %spx; height: %spx; ' % \
|
'padding: 0; padding-bottom: %s; padding-left: %spx; width: %spx;' \
|
||||||
|
'height: %spx; ' % \
|
||||||
(justify, align, valign, theme.font_main_name, theme.font_main_size,
|
(justify, align, valign, theme.font_main_name, theme.font_main_size,
|
||||||
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
||||||
left_margin, width, height)
|
padding_bottom, left_margin, width, height)
|
||||||
if theme.font_main_outline:
|
if theme.font_main_outline:
|
||||||
if webkit_version() <= 534.3:
|
if webkit_version() <= 534.3:
|
||||||
lyrics += u' letter-spacing: 1px;'
|
lyrics += u' letter-spacing: 1px;'
|
||||||
|
@ -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, #
|
||||||
@ -166,7 +166,7 @@ class ImageManager(QtCore.QObject):
|
|||||||
self.height = current_screen[u'size'].height()
|
self.height = current_screen[u'size'].height()
|
||||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
# stream to None.
|
# stream to None.
|
||||||
for key, image in self._cache.iteritems():
|
for image in self._cache.values():
|
||||||
self._reset_image(image)
|
self._reset_image(image)
|
||||||
|
|
||||||
def update_images(self, image_type, background):
|
def update_images(self, image_type, background):
|
||||||
@ -176,7 +176,7 @@ class ImageManager(QtCore.QObject):
|
|||||||
log.debug(u'update_images')
|
log.debug(u'update_images')
|
||||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
# stream to None.
|
# stream to None.
|
||||||
for key, image in self._cache.iteritems():
|
for image in self._cache.values():
|
||||||
if image.source == image_type:
|
if image.source == image_type:
|
||||||
image.background = background
|
image.background = background
|
||||||
self._reset_image(image)
|
self._reset_image(image)
|
||||||
@ -188,7 +188,7 @@ class ImageManager(QtCore.QObject):
|
|||||||
log.debug(u'update_images')
|
log.debug(u'update_images')
|
||||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
# stream to None.
|
# stream to None.
|
||||||
for key, image in self._cache.iteritems():
|
for image in self._cache.values():
|
||||||
if image.source == image_type and image.name == name:
|
if image.source == image_type and image.name == name:
|
||||||
image.background = background
|
image.background = background
|
||||||
self._reset_image(image)
|
self._reset_image(image)
|
||||||
|
@ -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, #
|
||||||
|
@ -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,8 +35,9 @@ 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.ui import UiStrings, context_menu_action, \
|
from openlp.core.lib.searchedit import SearchEdit
|
||||||
context_menu_separator, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, create_widget_action, \
|
||||||
|
critical_error_message_box
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -146,43 +147,6 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.pageLayout.addWidget(self.toolbar)
|
self.pageLayout.addWidget(self.toolbar)
|
||||||
|
|
||||||
def addToolbarButton(
|
|
||||||
self, title, tooltip, icon, slot=None, checkable=False):
|
|
||||||
"""
|
|
||||||
A method to help developers easily add a button to the toolbar.
|
|
||||||
|
|
||||||
``title``
|
|
||||||
The title of the button.
|
|
||||||
|
|
||||||
``tooltip``
|
|
||||||
The tooltip to be displayed when the mouse hovers over the
|
|
||||||
button.
|
|
||||||
|
|
||||||
``icon``
|
|
||||||
The icon of the button. This can be an instance of QIcon, or a
|
|
||||||
string containing either the absolute path to the image, or an
|
|
||||||
internal resource path starting with ':/'.
|
|
||||||
|
|
||||||
``slot``
|
|
||||||
The method to call when the button is clicked.
|
|
||||||
|
|
||||||
``checkable``
|
|
||||||
If *True* the button has two, *off* and *on*, states. Default is
|
|
||||||
*False*, which means the buttons has only one state.
|
|
||||||
"""
|
|
||||||
# NB different order (when I broke this out, I didn't want to
|
|
||||||
# break compatability), but it makes sense for the icon to
|
|
||||||
# come before the tooltip (as you have to have an icon, but
|
|
||||||
# not neccesarily a tooltip)
|
|
||||||
return self.toolbar.addToolbarButton(title, icon, tooltip, slot,
|
|
||||||
checkable)
|
|
||||||
|
|
||||||
def addToolbarSeparator(self):
|
|
||||||
"""
|
|
||||||
A very simple method to add a separator to the toolbar.
|
|
||||||
"""
|
|
||||||
self.toolbar.addSeparator()
|
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
"""
|
"""
|
||||||
This method sets up the interface on the button. Plugin
|
This method sets up the interface on the button. Plugin
|
||||||
@ -207,40 +171,41 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
toolbar_actions = []
|
toolbar_actions = []
|
||||||
## Import Button ##
|
## Import Button ##
|
||||||
if self.hasImportIcon:
|
if self.hasImportIcon:
|
||||||
toolbar_actions.append([StringContent.Import,
|
toolbar_actions.append([u'Import', StringContent.Import,
|
||||||
u':/general/general_import.png', self.onImportClick])
|
u':/general/general_import.png', self.onImportClick])
|
||||||
## Load Button ##
|
## Load Button ##
|
||||||
if self.hasFileIcon:
|
if self.hasFileIcon:
|
||||||
toolbar_actions.append([StringContent.Load,
|
toolbar_actions.append([u'Load', StringContent.Load,
|
||||||
u':/general/general_open.png', self.onFileClick])
|
u':/general/general_open.png', self.onFileClick])
|
||||||
## New Button ##
|
## New Button ##
|
||||||
if self.hasNewIcon:
|
if self.hasNewIcon:
|
||||||
toolbar_actions.append([StringContent.New,
|
toolbar_actions.append([u'New', StringContent.New,
|
||||||
u':/general/general_new.png', self.onNewClick])
|
u':/general/general_new.png', self.onNewClick])
|
||||||
## Edit Button ##
|
## Edit Button ##
|
||||||
if self.hasEditIcon:
|
if self.hasEditIcon:
|
||||||
toolbar_actions.append([StringContent.Edit,
|
toolbar_actions.append([u'Edit', StringContent.Edit,
|
||||||
u':/general/general_edit.png', self.onEditClick])
|
u':/general/general_edit.png', self.onEditClick])
|
||||||
## Delete Button ##
|
## Delete Button ##
|
||||||
if self.hasDeleteIcon:
|
if self.hasDeleteIcon:
|
||||||
toolbar_actions.append([StringContent.Delete,
|
toolbar_actions.append([u'Delete', StringContent.Delete,
|
||||||
u':/general/general_delete.png', self.onDeleteClick])
|
u':/general/general_delete.png', self.onDeleteClick])
|
||||||
## Preview ##
|
## Preview ##
|
||||||
toolbar_actions.append([StringContent.Preview,
|
toolbar_actions.append([u'Preview', StringContent.Preview,
|
||||||
u':/general/general_preview.png', self.onPreviewClick])
|
u':/general/general_preview.png', self.onPreviewClick])
|
||||||
## Live Button ##
|
## Live Button ##
|
||||||
toolbar_actions.append([StringContent.Live,
|
toolbar_actions.append([u'Live', StringContent.Live,
|
||||||
u':/general/general_live.png', self.onLiveClick])
|
u':/general/general_live.png', self.onLiveClick])
|
||||||
## Add to service Button ##
|
## Add to service Button ##
|
||||||
toolbar_actions.append([StringContent.Service,
|
toolbar_actions.append([u'Service', StringContent.Service,
|
||||||
u':/general/general_add.png', self.onAddClick])
|
u':/general/general_add.png', self.onAddClick])
|
||||||
for action in toolbar_actions:
|
for action in toolbar_actions:
|
||||||
if action[0] == StringContent.Preview:
|
if action[0] == StringContent.Preview:
|
||||||
self.addToolbarSeparator()
|
self.toolbar.addSeparator()
|
||||||
self.addToolbarButton(
|
self.toolbar.addToolbarAction(
|
||||||
self.plugin.getString(action[0])[u'title'],
|
u'%s%sAction' % (self.plugin.name, action[0]),
|
||||||
self.plugin.getString(action[0])[u'tooltip'],
|
text=self.plugin.getString(action[1])[u'title'], icon=action[2],
|
||||||
action[1], action[2])
|
tooltip=self.plugin.getString(action[1])[u'tooltip'],
|
||||||
|
triggers=action[3])
|
||||||
|
|
||||||
def addListViewToToolBar(self):
|
def addListViewToToolBar(self):
|
||||||
"""
|
"""
|
||||||
@ -258,35 +223,37 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
# define and add the context menu
|
# define and add the context menu
|
||||||
self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||||
if self.hasEditIcon:
|
if self.hasEditIcon:
|
||||||
context_menu_action(
|
create_widget_action(self.listView,
|
||||||
self.listView, u':/general/general_edit.png',
|
text=self.plugin.getString(StringContent.Edit)[u'title'],
|
||||||
self.plugin.getString(StringContent.Edit)[u'title'],
|
icon=u':/general/general_edit.png',
|
||||||
self.onEditClick)
|
triggers=self.onEditClick)
|
||||||
context_menu_separator(self.listView)
|
create_widget_action(self.listView, separator=True)
|
||||||
if self.hasDeleteIcon:
|
if self.hasDeleteIcon:
|
||||||
context_menu_action(
|
create_widget_action(self.listView,
|
||||||
self.listView, u':/general/general_delete.png',
|
text=self.plugin.getString(StringContent.Delete)[u'title'],
|
||||||
self.plugin.getString(StringContent.Delete)[u'title'],
|
icon=u':/general/general_delete.png',
|
||||||
self.onDeleteClick, [QtCore.Qt.Key_Delete])
|
shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
|
||||||
context_menu_separator(self.listView)
|
create_widget_action(self.listView, separator=True)
|
||||||
context_menu_action(
|
create_widget_action(self.listView,
|
||||||
self.listView, u':/general/general_preview.png',
|
text=self.plugin.getString(StringContent.Preview)[u'title'],
|
||||||
self.plugin.getString(StringContent.Preview)[u'title'],
|
icon=u':/general/general_preview.png',
|
||||||
self.onPreviewClick, [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
||||||
context_menu_action(
|
triggers=self.onPreviewClick)
|
||||||
self.listView, u':/general/general_live.png',
|
create_widget_action(self.listView,
|
||||||
self.plugin.getString(StringContent.Live)[u'title'],
|
text=self.plugin.getString(StringContent.Live)[u'title'],
|
||||||
self.onLiveClick, [QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Enter,
|
icon=u':/general/general_live.png',
|
||||||
QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Return])
|
shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
|
||||||
context_menu_action(
|
QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
|
||||||
self.listView, u':/general/general_add.png',
|
triggers=self.onLiveClick)
|
||||||
self.plugin.getString(StringContent.Service)[u'title'],
|
create_widget_action(self.listView,
|
||||||
self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal])
|
text=self.plugin.getString(StringContent.Service)[u'title'],
|
||||||
|
icon=u':/general/general_add.png',
|
||||||
|
shortcuts=[QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal],
|
||||||
|
triggers=self.onAddClick)
|
||||||
if self.addToServiceItem:
|
if self.addToServiceItem:
|
||||||
context_menu_action(
|
create_widget_action(self.listView, text=translate(
|
||||||
self.listView, u':/general/general_add.png',
|
'OpenLP.MediaManagerItem', '&Add to selected Service Item'),
|
||||||
translate('OpenLP.MediaManagerItem',
|
icon=u':/general/general_add.png', triggers=self.onAddEditClick)
|
||||||
'&Add to selected Service Item'), self.onAddEditClick)
|
|
||||||
self.addCustomContextActions()
|
self.addCustomContextActions()
|
||||||
# Create the context menu and add all actions from the listView.
|
# Create the context menu and add all actions from the listView.
|
||||||
self.menu = QtGui.QMenu()
|
self.menu = QtGui.QMenu()
|
||||||
@ -301,6 +268,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
|
||||||
@ -640,7 +641,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
if item:
|
if item:
|
||||||
self.autoSelectId = item.data(QtCore.Qt.UserRole).toInt()[0]
|
self.autoSelectId = item.data(QtCore.Qt.UserRole).toInt()[0]
|
||||||
|
|
||||||
def search(self, string):
|
def search(self, string, showError=True):
|
||||||
"""
|
"""
|
||||||
Performs a plugin specific search for items containing ``string``
|
Performs a plugin specific search for items containing ``string``
|
||||||
"""
|
"""
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -173,6 +173,9 @@ class Plugin(QtCore.QObject):
|
|||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
|
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
|
||||||
self.processAddServiceEvent)
|
self.processAddServiceEvent)
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'%s_config_updated' % self.name),
|
||||||
|
self.configUpdated)
|
||||||
|
|
||||||
def checkPreConditions(self):
|
def checkPreConditions(self):
|
||||||
"""
|
"""
|
||||||
@ -395,3 +398,9 @@ class Plugin(QtCore.QObject):
|
|||||||
Add html code to htmlbuilder.
|
Add html code to htmlbuilder.
|
||||||
"""
|
"""
|
||||||
return u''
|
return u''
|
||||||
|
|
||||||
|
def configUpdated(self):
|
||||||
|
"""
|
||||||
|
The plugin's config has changed
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -289,7 +289,7 @@ class Renderer(object):
|
|||||||
|
|
||||||
def _calculate_default(self):
|
def _calculate_default(self):
|
||||||
"""
|
"""
|
||||||
Calculate the default dimentions of the screen.
|
Calculate the default dimensions of the screen.
|
||||||
"""
|
"""
|
||||||
screen_size = self.screens.current[u'size']
|
screen_size = self.screens.current[u'size']
|
||||||
self.width = screen_size.width()
|
self.width = screen_size.width()
|
||||||
@ -380,6 +380,7 @@ class Renderer(object):
|
|||||||
(build_lyrics_format_css(self.theme_data, self.page_width,
|
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||||
self.page_height), build_lyrics_outline_css(self.theme_data))
|
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
|
self.empty_height = self.web_frame.contentsSize().height()
|
||||||
|
|
||||||
def _paginate_slide(self, lines, line_end):
|
def _paginate_slide(self, lines, line_end):
|
||||||
"""
|
"""
|
||||||
@ -600,7 +601,7 @@ class Renderer(object):
|
|||||||
"""
|
"""
|
||||||
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
||||||
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||||
return self.web_frame.contentsSize().height() <= self.page_height
|
return self.web_frame.contentsSize().height() <= self.empty_height
|
||||||
|
|
||||||
def _words_split(self, line):
|
def _words_split(self, line):
|
||||||
"""
|
"""
|
||||||
|
@ -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,7 +30,7 @@ import logging
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import build_icon
|
from openlp.core.lib import build_icon
|
||||||
from openlp.core.lib.ui import icon_action
|
from openlp.core.lib.ui import create_widget_action
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -122,6 +122,13 @@ class SearchEdit(QtGui.QLineEdit):
|
|||||||
menu = self.menuButton.menu()
|
menu = self.menuButton.menu()
|
||||||
for action in menu.actions():
|
for action in menu.actions():
|
||||||
if identifier == action.data().toInt()[0]:
|
if identifier == action.data().toInt()[0]:
|
||||||
|
# setPlaceholderText has been implemented in Qt 4.7 and in at
|
||||||
|
# least PyQt 4.9 (I am not sure, if it was implemented in
|
||||||
|
# PyQt 4.8).
|
||||||
|
try:
|
||||||
|
self.setPlaceholderText(action.placeholderText)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
self.menuButton.setDefaultAction(action)
|
self.menuButton.setDefaultAction(action)
|
||||||
self._currentSearchType = identifier
|
self._currentSearchType = identifier
|
||||||
self.emit(QtCore.SIGNAL(u'searchTypeChanged(int)'), identifier)
|
self.emit(QtCore.SIGNAL(u'searchTypeChanged(int)'), identifier)
|
||||||
@ -137,25 +144,22 @@ class SearchEdit(QtGui.QLineEdit):
|
|||||||
identifier, an icon (QIcon instance or string) and a title for the
|
identifier, an icon (QIcon instance or string) and a title for the
|
||||||
item in the menu. In short, they should look like this::
|
item in the menu. In short, they should look like this::
|
||||||
|
|
||||||
(<identifier>, <icon>, <title>)
|
(<identifier>, <icon>, <title>, <place holder text>)
|
||||||
|
|
||||||
For instance::
|
For instance::
|
||||||
|
|
||||||
(1, <QIcon instance>, "Titles")
|
(1, <QIcon instance>, "Titles", "Search Song Titles...")
|
||||||
|
|
||||||
Or::
|
Or::
|
||||||
|
|
||||||
(2, ":/songs/authors.png", "Authors")
|
(2, ":/songs/authors.png", "Authors", "Search Authors...")
|
||||||
"""
|
"""
|
||||||
menu = QtGui.QMenu(self)
|
menu = QtGui.QMenu(self)
|
||||||
first = None
|
first = None
|
||||||
for identifier, icon, title in items:
|
for identifier, icon, title, placeholder in items:
|
||||||
action = icon_action(menu, u'', icon)
|
action = create_widget_action(menu, text=title, icon=icon,
|
||||||
action.setText(title)
|
data=identifier, triggers=self._onMenuActionTriggered)
|
||||||
action.setData(QtCore.QVariant(identifier))
|
action.placeholderText = placeholder
|
||||||
menu.addAction(action)
|
|
||||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
|
|
||||||
self._onMenuActionTriggered)
|
|
||||||
if first is None:
|
if first is None:
|
||||||
first = action
|
first = action
|
||||||
self._currentSearchType = identifier
|
self._currentSearchType = identifier
|
||||||
@ -206,5 +210,12 @@ class SearchEdit(QtGui.QLineEdit):
|
|||||||
action.setChecked(False)
|
action.setChecked(False)
|
||||||
self.menuButton.setDefaultAction(sender)
|
self.menuButton.setDefaultAction(sender)
|
||||||
self._currentSearchType = sender.data().toInt()[0]
|
self._currentSearchType = sender.data().toInt()[0]
|
||||||
|
# setPlaceholderText has been implemented in Qt 4.7 and in at least
|
||||||
|
# PyQt 4.9 (I am not sure, if it was implemented in PyQt 4.8).
|
||||||
|
try:
|
||||||
|
self.setPlaceholderText(
|
||||||
|
self.menuButton.defaultAction().placeholderText)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
self.emit(QtCore.SIGNAL(u'searchTypeChanged(int)'),
|
self.emit(QtCore.SIGNAL(u'searchTypeChanged(int)'),
|
||||||
self._currentSearchType)
|
self._currentSearchType)
|
||||||
|
@ -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, #
|
||||||
@ -300,6 +300,7 @@ class ServiceItem(object):
|
|||||||
``path``
|
``path``
|
||||||
Defaults to *None*. Any path data, usually for images.
|
Defaults to *None*. Any path data, usually for images.
|
||||||
"""
|
"""
|
||||||
|
log.debug(u'set_from_service called with path %s' % path)
|
||||||
header = serviceitem[u'serviceitem'][u'header']
|
header = serviceitem[u'serviceitem'][u'header']
|
||||||
self.title = header[u'title']
|
self.title = header[u'title']
|
||||||
self.name = header[u'name']
|
self.name = header[u'name']
|
||||||
@ -325,7 +326,10 @@ class ServiceItem(object):
|
|||||||
if u'media_length' in header:
|
if u'media_length' in header:
|
||||||
self.media_length = header[u'media_length']
|
self.media_length = header[u'media_length']
|
||||||
if u'background_audio' in header:
|
if u'background_audio' in header:
|
||||||
self.background_audio = header[u'background_audio']
|
self.background_audio = []
|
||||||
|
for filename in header[u'background_audio']:
|
||||||
|
# Give them real file paths
|
||||||
|
self.background_audio.append(os.path.join(path, filename))
|
||||||
self.theme_overwritten = header.get(u'theme_overwritten', False)
|
self.theme_overwritten = header.get(u'theme_overwritten', False)
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -40,7 +40,7 @@ except ImportError:
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate, FormattingTags
|
from openlp.core.lib import translate, FormattingTags
|
||||||
from openlp.core.lib.ui import checkable_action
|
from openlp.core.lib.ui import create_action
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -90,9 +90,8 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
|||||||
lang_menu = QtGui.QMenu(
|
lang_menu = QtGui.QMenu(
|
||||||
translate('OpenLP.SpellTextEdit', 'Language:'))
|
translate('OpenLP.SpellTextEdit', 'Language:'))
|
||||||
for lang in enchant.list_languages():
|
for lang in enchant.list_languages():
|
||||||
action = checkable_action(
|
action = create_action(lang_menu, lang, text=lang,
|
||||||
lang_menu, lang, lang == self.dictionary.tag)
|
checked=lang == self.dictionary.tag)
|
||||||
action.setText(lang)
|
|
||||||
lang_menu.addAction(action)
|
lang_menu.addAction(action)
|
||||||
popupMenu.insertSeparator(popupMenu.actions()[0])
|
popupMenu.insertSeparator(popupMenu.actions()[0])
|
||||||
popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)
|
popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)
|
||||||
|
@ -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,
|
||||||
|
@ -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,7 +31,7 @@ import logging
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import build_icon
|
from openlp.core.lib.ui import create_widget_action
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -46,122 +46,41 @@ class OpenLPToolbar(QtGui.QToolBar):
|
|||||||
"""
|
"""
|
||||||
QtGui.QToolBar.__init__(self, parent)
|
QtGui.QToolBar.__init__(self, parent)
|
||||||
# useful to be able to reuse button icons...
|
# useful to be able to reuse button icons...
|
||||||
self.icons = {}
|
|
||||||
self.setIconSize(QtCore.QSize(20, 20))
|
self.setIconSize(QtCore.QSize(20, 20))
|
||||||
self.actions = {}
|
self.actions = {}
|
||||||
log.debug(u'Init done for %s' % parent.__class__.__name__)
|
log.debug(u'Init done for %s' % parent.__class__.__name__)
|
||||||
|
|
||||||
def addToolbarButton(self, title, icon, tooltip=None, slot=None,
|
def addToolbarAction(self, name, **kwargs):
|
||||||
checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
|
|
||||||
"""
|
"""
|
||||||
A method to help developers easily add a button to the toolbar.
|
A method to help developers easily add a button to the toolbar.
|
||||||
|
A new QAction is created by calling ``create_action()``. The action is
|
||||||
``title``
|
added to the toolbar and the toolbar is set as parent.
|
||||||
The title of the button.
|
For more details please look at openlp.core.lib.ui.create_action()
|
||||||
|
|
||||||
``icon``
|
|
||||||
The icon of the button. This can be an instance of QIcon, or a
|
|
||||||
string containing either the absolute path to the image, or an
|
|
||||||
internal resource path starting with ':/'.
|
|
||||||
|
|
||||||
``tooltip``
|
|
||||||
A hint or tooltip for this button.
|
|
||||||
|
|
||||||
``slot``
|
|
||||||
The method to run when this button is clicked.
|
|
||||||
|
|
||||||
``checkable``
|
|
||||||
If *True* the button has two, *off* and *on*, states. Default is
|
|
||||||
*False*, which means the buttons has only one state.
|
|
||||||
|
|
||||||
``shortcuts``
|
|
||||||
The list of shortcuts for this action
|
|
||||||
|
|
||||||
``context``
|
|
||||||
Specify the context in which this shortcut is valid
|
|
||||||
"""
|
"""
|
||||||
if icon:
|
action = create_widget_action(self, name, **kwargs)
|
||||||
actionIcon = build_icon(icon)
|
self.actions[name] = action
|
||||||
if slot and not checkable:
|
return action
|
||||||
newAction = self.addAction(actionIcon, title, slot)
|
|
||||||
else:
|
|
||||||
newAction = self.addAction(actionIcon, title)
|
|
||||||
self.icons[title] = actionIcon
|
|
||||||
else:
|
|
||||||
newAction = QtGui.QAction(title, self)
|
|
||||||
self.addAction(newAction)
|
|
||||||
QtCore.QObject.connect(newAction,
|
|
||||||
QtCore.SIGNAL(u'triggered()'), slot)
|
|
||||||
if tooltip:
|
|
||||||
newAction.setToolTip(tooltip)
|
|
||||||
if checkable:
|
|
||||||
newAction.setCheckable(True)
|
|
||||||
QtCore.QObject.connect(newAction,
|
|
||||||
QtCore.SIGNAL(u'toggled(bool)'), slot)
|
|
||||||
self.actions[title] = newAction
|
|
||||||
if shortcuts is not None:
|
|
||||||
newAction.setShortcuts(shortcuts)
|
|
||||||
newAction.setShortcutContext(context)
|
|
||||||
return newAction
|
|
||||||
|
|
||||||
def addToolbarSeparator(self, handle):
|
def addToolbarWidget(self, widget):
|
||||||
"""
|
"""
|
||||||
Add a Separator bar to the toolbar and store it's Handle
|
Add a widget and store it's handle under the widgets object name.
|
||||||
"""
|
|
||||||
action = self.addSeparator()
|
|
||||||
self.actions[handle] = action
|
|
||||||
|
|
||||||
def addToolbarWidget(self, handle, widget):
|
|
||||||
"""
|
|
||||||
Add a Widget to the toolbar and store it's Handle
|
|
||||||
"""
|
"""
|
||||||
action = self.addWidget(widget)
|
action = self.addWidget(widget)
|
||||||
self.actions[handle] = action
|
self.actions[unicode(widget.objectName())] = action
|
||||||
|
|
||||||
def getIconFromTitle(self, title):
|
def setWidgetVisible(self, widgets, visible=True):
|
||||||
"""
|
"""
|
||||||
Search through the list of icons for an icon with a particular title,
|
Set the visibitity for a widget or a list of widgets.
|
||||||
and return that icon.
|
|
||||||
|
|
||||||
``title``
|
``widget``
|
||||||
The title of the icon to search for.
|
A list of string with widget object names.
|
||||||
"""
|
|
||||||
title = QtCore.QString(title)
|
|
||||||
try:
|
|
||||||
if self.icons[title]:
|
|
||||||
return self.icons[title]
|
|
||||||
except KeyError:
|
|
||||||
log.exception(u'getIconFromTitle - no icon for %s' % title)
|
|
||||||
return QtGui.QIcon()
|
|
||||||
|
|
||||||
def makeWidgetsInvisible(self, widgets):
|
``visible``
|
||||||
|
The new state as bool.
|
||||||
"""
|
"""
|
||||||
Hide a set of widgets.
|
for handle in widgets:
|
||||||
|
if handle in self.actions:
|
||||||
|
self.actions[handle].setVisible(visible)
|
||||||
|
else:
|
||||||
|
log.warn(u'No handle "%s" in actions list.', unicode(handle))
|
||||||
|
|
||||||
``widgets``
|
|
||||||
The list of names of widgets to be hidden.
|
|
||||||
"""
|
|
||||||
for widget in widgets:
|
|
||||||
self.actions[widget].setVisible(False)
|
|
||||||
|
|
||||||
def makeWidgetsVisible(self, widgets):
|
|
||||||
"""
|
|
||||||
Show a set of widgets.
|
|
||||||
|
|
||||||
``widgets``
|
|
||||||
The list of names of widgets to be shown.
|
|
||||||
"""
|
|
||||||
for widget in widgets:
|
|
||||||
self.actions[widget].setVisible(True)
|
|
||||||
|
|
||||||
def addPushButton(self, image_file=None, text=u''):
|
|
||||||
"""
|
|
||||||
Adds a push button to the toolbar.
|
|
||||||
|
|
||||||
Returns the push button
|
|
||||||
"""
|
|
||||||
push_button = QtGui.QPushButton(build_icon(image_file), text)
|
|
||||||
push_button.setCheckable(True)
|
|
||||||
push_button.setFlat(True)
|
|
||||||
self.addWidget(push_button)
|
|
||||||
return push_button
|
|
||||||
|
@ -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')
|
||||||
@ -114,6 +115,8 @@ class UiStrings(object):
|
|||||||
'The abbreviated unit for seconds')
|
'The abbreviated unit for seconds')
|
||||||
self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
|
self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
|
||||||
self.Search = translate('OpenLP.Ui', 'Search')
|
self.Search = translate('OpenLP.Ui', 'Search')
|
||||||
|
self.SearchThemes = translate(
|
||||||
|
'OpenLP.Ui', 'Search Themes...', 'Search bar place holder text ')
|
||||||
self.SelectDelete = translate('OpenLP.Ui', 'You must select an item '
|
self.SelectDelete = translate('OpenLP.Ui', 'You must select an item '
|
||||||
'to delete.')
|
'to delete.')
|
||||||
self.SelectEdit = translate('OpenLP.Ui', 'You must select an item to '
|
self.SelectEdit = translate('OpenLP.Ui', 'You must select an item to '
|
||||||
@ -280,100 +283,102 @@ def create_up_down_push_button_set(parent):
|
|||||||
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
|
||||||
return up_button, down_button
|
return up_button, down_button
|
||||||
|
|
||||||
def base_action(parent, name, category=None):
|
def create_action(parent, name, **kwargs):
|
||||||
"""
|
"""
|
||||||
Return the most basic action with the object name set.
|
Return an action with the object name set and the given parameters.
|
||||||
|
|
||||||
``category``
|
``parent``
|
||||||
The category the action should be listed in the shortcut dialog. If you
|
A QtCore.QObject for the actions parent (required).
|
||||||
not wish, that this action is added to the shortcut dialog, then do not
|
|
||||||
state any.
|
|
||||||
"""
|
|
||||||
action = QtGui.QAction(parent)
|
|
||||||
action.setObjectName(name)
|
|
||||||
if category is not None:
|
|
||||||
action_list = ActionList.get_instance()
|
|
||||||
action_list.add_action(action, category)
|
|
||||||
return action
|
|
||||||
|
|
||||||
def checkable_action(parent, name, checked=None, category=None):
|
``name``
|
||||||
"""
|
A string which is set as object name (required).
|
||||||
Return a standard action with the checkable attribute set.
|
|
||||||
"""
|
|
||||||
action = base_action(parent, name, category)
|
|
||||||
action.setCheckable(True)
|
|
||||||
if checked is not None:
|
|
||||||
action.setChecked(checked)
|
|
||||||
return action
|
|
||||||
|
|
||||||
def icon_action(parent, name, icon, checked=None, category=None):
|
|
||||||
"""
|
|
||||||
Return a standard action with an icon.
|
|
||||||
"""
|
|
||||||
if checked is not None:
|
|
||||||
action = checkable_action(parent, name, checked, category)
|
|
||||||
else:
|
|
||||||
action = base_action(parent, name, category)
|
|
||||||
action.setIcon(build_icon(icon))
|
|
||||||
return action
|
|
||||||
|
|
||||||
def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None,
|
|
||||||
category=None, context=QtCore.Qt.WindowShortcut):
|
|
||||||
"""
|
|
||||||
Return a shortcut enabled action.
|
|
||||||
"""
|
|
||||||
action = QtGui.QAction(parent)
|
|
||||||
action.setObjectName(name)
|
|
||||||
if icon is not None:
|
|
||||||
action.setIcon(build_icon(icon))
|
|
||||||
if checked is not None:
|
|
||||||
action.setCheckable(True)
|
|
||||||
action.setChecked(checked)
|
|
||||||
if shortcuts:
|
|
||||||
action.setShortcuts(shortcuts)
|
|
||||||
action.setShortcutContext(context)
|
|
||||||
action_list = ActionList.get_instance()
|
|
||||||
action_list.add_action(action, category)
|
|
||||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), function)
|
|
||||||
return action
|
|
||||||
|
|
||||||
def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
|
|
||||||
context=QtCore.Qt.WidgetShortcut):
|
|
||||||
"""
|
|
||||||
Utility method to help build context menus.
|
|
||||||
|
|
||||||
``base``
|
|
||||||
The parent menu to add this menu item to
|
|
||||||
|
|
||||||
``icon``
|
|
||||||
An icon for this action
|
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text to display for this action
|
A string for the action text.
|
||||||
|
|
||||||
``slot``
|
``icon``
|
||||||
The code to run when this action is triggered
|
Either a QIcon, a resource string, or a file location string for the
|
||||||
|
action icon.
|
||||||
|
|
||||||
|
``tooltip``
|
||||||
|
A string for the action tool tip.
|
||||||
|
|
||||||
|
``statustip``
|
||||||
|
A string for the action status tip.
|
||||||
|
|
||||||
|
``checked``
|
||||||
|
A bool for the state. If ``None`` the Action is not checkable.
|
||||||
|
|
||||||
|
``enabled``
|
||||||
|
False in case the action should be disabled.
|
||||||
|
|
||||||
|
``visible``
|
||||||
|
False in case the action should be hidden.
|
||||||
|
|
||||||
|
``separator``
|
||||||
|
True in case the action will be considered a separator.
|
||||||
|
|
||||||
|
``data``
|
||||||
|
Data which is set as QVariant type.
|
||||||
|
|
||||||
``shortcuts``
|
``shortcuts``
|
||||||
The action's shortcuts.
|
A QList<QKeySequence> (or a list of strings) which are set as shortcuts.
|
||||||
|
|
||||||
``category``
|
|
||||||
The category the shortcut should be listed in the shortcut dialog. If
|
|
||||||
left to ``None``, then the action will be hidden in the shortcut dialog.
|
|
||||||
|
|
||||||
``context``
|
``context``
|
||||||
The context the shortcut is valid.
|
A context for the shortcut execution.
|
||||||
|
|
||||||
|
``category``
|
||||||
|
A category the action should be listed in the shortcut dialog.
|
||||||
|
|
||||||
|
``triggers``
|
||||||
|
A slot which is connected to the actions ``triggered()`` slot.
|
||||||
"""
|
"""
|
||||||
action = QtGui.QAction(text, base)
|
action = QtGui.QAction(parent)
|
||||||
if icon:
|
action.setObjectName(name)
|
||||||
action.setIcon(build_icon(icon))
|
if kwargs.get(u'text'):
|
||||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot)
|
action.setText(kwargs.pop(u'text'))
|
||||||
if shortcuts is not None:
|
if kwargs.get(u'icon'):
|
||||||
action.setShortcuts(shortcuts)
|
action.setIcon(build_icon(kwargs.pop(u'icon')))
|
||||||
action.setShortcutContext(context)
|
if kwargs.get(u'tooltip'):
|
||||||
|
action.setToolTip(kwargs.pop(u'tooltip'))
|
||||||
|
if kwargs.get(u'statustip'):
|
||||||
|
action.setStatusTip(kwargs.pop(u'statustip'))
|
||||||
|
if kwargs.get(u'checked') is not None:
|
||||||
|
action.setCheckable(True)
|
||||||
|
action.setChecked(kwargs.pop(u'checked'))
|
||||||
|
if not kwargs.pop(u'enabled', True):
|
||||||
|
action.setEnabled(False)
|
||||||
|
if not kwargs.pop(u'visible', True):
|
||||||
|
action.setVisible(False)
|
||||||
|
if kwargs.pop(u'separator', False):
|
||||||
|
action.setSeparator(True)
|
||||||
|
if u'data' in kwargs:
|
||||||
|
action.setData(QtCore.QVariant(kwargs.pop(u'data')))
|
||||||
|
if kwargs.get(u'shortcuts'):
|
||||||
|
action.setShortcuts(kwargs.pop(u'shortcuts'))
|
||||||
|
if u'context' in kwargs:
|
||||||
|
action.setShortcutContext(kwargs.pop(u'context'))
|
||||||
|
if kwargs.get(u'category'):
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_action(action)
|
action_list.add_action(action, unicode(kwargs.pop(u'category')))
|
||||||
base.addAction(action)
|
if kwargs.get(u'triggers'):
|
||||||
|
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
|
||||||
|
kwargs.pop(u'triggers'))
|
||||||
|
for key in kwargs.keys():
|
||||||
|
if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked',
|
||||||
|
u'shortcuts', u'category', u'triggers']:
|
||||||
|
log.warn(u'Parameter %s was not consumed in create_action().', key)
|
||||||
|
return action
|
||||||
|
|
||||||
|
def create_widget_action(parent, name=u'', **kwargs):
|
||||||
|
"""
|
||||||
|
Return a new QAction by calling ``create_action(parent, name, **kwargs)``.
|
||||||
|
The shortcut context defaults to ``QtCore.Qt.WidgetShortcut`` and the action
|
||||||
|
is added to the parents action list.
|
||||||
|
"""
|
||||||
|
kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut)
|
||||||
|
action = create_action(parent, name, **kwargs)
|
||||||
|
parent.addAction(action)
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def context_menu(base, icon, text):
|
def context_menu(base, icon, text):
|
||||||
@ -393,18 +398,6 @@ def context_menu(base, icon, text):
|
|||||||
action.setIcon(build_icon(icon))
|
action.setIcon(build_icon(icon))
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def context_menu_separator(base):
|
|
||||||
"""
|
|
||||||
Add a separator to a context menu
|
|
||||||
|
|
||||||
``base``
|
|
||||||
The menu object to add the separator to
|
|
||||||
"""
|
|
||||||
action = QtGui.QAction(u'', base)
|
|
||||||
action.setSeparator(True)
|
|
||||||
base.addAction(action)
|
|
||||||
return action
|
|
||||||
|
|
||||||
def add_widget_completer(cache, widget):
|
def add_widget_completer(cache, widget):
|
||||||
"""
|
"""
|
||||||
Adds a text autocompleter to a widget.
|
Adds a text autocompleter to a widget.
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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 '
|
||||||
|
@ -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, #
|
||||||
|
@ -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,23 @@ 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 may not contain any of the following characters: '
|
||||||
|
'/\\?*|<>\[\]":+\n'
|
||||||
|
'See http://docs.python.org/library/datetime.html'
|
||||||
|
'#strftime-strptime-behavior for more information.'))
|
||||||
|
self.defaultImage = u':/graphics/openlp-splash-screen.png'
|
||||||
|
self.defaultColor = u'#ffffff'
|
||||||
self.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 +98,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 +183,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 +192,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 +283,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 +333,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 next or previous Service Item from the '
|
||||||
|
'top and bottom slides of each Service Item.'))
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
"""
|
"""
|
||||||
@ -198,14 +387,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 +427,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 +456,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 +531,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
|
||||||
|
@ -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, #
|
||||||
|
@ -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__ + \
|
||||||
@ -144,7 +150,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
|||||||
translate('OpenLP.ExceptionForm',
|
translate('OpenLP.ExceptionForm',
|
||||||
'Text files (*.txt *.log *.text)'))
|
'Text files (*.txt *.log *.text)'))
|
||||||
if filename:
|
if filename:
|
||||||
filename = unicode(QtCore.QDir.toNativeSeparators(filename))
|
filename = unicode(filename).replace(u'/', os.path.sep)
|
||||||
SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(
|
SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(
|
||||||
filename))
|
filename))
|
||||||
report_text = report_text % self._createReport()
|
report_text = report_text % self._createReport()
|
||||||
|
@ -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)
|
||||||
|
@ -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, #
|
||||||
|
@ -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
|
||||||
|
|
||||||
@ -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()
|
||||||
@ -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',
|
||||||
|
@ -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, #
|
||||||
|
@ -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,6 +27,7 @@
|
|||||||
|
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib.ui import create_action
|
||||||
from openlp.core.utils import LanguageManager
|
from openlp.core.utils import LanguageManager
|
||||||
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
|
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
|
||||||
|
|
||||||
@ -55,8 +56,7 @@ class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
|
|||||||
LanguageManager.set_language(False, False)
|
LanguageManager.set_language(False, False)
|
||||||
else:
|
else:
|
||||||
LanguageManager.auto_language = False
|
LanguageManager.auto_language = False
|
||||||
action = QtGui.QAction(None)
|
action = create_action(None, self.languageComboBox.currentText())
|
||||||
action.setObjectName(unicode(self.languageComboBox.currentText()))
|
|
||||||
LanguageManager.set_language(action, False)
|
LanguageManager.set_language(action, False)
|
||||||
return QtGui.QDialog.accept(self)
|
return QtGui.QDialog.accept(self)
|
||||||
|
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -53,63 +53,64 @@ class GeneralTab(SettingsTab):
|
|||||||
"""
|
"""
|
||||||
self.setObjectName(u'GeneralTab')
|
self.setObjectName(u'GeneralTab')
|
||||||
SettingsTab.setupUi(self)
|
SettingsTab.setupUi(self)
|
||||||
|
self.tabLayout.setStretch(1, 1)
|
||||||
|
# Monitors
|
||||||
self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn)
|
self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
self.monitorGroupBox.setObjectName(u'monitorGroupBox')
|
self.monitorGroupBox.setObjectName(u'monitorGroupBox')
|
||||||
self.monitorLayout = QtGui.QFormLayout(self.monitorGroupBox)
|
self.monitorLayout = QtGui.QGridLayout(self.monitorGroupBox)
|
||||||
self.monitorLayout.setObjectName(u'monitorLayout')
|
self.monitorLayout.setObjectName(u'monitorLayout')
|
||||||
self.monitorLabel = QtGui.QLabel(self.monitorGroupBox)
|
self.monitorRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
|
||||||
self.monitorLabel.setObjectName(u'monitorLabel')
|
self.monitorRadioButton.setObjectName(u'monitorRadioButton')
|
||||||
self.monitorLayout.addRow(self.monitorLabel)
|
self.monitorLayout.addWidget(self.monitorRadioButton, 0, 0, 1, 5)
|
||||||
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
|
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
|
||||||
self.monitorComboBox.setObjectName(u'monitorComboBox')
|
self.monitorComboBox.setObjectName(u'monitorComboBox')
|
||||||
self.monitorLayout.addRow(self.monitorComboBox)
|
self.monitorLayout.addWidget(self.monitorComboBox, 1, 1, 1, 4)
|
||||||
self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox)
|
self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox)
|
||||||
self.displayOnMonitorCheck.setObjectName(u'monitorComboBox')
|
self.displayOnMonitorCheck.setObjectName(u'monitorComboBox')
|
||||||
self.monitorLayout.addRow(self.displayOnMonitorCheck)
|
self.monitorLayout.addWidget(self.displayOnMonitorCheck, 2, 1, 1, 4)
|
||||||
|
# Display Position
|
||||||
|
self.overrideRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
|
||||||
|
self.overrideRadioButton.setObjectName(u'overrideRadioButton')
|
||||||
|
self.monitorLayout.addWidget(self.overrideRadioButton, 3, 0, 1, 5)
|
||||||
|
# Custom position
|
||||||
|
self.customXLabel = QtGui.QLabel(self.monitorGroupBox)
|
||||||
|
self.customXLabel.setObjectName(u'customXLabel')
|
||||||
|
self.monitorLayout.addWidget(self.customXLabel, 4, 1)
|
||||||
|
self.customXValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
|
||||||
|
self.customXValueEdit.setObjectName(u'customXValueEdit')
|
||||||
|
self.customXValueEdit.setRange(-9999, 9999)
|
||||||
|
self.monitorLayout.addWidget(self.customXValueEdit, 5, 1)
|
||||||
|
self.customYLabel = QtGui.QLabel(self.monitorGroupBox)
|
||||||
|
self.customYLabel.setObjectName(u'customYLabel')
|
||||||
|
self.monitorLayout.addWidget(self.customYLabel, 4, 2)
|
||||||
|
self.customYValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
|
||||||
|
self.customYValueEdit.setObjectName(u'customYValueEdit')
|
||||||
|
self.customYValueEdit.setRange(-9999, 9999)
|
||||||
|
self.monitorLayout.addWidget(self.customYValueEdit, 5, 2)
|
||||||
|
self.customWidthLabel = QtGui.QLabel(self.monitorGroupBox)
|
||||||
|
self.customWidthLabel.setObjectName(u'customWidthLabel')
|
||||||
|
self.monitorLayout.addWidget(self.customWidthLabel, 4, 3)
|
||||||
|
self.customWidthValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
|
||||||
|
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
|
||||||
|
self.customWidthValueEdit.setMaximum(9999)
|
||||||
|
self.monitorLayout.addWidget(self.customWidthValueEdit, 5, 3)
|
||||||
|
self.customHeightLabel = QtGui.QLabel(self.monitorGroupBox)
|
||||||
|
self.customHeightLabel.setObjectName(u'customHeightLabel')
|
||||||
|
self.monitorLayout.addWidget(self.customHeightLabel, 4, 4)
|
||||||
|
self.customHeightValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
|
||||||
|
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
|
||||||
|
self.customHeightValueEdit.setMaximum(9999)
|
||||||
|
self.monitorLayout.addWidget(self.customHeightValueEdit, 5, 4)
|
||||||
|
# Set up the stretchiness of each column, so that the first column
|
||||||
|
# less stretchy (and therefore smaller) than the others
|
||||||
|
self.monitorLayout.setColumnStretch(0, 1)
|
||||||
|
self.monitorLayout.setColumnStretch(1, 3)
|
||||||
|
self.monitorLayout.setColumnStretch(2, 3)
|
||||||
|
self.monitorLayout.setColumnStretch(3, 3)
|
||||||
|
self.monitorLayout.setColumnStretch(4, 3)
|
||||||
self.leftLayout.addWidget(self.monitorGroupBox)
|
self.leftLayout.addWidget(self.monitorGroupBox)
|
||||||
self.startupGroupBox = QtGui.QGroupBox(self.leftColumn)
|
# CCLI Details
|
||||||
self.startupGroupBox.setObjectName(u'startupGroupBox')
|
self.ccliGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
|
|
||||||
self.startupLayout.setObjectName(u'startupLayout')
|
|
||||||
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
|
||||||
self.warningCheckBox.setObjectName(u'warningCheckBox')
|
|
||||||
self.startupLayout.addWidget(self.warningCheckBox)
|
|
||||||
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
|
||||||
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
|
|
||||||
self.startupLayout.addWidget(self.autoOpenCheckBox)
|
|
||||||
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
|
||||||
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
|
|
||||||
self.startupLayout.addWidget(self.showSplashCheckBox)
|
|
||||||
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
|
||||||
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
|
|
||||||
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
|
|
||||||
self.leftLayout.addWidget(self.startupGroupBox)
|
|
||||||
self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn)
|
|
||||||
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
|
|
||||||
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
|
|
||||||
self.settingsLayout.setObjectName(u'settingsLayout')
|
|
||||||
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
|
||||||
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
|
|
||||||
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
|
|
||||||
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
|
||||||
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
|
|
||||||
self.settingsLayout.addRow(self.autoUnblankCheckBox)
|
|
||||||
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
|
||||||
self.autoPreviewCheckBox.setObjectName(u'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
|
|
||||||
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
|
|
||||||
self.timeoutLabel.setObjectName(u'timeoutLabel')
|
|
||||||
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
|
|
||||||
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
|
|
||||||
self.timeoutSpinBox.setRange(1, 180)
|
|
||||||
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
|
|
||||||
self.leftLayout.addWidget(self.settingsGroupBox)
|
|
||||||
self.leftLayout.addStretch()
|
|
||||||
self.ccliGroupBox = QtGui.QGroupBox(self.rightColumn)
|
|
||||||
self.ccliGroupBox.setObjectName(u'ccliGroupBox')
|
self.ccliGroupBox.setObjectName(u'ccliGroupBox')
|
||||||
self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox)
|
self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox)
|
||||||
self.ccliLayout.setObjectName(u'ccliLayout')
|
self.ccliLayout.setObjectName(u'ccliLayout')
|
||||||
@ -130,59 +131,64 @@ class GeneralTab(SettingsTab):
|
|||||||
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
|
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
|
||||||
self.passwordEdit.setObjectName(u'passwordEdit')
|
self.passwordEdit.setObjectName(u'passwordEdit')
|
||||||
self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit)
|
self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit)
|
||||||
self.rightLayout.addWidget(self.ccliGroupBox)
|
self.leftLayout.addWidget(self.ccliGroupBox)
|
||||||
# Moved here from display tab
|
|
||||||
self.displayGroupBox = QtGui.QGroupBox(self.rightColumn)
|
|
||||||
self.displayGroupBox.setObjectName(u'displayGroupBox')
|
|
||||||
self.displayLayout = QtGui.QGridLayout(self.displayGroupBox)
|
|
||||||
self.displayLayout.setObjectName(u'displayLayout')
|
|
||||||
self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox)
|
|
||||||
self.overrideCheckBox.setObjectName(u'overrideCheckBox')
|
|
||||||
self.displayLayout.addWidget(self.overrideCheckBox, 2, 0, 1, 4)
|
|
||||||
self.rightLayout.addWidget(self.displayGroupBox)
|
|
||||||
# Custom position
|
|
||||||
self.customXLabel = QtGui.QLabel(self.displayGroupBox)
|
|
||||||
self.customXLabel.setObjectName(u'customXLabel')
|
|
||||||
self.displayLayout.addWidget(self.customXLabel, 3, 0)
|
|
||||||
self.customXValueEdit = QtGui.QSpinBox(self.displayGroupBox)
|
|
||||||
self.customXValueEdit.setObjectName(u'customXValueEdit')
|
|
||||||
self.customXValueEdit.setRange(-9999, 9999)
|
|
||||||
self.displayLayout.addWidget(self.customXValueEdit, 4, 0)
|
|
||||||
self.customYLabel = QtGui.QLabel(self.displayGroupBox)
|
|
||||||
self.customYLabel.setObjectName(u'customYLabel')
|
|
||||||
self.displayLayout.addWidget(self.customYLabel, 3, 1)
|
|
||||||
self.customYValueEdit = QtGui.QSpinBox(self.displayGroupBox)
|
|
||||||
self.customYValueEdit.setObjectName(u'customYValueEdit')
|
|
||||||
self.customYValueEdit.setRange(-9999, 9999)
|
|
||||||
self.displayLayout.addWidget(self.customYValueEdit, 4, 1)
|
|
||||||
self.customWidthLabel = QtGui.QLabel(self.displayGroupBox)
|
|
||||||
self.customWidthLabel.setObjectName(u'customWidthLabel')
|
|
||||||
self.displayLayout.addWidget(self.customWidthLabel, 3, 2)
|
|
||||||
self.customWidthValueEdit = QtGui.QSpinBox(self.displayGroupBox)
|
|
||||||
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
|
|
||||||
self.customWidthValueEdit.setMaximum(9999)
|
|
||||||
self.displayLayout.addWidget(self.customWidthValueEdit, 4, 2)
|
|
||||||
self.customHeightLabel = QtGui.QLabel(self.displayGroupBox)
|
|
||||||
self.customHeightLabel.setObjectName(u'customHeightLabel')
|
|
||||||
self.displayLayout.addWidget(self.customHeightLabel, 3, 3)
|
|
||||||
self.customHeightValueEdit = QtGui.QSpinBox(self.displayGroupBox)
|
|
||||||
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
|
|
||||||
self.customHeightValueEdit.setMaximum(9999)
|
|
||||||
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
|
|
||||||
self.rightLayout.addWidget(self.displayGroupBox)
|
|
||||||
# Background audio
|
# Background audio
|
||||||
self.audioGroupBox = QtGui.QGroupBox(self.rightColumn)
|
self.audioGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
self.audioGroupBox.setObjectName(u'audioGroupBox')
|
self.audioGroupBox.setObjectName(u'audioGroupBox')
|
||||||
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
|
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
|
||||||
self.audioLayout.setObjectName(u'audioLayout')
|
self.audioLayout.setObjectName(u'audioLayout')
|
||||||
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.rightLayout.addWidget(self.audioGroupBox)
|
self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
|
||||||
|
self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
|
||||||
|
self.audioLayout.addWidget(self.repeatListCheckBox)
|
||||||
|
self.leftLayout.addWidget(self.audioGroupBox)
|
||||||
|
self.leftLayout.addStretch()
|
||||||
|
# Application Startup
|
||||||
|
self.startupGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
|
self.startupGroupBox.setObjectName(u'startupGroupBox')
|
||||||
|
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
|
||||||
|
self.startupLayout.setObjectName(u'startupLayout')
|
||||||
|
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||||
|
self.warningCheckBox.setObjectName(u'warningCheckBox')
|
||||||
|
self.startupLayout.addWidget(self.warningCheckBox)
|
||||||
|
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||||
|
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
|
||||||
|
self.startupLayout.addWidget(self.autoOpenCheckBox)
|
||||||
|
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||||
|
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
|
||||||
|
self.startupLayout.addWidget(self.showSplashCheckBox)
|
||||||
|
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||||
|
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
|
||||||
|
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
|
||||||
|
self.rightLayout.addWidget(self.startupGroupBox)
|
||||||
|
# Application Settings
|
||||||
|
self.settingsGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
|
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
|
||||||
|
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
|
||||||
|
self.settingsLayout.setObjectName(u'settingsLayout')
|
||||||
|
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
||||||
|
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
|
||||||
|
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
|
||||||
|
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
||||||
|
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
|
||||||
|
self.settingsLayout.addRow(self.autoUnblankCheckBox)
|
||||||
|
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
|
||||||
|
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
|
||||||
|
self.settingsLayout.addRow(self.autoPreviewCheckBox)
|
||||||
|
# Moved here from image tab
|
||||||
|
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
|
||||||
|
self.timeoutLabel.setObjectName(u'timeoutLabel')
|
||||||
|
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
|
||||||
|
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
|
||||||
|
self.timeoutSpinBox.setRange(1, 180)
|
||||||
|
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
|
||||||
|
self.rightLayout.addWidget(self.settingsGroupBox)
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
QtCore.QObject.connect(self.overrideCheckBox,
|
QtCore.QObject.connect(self.overrideRadioButton,
|
||||||
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled)
|
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideRadioButtonPressed)
|
||||||
QtCore.QObject.connect(self.customHeightValueEdit,
|
QtCore.QObject.connect(self.customHeightValueEdit,
|
||||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged)
|
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged)
|
||||||
QtCore.QObject.connect(self.customWidthValueEdit,
|
QtCore.QObject.connect(self.customWidthValueEdit,
|
||||||
@ -209,7 +215,7 @@ class GeneralTab(SettingsTab):
|
|||||||
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
|
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
|
||||||
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
|
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
|
||||||
'Monitors'))
|
'Monitors'))
|
||||||
self.monitorLabel.setText(translate('OpenLP.GeneralTab',
|
self.monitorRadioButton.setText(translate('OpenLP.GeneralTab',
|
||||||
'Select monitor for output display:'))
|
'Select monitor for output display:'))
|
||||||
self.displayOnMonitorCheck.setText(
|
self.displayOnMonitorCheck.setText(
|
||||||
translate('OpenLP.GeneralTab', 'Display if a single screen'))
|
translate('OpenLP.GeneralTab', 'Display if a single screen'))
|
||||||
@ -231,8 +237,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'))
|
||||||
@ -244,10 +248,8 @@ class GeneralTab(SettingsTab):
|
|||||||
self.passwordLabel.setText(
|
self.passwordLabel.setText(
|
||||||
translate('OpenLP.GeneralTab', 'SongSelect password:'))
|
translate('OpenLP.GeneralTab', 'SongSelect password:'))
|
||||||
# Moved from display tab
|
# Moved from display tab
|
||||||
self.displayGroupBox.setTitle(
|
self.overrideRadioButton.setText(translate('OpenLP.GeneralTab',
|
||||||
translate('OpenLP.GeneralTab', 'Display Position'))
|
'Override display position:'))
|
||||||
self.overrideCheckBox.setText(translate('OpenLP.GeneralTab',
|
|
||||||
'Override display position'))
|
|
||||||
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
|
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
|
||||||
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
|
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
|
||||||
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
|
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
|
||||||
@ -256,6 +258,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,11 +293,12 @@ 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.monitorRadioButton.setChecked(
|
||||||
|
not settings.value(u'override position',
|
||||||
|
QtCore.QVariant(False)).toBool())
|
||||||
|
self.overrideRadioButton.setChecked(settings.value(u'override position',
|
||||||
QtCore.QVariant(False)).toBool())
|
QtCore.QVariant(False)).toBool())
|
||||||
self.customXValueEdit.setValue(settings.value(u'x position',
|
self.customXValueEdit.setValue(settings.value(u'x position',
|
||||||
QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0])
|
QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0])
|
||||||
@ -305,12 +310,20 @@ 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.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked())
|
||||||
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
self.displayOnMonitorCheck.setDisabled(
|
||||||
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
self.overrideRadioButton.isChecked())
|
||||||
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
self.customXValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||||
|
self.customYValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||||
|
self.customHeightValueEdit.setEnabled(
|
||||||
|
self.overrideRadioButton.isChecked())
|
||||||
|
self.customWidthValueEdit.setEnabled(
|
||||||
|
self.overrideRadioButton.isChecked())
|
||||||
self.display_changed = False
|
self.display_changed = False
|
||||||
|
settings.beginGroup(self.settingsSection)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
@ -336,8 +349,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',
|
||||||
@ -355,9 +366,11 @@ class GeneralTab(SettingsTab):
|
|||||||
settings.setValue(u'width',
|
settings.setValue(u'width',
|
||||||
QtCore.QVariant(self.customWidthValueEdit.value()))
|
QtCore.QVariant(self.customWidthValueEdit.value()))
|
||||||
settings.setValue(u'override position',
|
settings.setValue(u'override position',
|
||||||
QtCore.QVariant(self.overrideCheckBox.isChecked()))
|
QtCore.QVariant(self.overrideRadioButton.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)
|
||||||
@ -379,7 +392,7 @@ class GeneralTab(SettingsTab):
|
|||||||
self.customYValueEdit.value(),
|
self.customYValueEdit.value(),
|
||||||
self.customWidthValueEdit.value(),
|
self.customWidthValueEdit.value(),
|
||||||
self.customHeightValueEdit.value())
|
self.customHeightValueEdit.value())
|
||||||
if self.overrideCheckBox.isChecked():
|
if self.overrideRadioButton.isChecked():
|
||||||
self.screens.set_override_display()
|
self.screens.set_override_display()
|
||||||
else:
|
else:
|
||||||
self.screens.reset_current_display()
|
self.screens.reset_current_display()
|
||||||
@ -387,13 +400,15 @@ class GeneralTab(SettingsTab):
|
|||||||
Receiver.send_message(u'config_screen_changed')
|
Receiver.send_message(u'config_screen_changed')
|
||||||
self.display_changed = False
|
self.display_changed = False
|
||||||
|
|
||||||
def onOverrideCheckBoxToggled(self, checked):
|
def onOverrideRadioButtonPressed(self, checked):
|
||||||
"""
|
"""
|
||||||
Toggle screen state depending on check box state.
|
Toggle screen state depending on check box state.
|
||||||
|
|
||||||
``checked``
|
``checked``
|
||||||
The state of the check box (boolean).
|
The state of the check box (boolean).
|
||||||
"""
|
"""
|
||||||
|
self.monitorComboBox.setDisabled(checked)
|
||||||
|
self.displayOnMonitorCheck.setDisabled(checked)
|
||||||
self.customXValueEdit.setEnabled(checked)
|
self.customXValueEdit.setEnabled(checked)
|
||||||
self.customYValueEdit.setEnabled(checked)
|
self.customYValueEdit.setEnabled(checked)
|
||||||
self.customHeightValueEdit.setEnabled(checked)
|
self.customHeightValueEdit.setEnabled(checked)
|
||||||
|
@ -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,6 +63,11 @@ 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
|
||||||
|
# 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())
|
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)
|
||||||
|
@ -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, #
|
||||||
@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui
|
|||||||
|
|
||||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
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, create_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
|
||||||
@ -178,75 +178,78 @@ class Ui_MainWindow(object):
|
|||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(unicode(UiStrings().File),
|
action_list.add_category(unicode(UiStrings().File),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.fileNewItem = shortcut_action(mainWindow, u'fileNewItem',
|
self.fileNewItem = create_action(mainWindow, u'fileNewItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+N')],
|
icon=u':/general/general_new.png',
|
||||||
self.serviceManagerContents.onNewServiceClicked,
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
|
||||||
u':/general/general_new.png', category=unicode(UiStrings().File))
|
category=UiStrings().File,
|
||||||
self.fileOpenItem = shortcut_action(mainWindow, u'fileOpenItem',
|
triggers=self.serviceManagerContents.onNewServiceClicked)
|
||||||
[QtGui.QKeySequence(u'Ctrl+O')],
|
self.fileOpenItem = create_action(mainWindow, u'fileOpenItem',
|
||||||
self.serviceManagerContents.onLoadServiceClicked,
|
icon=u':/general/general_open.png',
|
||||||
u':/general/general_open.png', category=unicode(UiStrings().File))
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
|
||||||
self.fileSaveItem = shortcut_action(mainWindow, u'fileSaveItem',
|
category=UiStrings().File,
|
||||||
[QtGui.QKeySequence(u'Ctrl+S')],
|
triggers=self.serviceManagerContents.onLoadServiceClicked)
|
||||||
self.serviceManagerContents.saveFile,
|
self.fileSaveItem = create_action(mainWindow, u'fileSaveItem',
|
||||||
u':/general/general_save.png', category=unicode(UiStrings().File))
|
icon=u':/general/general_save.png',
|
||||||
self.fileSaveAsItem = shortcut_action(mainWindow, u'fileSaveAsItem',
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
|
||||||
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
category=UiStrings().File,
|
||||||
self.serviceManagerContents.saveFileAs,
|
triggers=self.serviceManagerContents.saveFile)
|
||||||
category=unicode(UiStrings().File))
|
self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem',
|
||||||
self.printServiceOrderItem = shortcut_action(mainWindow,
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||||
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
|
category=UiStrings().File,
|
||||||
self.serviceManagerContents.printServiceOrder,
|
triggers=self.serviceManagerContents.saveFileAs)
|
||||||
category=unicode(UiStrings().File))
|
self.printServiceOrderItem = create_action(mainWindow,
|
||||||
self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
|
u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
|
||||||
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
|
category=UiStrings().File,
|
||||||
u':/system/system_exit.png', category=unicode(UiStrings().File))
|
triggers=self.serviceManagerContents.printServiceOrder)
|
||||||
|
self.fileExitItem = create_action(mainWindow, u'fileExitItem',
|
||||||
|
icon=u':/system/system_exit.png',
|
||||||
|
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
|
||||||
|
category=UiStrings().File, triggers=mainWindow.close)
|
||||||
action_list.add_category(unicode(UiStrings().Import),
|
action_list.add_category(unicode(UiStrings().Import),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.importThemeItem = base_action(
|
self.importThemeItem = create_action(mainWindow,
|
||||||
mainWindow, u'importThemeItem', unicode(UiStrings().Import))
|
u'importThemeItem', category=UiStrings().Import)
|
||||||
self.importLanguageItem = base_action(
|
self.importLanguageItem = create_action(mainWindow,
|
||||||
mainWindow, u'importLanguageItem')#, unicode(UiStrings().Import))
|
u'importLanguageItem')#, category=UiStrings().Import)
|
||||||
action_list.add_category(unicode(UiStrings().Export),
|
action_list.add_category(unicode(UiStrings().Export),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.exportThemeItem = base_action(
|
self.exportThemeItem = create_action(mainWindow,
|
||||||
mainWindow, u'exportThemeItem', unicode(UiStrings().Export))
|
u'exportThemeItem', category=UiStrings().Export)
|
||||||
self.exportLanguageItem = base_action(
|
self.exportLanguageItem = create_action(mainWindow,
|
||||||
mainWindow, u'exportLanguageItem')#, unicode(UiStrings().Export))
|
u'exportLanguageItem')#, category=UiStrings().Export)
|
||||||
action_list.add_category(unicode(UiStrings().View),
|
action_list.add_category(unicode(UiStrings().View),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.viewMediaManagerItem = shortcut_action(mainWindow,
|
self.viewMediaManagerItem = create_action(mainWindow,
|
||||||
u'viewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
|
u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
|
||||||
self.toggleMediaManager, u':/system/system_mediamanager.png',
|
icon=u':/system/system_mediamanager.png',
|
||||||
self.mediaManagerDock.isVisible(), unicode(UiStrings().View))
|
checked=self.mediaManagerDock.isVisible(),
|
||||||
self.viewThemeManagerItem = shortcut_action(mainWindow,
|
category=UiStrings().View, triggers=self.toggleMediaManager)
|
||||||
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
self.viewThemeManagerItem = create_action(mainWindow,
|
||||||
self.toggleThemeManager, u':/system/system_thememanager.png',
|
u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
|
||||||
self.themeManagerDock.isVisible(), unicode(UiStrings().View))
|
icon=u':/system/system_thememanager.png',
|
||||||
self.viewServiceManagerItem = shortcut_action(mainWindow,
|
checked=self.themeManagerDock.isVisible(),
|
||||||
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
category=UiStrings().View, triggers=self.toggleThemeManager)
|
||||||
self.toggleServiceManager, u':/system/system_servicemanager.png',
|
self.viewServiceManagerItem = create_action(mainWindow,
|
||||||
self.serviceManagerDock.isVisible(), unicode(UiStrings().View))
|
u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
|
||||||
self.viewPreviewPanel = shortcut_action(mainWindow,
|
icon=u':/system/system_servicemanager.png',
|
||||||
u'viewPreviewPanel', [QtGui.QKeySequence(u'F11')],
|
checked=self.serviceManagerDock.isVisible(),
|
||||||
self.setPreviewPanelVisibility, checked=previewVisible,
|
category=UiStrings().View, triggers=self.toggleServiceManager)
|
||||||
category=unicode(UiStrings().View))
|
self.viewPreviewPanel = create_action(mainWindow, u'viewPreviewPanel',
|
||||||
self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
|
shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
|
||||||
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
|
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
|
||||||
checked=liveVisible, category=unicode(UiStrings().View))
|
self.viewLivePanel = create_action(mainWindow, u'viewLivePanel',
|
||||||
self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
|
shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
|
||||||
None, self.setLockPanel,
|
category=UiStrings().View, triggers=self.setLivePanelVisibility)
|
||||||
checked=panelLocked, category=None)
|
self.lockPanel = create_action(mainWindow, u'lockPanel',
|
||||||
|
checked=panelLocked, triggers=self.setLockPanel)
|
||||||
action_list.add_category(unicode(UiStrings().ViewMode),
|
action_list.add_category(unicode(UiStrings().ViewMode),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.modeDefaultItem = checkable_action(
|
self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem',
|
||||||
mainWindow, u'modeDefaultItem',
|
checked=False, category=UiStrings().ViewMode)
|
||||||
category=unicode(UiStrings().ViewMode))
|
self.modeSetupItem = create_action(mainWindow, u'modeSetupItem',
|
||||||
self.modeSetupItem = checkable_action(
|
checked=False, category=UiStrings().ViewMode)
|
||||||
mainWindow, u'modeSetupItem',
|
self.modeLiveItem = create_action(mainWindow, u'modeLiveItem',
|
||||||
category=unicode(UiStrings().ViewMode))
|
checked=True, category=UiStrings().ViewMode)
|
||||||
self.modeLiveItem = checkable_action(
|
|
||||||
mainWindow, u'modeLiveItem', True, unicode(UiStrings().ViewMode))
|
|
||||||
self.modeGroup = QtGui.QActionGroup(mainWindow)
|
self.modeGroup = QtGui.QActionGroup(mainWindow)
|
||||||
self.modeGroup.addAction(self.modeDefaultItem)
|
self.modeGroup.addAction(self.modeDefaultItem)
|
||||||
self.modeGroup.addAction(self.modeSetupItem)
|
self.modeGroup.addAction(self.modeSetupItem)
|
||||||
@ -254,25 +257,27 @@ class Ui_MainWindow(object):
|
|||||||
self.modeDefaultItem.setChecked(True)
|
self.modeDefaultItem.setChecked(True)
|
||||||
action_list.add_category(unicode(UiStrings().Tools),
|
action_list.add_category(unicode(UiStrings().Tools),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.toolsAddToolItem = icon_action(mainWindow, u'toolsAddToolItem',
|
self.toolsAddToolItem = create_action(mainWindow,
|
||||||
u':/tools/tools_add.png', category=unicode(UiStrings().Tools))
|
u'toolsAddToolItem', icon=u':/tools/tools_add.png',
|
||||||
self.toolsOpenDataFolder = icon_action(mainWindow,
|
category=UiStrings().Tools)
|
||||||
u'toolsOpenDataFolder', u':/general/general_open.png',
|
self.toolsOpenDataFolder = create_action(mainWindow,
|
||||||
category=unicode(UiStrings().Tools))
|
u'toolsOpenDataFolder', icon=u':/general/general_open.png',
|
||||||
self.toolsFirstTimeWizard = icon_action(mainWindow,
|
category=UiStrings().Tools)
|
||||||
u'toolsFirstTimeWizard', u':/general/general_revert.png',
|
self.toolsFirstTimeWizard = create_action(mainWindow,
|
||||||
category=unicode(UiStrings().Tools))
|
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
|
||||||
self.updateThemeImages = base_action(mainWindow,
|
category=UiStrings().Tools)
|
||||||
u'updateThemeImages', category=unicode(UiStrings().Tools))
|
self.updateThemeImages = create_action(mainWindow,
|
||||||
|
u'updateThemeImages', category=UiStrings().Tools)
|
||||||
action_list.add_category(unicode(UiStrings().Settings),
|
action_list.add_category(unicode(UiStrings().Settings),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.settingsPluginListItem = shortcut_action(mainWindow,
|
self.settingsPluginListItem = create_action(mainWindow,
|
||||||
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
|
u'settingsPluginListItem',
|
||||||
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
|
icon=u':/system/settings_plugin_list.png',
|
||||||
category=unicode(UiStrings().Settings))
|
shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
|
||||||
|
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
|
||||||
# i18n Language Items
|
# i18n Language Items
|
||||||
self.autoLanguageItem = checkable_action(mainWindow,
|
self.autoLanguageItem = create_action(mainWindow, u'autoLanguageItem',
|
||||||
u'autoLanguageItem', LanguageManager.auto_language)
|
checked=LanguageManager.auto_language)
|
||||||
self.languageGroup = QtGui.QActionGroup(mainWindow)
|
self.languageGroup = QtGui.QActionGroup(mainWindow)
|
||||||
self.languageGroup.setExclusive(True)
|
self.languageGroup.setExclusive(True)
|
||||||
self.languageGroup.setObjectName(u'languageGroup')
|
self.languageGroup.setObjectName(u'languageGroup')
|
||||||
@ -280,44 +285,43 @@ class Ui_MainWindow(object):
|
|||||||
qmList = LanguageManager.get_qm_list()
|
qmList = LanguageManager.get_qm_list()
|
||||||
savedLanguage = LanguageManager.get_language()
|
savedLanguage = LanguageManager.get_language()
|
||||||
for key in sorted(qmList.keys()):
|
for key in sorted(qmList.keys()):
|
||||||
languageItem = checkable_action(
|
languageItem = create_action(mainWindow, key,
|
||||||
mainWindow, key, qmList[key] == savedLanguage)
|
checked=qmList[key] == savedLanguage)
|
||||||
add_actions(self.languageGroup, [languageItem])
|
add_actions(self.languageGroup, [languageItem])
|
||||||
self.settingsShortcutsItem = icon_action(mainWindow,
|
self.settingsShortcutsItem = create_action(mainWindow,
|
||||||
u'settingsShortcutsItem',
|
u'settingsShortcutsItem',
|
||||||
u':/system/system_configure_shortcuts.png',
|
icon=u':/system/system_configure_shortcuts.png',
|
||||||
category=unicode(UiStrings().Settings))
|
category=UiStrings().Settings)
|
||||||
# Formatting Tags were also known as display tags.
|
# Formatting Tags were also known as display tags.
|
||||||
self.formattingTagItem = icon_action(mainWindow,
|
self.formattingTagItem = create_action(mainWindow,
|
||||||
u'displayTagItem', u':/system/tag_editor.png',
|
u'displayTagItem', icon=u':/system/tag_editor.png',
|
||||||
category=unicode(UiStrings().Settings))
|
category=UiStrings().Settings)
|
||||||
self.settingsConfigureItem = icon_action(mainWindow,
|
self.settingsConfigureItem = create_action(mainWindow,
|
||||||
u'settingsConfigureItem', u':/system/system_settings.png',
|
u'settingsConfigureItem', icon=u':/system/system_settings.png',
|
||||||
category=unicode(UiStrings().Settings))
|
category=UiStrings().Settings)
|
||||||
self.settingsImportItem = base_action(mainWindow,
|
self.settingsImportItem = create_action(mainWindow,
|
||||||
u'settingsImportItem', category=unicode(UiStrings().Settings))
|
u'settingsImportItem', category=UiStrings().Settings)
|
||||||
self.settingsExportItem = base_action(mainWindow,
|
self.settingsExportItem = create_action(mainWindow,
|
||||||
u'settingsExportItem', category=unicode(UiStrings().Settings))
|
u'settingsExportItem', category=UiStrings().Settings)
|
||||||
action_list.add_category(unicode(UiStrings().Help),
|
action_list.add_category(unicode(UiStrings().Help),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
|
self.aboutItem = create_action(mainWindow, u'aboutItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
|
icon=u':/system/system_about.png',
|
||||||
u':/system/system_about.png', category=unicode(UiStrings().Help))
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
||||||
|
category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
self.localHelpFile = os.path.join(
|
self.localHelpFile = os.path.join(
|
||||||
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
||||||
self.offlineHelpItem = shortcut_action(
|
self.offlineHelpItem = create_action(mainWindow, u'offlineHelpItem',
|
||||||
mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
|
icon=u':/system/system_help_contents.png',
|
||||||
self.onOfflineHelpClicked,
|
shortcuts=[QtGui.QKeySequence(u'F1')],
|
||||||
u':/system/system_help_contents.png',
|
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
|
||||||
category=unicode(UiStrings().Help))
|
self.onlineHelpItem = create_action(mainWindow, u'onlineHelpItem',
|
||||||
self.onlineHelpItem = shortcut_action(
|
icon=u':/system/system_online_help.png',
|
||||||
mainWindow, u'onlineHelpItem',
|
shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
|
||||||
[QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
|
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
|
||||||
u':/system/system_online_help.png',
|
self.webSiteItem = create_action(mainWindow,
|
||||||
category=unicode(UiStrings().Help))
|
u'webSiteItem', category=UiStrings().Help)
|
||||||
self.webSiteItem = base_action(
|
|
||||||
mainWindow, u'webSiteItem', category=unicode(UiStrings().Help))
|
|
||||||
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
|
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
|
||||||
self.importThemeItem, self.importLanguageItem))
|
self.importThemeItem, self.importLanguageItem))
|
||||||
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
|
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
|
||||||
@ -1059,7 +1063,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 +1310,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')
|
||||||
@ -1365,27 +1381,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
recentFileCount = QtCore.QSettings().value(
|
recentFileCount = QtCore.QSettings().value(
|
||||||
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
||||||
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
||||||
if QtCore.QFile.exists(recentFile)]
|
if os.path.isfile(unicode(recentFile))]
|
||||||
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
||||||
self.recentFilesMenu.clear()
|
self.recentFilesMenu.clear()
|
||||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||||
log.debug('Recent file name: %s', filename)
|
log.debug('Recent file name: %s', filename)
|
||||||
action = base_action(self, u'')
|
action = create_action(self, u'',
|
||||||
action.setText(u'&%d %s' %
|
text=u'&%d %s' % (fileId + 1, os.path.splitext(os.path.basename(
|
||||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
unicode(filename)))[0]), data=filename,
|
||||||
action.setData(QtCore.QVariant(filename))
|
triggers=self.serviceManagerContents.onRecentServiceClicked)
|
||||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
|
||||||
self.serviceManagerContents.onRecentServiceClicked)
|
|
||||||
self.recentFilesMenu.addAction(action)
|
self.recentFilesMenu.addAction(action)
|
||||||
clearRecentFilesAction = base_action(self, u'')
|
clearRecentFilesAction = create_action(self, u'',
|
||||||
clearRecentFilesAction.setText(
|
text=translate('OpenLP.MainWindow', 'Clear List',
|
||||||
translate('OpenLP.MainWindow', 'Clear List',
|
'Clear List of recent files'),
|
||||||
'Clear List of recent files'))
|
statustip=translate('OpenLP.MainWindow',
|
||||||
clearRecentFilesAction.setStatusTip(
|
'Clear the list of recent files.'),
|
||||||
translate('OpenLP.MainWindow', 'Clear the list of recent files.'))
|
enabled=not self.recentFiles.isEmpty(),
|
||||||
|
triggers=self.recentFiles.clear)
|
||||||
add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
|
add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
|
||||||
self.connect(clearRecentFilesAction, QtCore.SIGNAL(u'triggered()'),
|
|
||||||
self.recentFiles.clear)
|
|
||||||
clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
|
clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
|
||||||
|
|
||||||
def addRecentFile(self, filename):
|
def addRecentFile(self, filename):
|
||||||
|
@ -24,17 +24,21 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class MediaState(object):
|
class MediaState(object):
|
||||||
"""
|
"""
|
||||||
An enumeration for possible States of the Media Player (copied partially
|
An enumeration for possible States of the Media Player
|
||||||
from Phonon::State)
|
|
||||||
"""
|
"""
|
||||||
Loading = 0
|
Off = 0
|
||||||
Stopped = 1
|
Loaded = 1
|
||||||
Playing = 2
|
Playing = 2
|
||||||
Paused = 4
|
Paused = 3
|
||||||
Off = 6
|
Stopped = 4
|
||||||
|
|
||||||
|
|
||||||
class MediaType(object):
|
class MediaType(object):
|
||||||
@ -62,4 +66,48 @@ class MediaInfo(object):
|
|||||||
end_time = 0
|
end_time = 0
|
||||||
media_type = MediaType()
|
media_type = MediaType()
|
||||||
|
|
||||||
|
def get_media_players():
|
||||||
|
"""
|
||||||
|
This method extract the configured media players and overridden player from
|
||||||
|
the settings
|
||||||
|
|
||||||
|
``players_list``
|
||||||
|
this is a python list with all active media players
|
||||||
|
``overridden_player``
|
||||||
|
here an special media player is choosen for all media actions
|
||||||
|
"""
|
||||||
|
log.debug(u'get_media_players')
|
||||||
|
players = unicode(QtCore.QSettings().value(u'media/players').toString())
|
||||||
|
if not players:
|
||||||
|
players = u'webkit'
|
||||||
|
reg_ex = QtCore.QRegExp(".*\[(.*)\].*")
|
||||||
|
if QtCore.QSettings().value(u'media/override player',
|
||||||
|
QtCore.QVariant(QtCore.Qt.Unchecked)).toInt()[0] == QtCore.Qt.Checked:
|
||||||
|
if reg_ex.exactMatch(players):
|
||||||
|
overridden_player = u'%s' % reg_ex.cap(1)
|
||||||
|
else:
|
||||||
|
overridden_player = u'auto'
|
||||||
|
else:
|
||||||
|
overridden_player = u''
|
||||||
|
players_list = players.replace(u'[', u'').replace(u']', u'').split(u',')
|
||||||
|
return players_list, overridden_player
|
||||||
|
|
||||||
|
def set_media_players(players_list, overridden_player=u'auto'):
|
||||||
|
"""
|
||||||
|
This method saves the configured media players and overridden player to the
|
||||||
|
settings
|
||||||
|
|
||||||
|
``players_list``
|
||||||
|
this is a python list with all active media players
|
||||||
|
``overridden_player``
|
||||||
|
here an special media player is choosen for all media actions
|
||||||
|
"""
|
||||||
|
log.debug(u'set_media_players')
|
||||||
|
players = u','.join(players_list)
|
||||||
|
if QtCore.QSettings().value(u'media/override player',
|
||||||
|
QtCore.QVariant(QtCore.Qt.Unchecked)).toInt()[0] == \
|
||||||
|
QtCore.Qt.Checked and overridden_player != u'auto':
|
||||||
|
players = players.replace(overridden_player, u'[%s]' % overridden_player)
|
||||||
|
QtCore.QSettings().setValue(u'media/players', QtCore.QVariant(players))
|
||||||
|
|
||||||
from mediacontroller import MediaController
|
from mediacontroller import MediaController
|
||||||
|
@ -32,7 +32,8 @@ from PyQt4 import QtCore, QtGui
|
|||||||
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
||||||
from openlp.core.lib.mediaplayer import MediaPlayer
|
from openlp.core.lib.mediaplayer import MediaPlayer
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType
|
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, \
|
||||||
|
get_media_players, set_media_players
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -47,7 +48,6 @@ class MediaController(object):
|
|||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.mediaPlayers = {}
|
self.mediaPlayers = {}
|
||||||
self.controller = []
|
self.controller = []
|
||||||
self.overridenPlayer = ''
|
|
||||||
self.curDisplayMediaPlayer = {}
|
self.curDisplayMediaPlayer = {}
|
||||||
# Timer for video state
|
# Timer for video state
|
||||||
self.timer = QtCore.QTimer()
|
self.timer = QtCore.QTimer()
|
||||||
@ -58,23 +58,21 @@ class MediaController(object):
|
|||||||
QtCore.QObject.connect(self.timer,
|
QtCore.QObject.connect(self.timer,
|
||||||
QtCore.SIGNAL("timeout()"), self.video_state)
|
QtCore.SIGNAL("timeout()"), self.video_state)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_playback_play'), self.video_play)
|
QtCore.SIGNAL(u'playbackPlay'), self.video_play)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_playback_pause'), self.video_pause)
|
QtCore.SIGNAL(u'playbackPause'), self.video_pause)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_playback_stop'), self.video_stop)
|
QtCore.SIGNAL(u'playbackStop'), self.video_stop)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'seek_slider'), self.video_seek)
|
QtCore.SIGNAL(u'seekSlider'), self.video_seek)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'volume_slider'), self.video_volume)
|
QtCore.SIGNAL(u'volumeSlider'), self.video_volume)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_hide'), self.video_hide)
|
QtCore.SIGNAL(u'media_hide'), self.video_hide)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_blank'), self.video_blank)
|
QtCore.SIGNAL(u'media_blank'), self.video_blank)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'media_unblank'), self.video_unblank)
|
QtCore.SIGNAL(u'media_unblank'), self.video_unblank)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
|
||||||
QtCore.SIGNAL(u'media_override_player'), self.override_player)
|
|
||||||
# Signals for background video
|
# Signals for background video
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'songs_hide'), self.video_hide)
|
QtCore.SIGNAL(u'songs_hide'), self.video_hide)
|
||||||
@ -84,11 +82,7 @@ class MediaController(object):
|
|||||||
QtCore.SIGNAL(u'mediaitem_media_rebuild'), self.set_active_players)
|
QtCore.SIGNAL(u'mediaitem_media_rebuild'), self.set_active_players)
|
||||||
|
|
||||||
def set_active_players(self):
|
def set_active_players(self):
|
||||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
savedPlayers = get_media_players()[0]
|
||||||
QtCore.QVariant(u'webkit')).toString())
|
|
||||||
if len(playerSettings) == 0:
|
|
||||||
playerSettings = u'webkit'
|
|
||||||
savedPlayers = playerSettings.split(u',')
|
|
||||||
for player in self.mediaPlayers.keys():
|
for player in self.mediaPlayers.keys():
|
||||||
if player in savedPlayers:
|
if player in savedPlayers:
|
||||||
self.mediaPlayers[player].isActive = True
|
self.mediaPlayers[player].isActive = True
|
||||||
@ -100,7 +94,6 @@ 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):
|
||||||
@ -130,17 +123,14 @@ class MediaController(object):
|
|||||||
controller = controller_class(self)
|
controller = controller_class(self)
|
||||||
self.register_controllers(controller)
|
self.register_controllers(controller)
|
||||||
if self.mediaPlayers:
|
if self.mediaPlayers:
|
||||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
savedPlayers, overriddenPlayer = get_media_players()
|
||||||
QtCore.QVariant(u'webkit')).toString())
|
|
||||||
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)
|
||||||
newPlayerSetting = u','.join(savedPlayers)
|
set_media_players(savedPlayers, overriddenPlayer)
|
||||||
QtCore.QSettings().setValue(u'media/players',
|
|
||||||
QtCore.QVariant(newPlayerSetting))
|
|
||||||
self.set_active_players()
|
self.set_active_players()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@ -160,6 +150,11 @@ class MediaController(object):
|
|||||||
if self.curDisplayMediaPlayer[display] \
|
if self.curDisplayMediaPlayer[display] \
|
||||||
.state == MediaState.Playing:
|
.state == MediaState.Playing:
|
||||||
return
|
return
|
||||||
|
# no players are active anymore
|
||||||
|
for display in self.curDisplayMediaPlayer.keys():
|
||||||
|
if self.curDisplayMediaPlayer[display] \
|
||||||
|
.state != MediaState.Paused:
|
||||||
|
display.controller.seekSlider.setSliderPosition(0)
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
|
|
||||||
def get_media_display_css(self):
|
def get_media_display_css(self):
|
||||||
@ -204,47 +199,50 @@ class MediaController(object):
|
|||||||
controller.media_info = MediaInfo()
|
controller.media_info = MediaInfo()
|
||||||
# Build a Media ToolBar
|
# Build a Media ToolBar
|
||||||
controller.mediabar = OpenLPToolbar(controller)
|
controller.mediabar = OpenLPToolbar(controller)
|
||||||
controller.mediabar.addToolbarButton(
|
controller.mediabar.addToolbarAction(u'playbackPlay',
|
||||||
u'media_playback_play', u':/slides/media_playback_start.png',
|
text=u'media_playback_play',
|
||||||
translate('OpenLP.SlideController', 'Start playing media.'),
|
icon=u':/slides/media_playback_start.png',
|
||||||
controller.sendToPlugins)
|
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
||||||
controller.mediabar.addToolbarButton(
|
triggers=controller.sendToPlugins)
|
||||||
u'media_playback_pause', u':/slides/media_playback_pause.png',
|
controller.mediabar.addToolbarAction(u'playbackPause',
|
||||||
translate('OpenLP.SlideController', 'Pause playing media.'),
|
text=u'media_playback_pause',
|
||||||
controller.sendToPlugins)
|
icon=u':/slides/media_playback_pause.png',
|
||||||
controller.mediabar.addToolbarButton(
|
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||||
u'media_playback_stop', u':/slides/media_playback_stop.png',
|
triggers=controller.sendToPlugins)
|
||||||
translate('OpenLP.SlideController', 'Stop playing media.'),
|
controller.mediabar.addToolbarAction(u'playbackStop',
|
||||||
controller.sendToPlugins)
|
text=u'media_playback_stop',
|
||||||
|
icon=u':/slides/media_playback_stop.png',
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||||
|
triggers=controller.sendToPlugins)
|
||||||
# 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))
|
||||||
controller.seekSlider.setObjectName(u'seek_slider')
|
controller.seekSlider.setObjectName(u'seekSlider')
|
||||||
controller.mediabar.addToolbarWidget(u'Seek Slider',
|
controller.mediabar.addToolbarWidget(controller.seekSlider)
|
||||||
controller.seekSlider)
|
|
||||||
# Build the volumeSlider.
|
# Build the volumeSlider.
|
||||||
controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||||
controller.volumeSlider.setTickInterval(10)
|
controller.volumeSlider.setTickInterval(10)
|
||||||
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)
|
||||||
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||||
controller.volumeSlider.setObjectName(u'volume_slider')
|
controller.volumeSlider.setObjectName(u'volumeSlider')
|
||||||
controller.mediabar.addToolbarWidget(u'Audio Volume',
|
controller.mediabar.addToolbarWidget(controller.volumeSlider)
|
||||||
controller.volumeSlider)
|
|
||||||
control_panel.addWidget(controller.mediabar)
|
control_panel.addWidget(controller.mediabar)
|
||||||
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 +274,11 @@ 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 +319,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
|
||||||
@ -353,13 +357,9 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
Select the correct media Player type from the prioritized Player list
|
Select the correct media Player type from the prioritized Player list
|
||||||
"""
|
"""
|
||||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
usedPlayers, overriddenPlayer = get_media_players()
|
||||||
QtCore.QVariant(u'webkit')).toString())
|
if overriddenPlayer and overriddenPlayer != u'auto':
|
||||||
usedPlayers = playerSettings.split(u',')
|
usedPlayers = [overriddenPlayer]
|
||||||
if QtCore.QSettings().value(u'media/override player',
|
|
||||||
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
|
||||||
if self.overridenPlayer != '':
|
|
||||||
usedPlayers = [self.overridenPlayer]
|
|
||||||
if controller.media_info.file_info.isFile():
|
if controller.media_info.file_info.isFile():
|
||||||
suffix = u'*.%s' % \
|
suffix = u'*.%s' % \
|
||||||
controller.media_info.file_info.suffix().toLower()
|
controller.media_info.file_info.suffix().toLower()
|
||||||
@ -443,6 +443,7 @@ class MediaController(object):
|
|||||||
display.frame.evaluateJavaScript(u'show_blank("black");')
|
display.frame.evaluateJavaScript(u'show_blank("black");')
|
||||||
self.curDisplayMediaPlayer[display].stop(display)
|
self.curDisplayMediaPlayer[display].stop(display)
|
||||||
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
||||||
|
controller.seekSlider.setSliderPosition(0)
|
||||||
|
|
||||||
def video_volume(self, msg):
|
def video_volume(self, msg):
|
||||||
"""
|
"""
|
||||||
@ -478,6 +479,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 +488,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):
|
||||||
"""
|
"""
|
||||||
@ -569,15 +570,6 @@ class MediaController(object):
|
|||||||
video_list.append(item)
|
video_list.append(item)
|
||||||
return video_list
|
return video_list
|
||||||
|
|
||||||
def override_player(self, override_player):
|
|
||||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
|
||||||
QtCore.QVariant(u'webkit')).toString())
|
|
||||||
usedPlayers = playerSettings.split(u',')
|
|
||||||
if override_player in usedPlayers:
|
|
||||||
self.overridenPlayer = override_player
|
|
||||||
else:
|
|
||||||
self.overridenPlayer = ''
|
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
for controller in self.controller:
|
for controller in self.controller:
|
||||||
|
@ -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']}
|
||||||
|
|
||||||
|
|
||||||
@ -62,6 +63,8 @@ class PhononPlayer(MediaPlayer):
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
MediaPlayer.__init__(self, parent, u'phonon')
|
MediaPlayer.__init__(self, parent, u'phonon')
|
||||||
|
self.original_name = u'Phonon'
|
||||||
|
self.display_name = u'&Phonon'
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.additional_extensions = ADDITIONAL_EXT
|
self.additional_extensions = ADDITIONAL_EXT
|
||||||
mimetypes.init()
|
mimetypes.init()
|
||||||
@ -189,6 +192,9 @@ class PhononPlayer(MediaPlayer):
|
|||||||
display.phononWidget.setVisible(status)
|
display.phononWidget.setVisible(status)
|
||||||
|
|
||||||
def update_ui(self, display):
|
def update_ui(self, display):
|
||||||
|
if display.mediaObject.state() == Phonon.PausedState and \
|
||||||
|
self.state != MediaState.Paused:
|
||||||
|
self.stop(display)
|
||||||
controller = display.controller
|
controller = display.controller
|
||||||
if controller.media_info.end_time > 0:
|
if controller.media_info.end_time > 0:
|
||||||
if display.mediaObject.currentTime() > \
|
if display.mediaObject.currentTime() > \
|
||||||
|
5649
openlp/core/ui/media/vlc.py
Normal file
5649
openlp/core/ui/media/vlc.py
Normal file
File diff suppressed because it is too large
Load Diff
224
openlp/core/ui/media/vlcplayer.py
Normal file
224
openlp/core/ui/media/vlcplayer.py
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
# -*- 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 VLC
|
||||||
|
display.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
MediaPlayer.__init__(self, parent, u'vlc')
|
||||||
|
self.original_name = u'VLC'
|
||||||
|
self.display_name = 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):
|
||||||
|
if display.vlcMedia.get_state() == vlc.State.Ended:
|
||||||
|
self.stop(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())
|
||||||
|
|
@ -134,6 +134,8 @@ VIDEO_JS = u"""
|
|||||||
// doesnt work currently
|
// doesnt work currently
|
||||||
vid.currentTime = varVal;
|
vid.currentTime = varVal;
|
||||||
break;
|
break;
|
||||||
|
case 'isEnded':
|
||||||
|
return vid.ended;
|
||||||
case 'setVisible':
|
case 'setVisible':
|
||||||
vid.style.visibility = varVal;
|
vid.style.visibility = varVal;
|
||||||
break;
|
break;
|
||||||
@ -211,6 +213,8 @@ FLASH_JS = u"""
|
|||||||
case 'seek':
|
case 'seek':
|
||||||
// flashMovie.GotoFrame(varVal);
|
// flashMovie.GotoFrame(varVal);
|
||||||
break;
|
break;
|
||||||
|
case 'isEnded':
|
||||||
|
return false;//TODO check flash end
|
||||||
case 'setVisible':
|
case 'setVisible':
|
||||||
text.style.visibility = varVal;
|
text.style.visibility = varVal;
|
||||||
break;
|
break;
|
||||||
@ -260,6 +264,8 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
MediaPlayer.__init__(self, parent, u'webkit')
|
MediaPlayer.__init__(self, parent, u'webkit')
|
||||||
|
self.original_name = u'WebKit'
|
||||||
|
self.display_name = u'&WebKit'
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.canBackground = True
|
self.canBackground = True
|
||||||
self.audio_extensions_list = AUDIO_EXT
|
self.audio_extensions_list = AUDIO_EXT
|
||||||
@ -294,7 +300,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:
|
||||||
@ -354,7 +360,6 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
||||||
else:
|
else:
|
||||||
display.frame.evaluateJavaScript(u'show_video("stop");')
|
display.frame.evaluateJavaScript(u'show_video("stop");')
|
||||||
controller.seekSlider.setSliderPosition(0)
|
|
||||||
self.state = MediaState.Stopped
|
self.state = MediaState.Stopped
|
||||||
|
|
||||||
def volume(self, display, vol):
|
def volume(self, display, vol):
|
||||||
@ -406,6 +411,9 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
length = display.frame.evaluateJavaScript( \
|
length = display.frame.evaluateJavaScript( \
|
||||||
u'show_flash("length");').toInt()[0]
|
u'show_flash("length");').toInt()[0]
|
||||||
else:
|
else:
|
||||||
|
if display.frame.evaluateJavaScript( \
|
||||||
|
u'show_video("isEnded");').toString() == 'true':
|
||||||
|
self.stop(display)
|
||||||
(currentTime, ok) = display.frame.evaluateJavaScript( \
|
(currentTime, ok) = display.frame.evaluateJavaScript( \
|
||||||
u'show_video("currentTime");').toFloat()
|
u'show_video("currentTime");').toFloat()
|
||||||
# check if conversion was ok and value is not 'NaN'
|
# check if conversion was ok and value is not 'NaN'
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -405,7 +405,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
# Only continue when we include the song's text.
|
# Only continue when we include the song's text.
|
||||||
if not self.slideTextCheckBox.isChecked():
|
if not self.slideTextCheckBox.isChecked():
|
||||||
return
|
return
|
||||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
for item in self.serviceManager.serviceItems:
|
||||||
# Trigger Audit requests
|
# Trigger Audit requests
|
||||||
Receiver.send_message(u'print_service_started',
|
Receiver.send_message(u'print_service_started',
|
||||||
[item[u'service_item']])
|
[item[u'service_item']])
|
||||||
|
@ -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.
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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__)
|
||||||
|
|
||||||
@ -40,11 +41,10 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
|
|||||||
ItemCapabilities, SettingsManager, translate, str_to_bool
|
ItemCapabilities, SettingsManager, translate, str_to_bool
|
||||||
from openlp.core.lib.theme import ThemeLevel
|
from openlp.core.lib.theme import ThemeLevel
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
||||||
context_menu_action, context_menu_separator, find_and_set_in_combo_box
|
create_widget_action, 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):
|
||||||
@ -117,22 +117,23 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.layout.setMargin(0)
|
self.layout.setMargin(0)
|
||||||
# Create the top toolbar
|
# Create the top toolbar
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarAction(u'newService',
|
||||||
UiStrings().NewService, u':/general/general_new.png',
|
text=UiStrings().NewService, icon=u':/general/general_new.png',
|
||||||
UiStrings().CreateService, self.onNewServiceClicked)
|
tooltip=UiStrings().CreateService,
|
||||||
self.toolbar.addToolbarButton(
|
triggers=self.onNewServiceClicked)
|
||||||
UiStrings().OpenService, u':/general/general_open.png',
|
self.toolbar.addToolbarAction(u'openService',
|
||||||
translate('OpenLP.ServiceManager', 'Load an existing service.'),
|
text=UiStrings().OpenService, icon=u':/general/general_open.png',
|
||||||
self.onLoadServiceClicked)
|
tooltip=translate('OpenLP.ServiceManager',
|
||||||
self.toolbar.addToolbarButton(
|
'Load an existing service.'), triggers=self.onLoadServiceClicked)
|
||||||
UiStrings().SaveService, u':/general/general_save.png',
|
self.toolbar.addToolbarAction(u'saveService',
|
||||||
translate('OpenLP.ServiceManager', 'Save this service.'),
|
text=UiStrings().SaveService, icon=u':/general/general_save.png',
|
||||||
self.saveFile)
|
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||||
|
triggers=self.saveFile)
|
||||||
self.toolbar.addSeparator()
|
self.toolbar.addSeparator()
|
||||||
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
|
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
|
||||||
self.themeLabel.setMargin(3)
|
self.themeLabel.setMargin(3)
|
||||||
self.themeLabel.setObjectName(u'themeLabel')
|
self.themeLabel.setObjectName(u'themeLabel')
|
||||||
self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
|
self.toolbar.addToolbarWidget(self.themeLabel)
|
||||||
self.themeComboBox = QtGui.QComboBox(self.toolbar)
|
self.themeComboBox = QtGui.QComboBox(self.toolbar)
|
||||||
self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
|
self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
|
||||||
'Select a theme for the service.'))
|
'Select a theme for the service.'))
|
||||||
@ -141,7 +142,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.themeComboBox.setSizePolicy(
|
self.themeComboBox.setSizePolicy(
|
||||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||||
self.themeComboBox.setObjectName(u'themeComboBox')
|
self.themeComboBox.setObjectName(u'themeComboBox')
|
||||||
self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
|
self.toolbar.addToolbarWidget(self.themeComboBox)
|
||||||
self.toolbar.setObjectName(u'toolbar')
|
self.toolbar.setObjectName(u'toolbar')
|
||||||
self.layout.addWidget(self.toolbar)
|
self.layout.addWidget(self.toolbar)
|
||||||
# Create the service manager list
|
# Create the service manager list
|
||||||
@ -168,99 +169,77 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.layout.addWidget(self.serviceManagerList)
|
self.layout.addWidget(self.serviceManagerList)
|
||||||
# Add the bottom toolbar
|
# Add the bottom toolbar
|
||||||
self.orderToolbar = OpenLPToolbar(self)
|
self.orderToolbar = OpenLPToolbar(self)
|
||||||
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarButton(
|
|
||||||
translate('OpenLP.ServiceManager', 'Move to &top'),
|
|
||||||
u':/services/service_top.png',
|
|
||||||
translate('OpenLP.ServiceManager',
|
|
||||||
'Move item to the top of the service.'),
|
|
||||||
self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
|
|
||||||
self.serviceManagerList.moveTop.setObjectName(u'moveTop')
|
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(
|
action_list.add_category(
|
||||||
unicode(UiStrings().Service), CategoryOrder.standardToolbar)
|
unicode(UiStrings().Service), CategoryOrder.standardToolbar)
|
||||||
action_list.add_action(
|
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(
|
||||||
self.serviceManagerList.moveTop, unicode(UiStrings().Service))
|
u'moveTop', text=translate('OpenLP.ServiceManager', 'Move to &top'),
|
||||||
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
|
icon=u':/services/service_top.png', tooltip=translate(
|
||||||
translate('OpenLP.ServiceManager', 'Move &up'),
|
'OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
||||||
u':/services/service_up.png',
|
shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service,
|
||||||
translate('OpenLP.ServiceManager',
|
triggers=self.onServiceTop)
|
||||||
|
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarAction(
|
||||||
|
u'moveUp', text=translate('OpenLP.ServiceManager', 'Move &up'),
|
||||||
|
icon=u':/services/service_up.png',
|
||||||
|
tooltip=translate( 'OpenLP.ServiceManager',
|
||||||
'Move item up one position in the service.'),
|
'Move item up one position in the service.'),
|
||||||
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
|
shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service,
|
||||||
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
|
triggers=self.onServiceUp)
|
||||||
action_list.add_action(
|
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarAction(
|
||||||
self.serviceManagerList.moveUp, unicode(UiStrings().Service))
|
u'moveDown', text=translate('OpenLP.ServiceManager', 'Move &down'),
|
||||||
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
|
icon=u':/services/service_down.png',
|
||||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
tooltip=translate('OpenLP.ServiceManager',
|
||||||
u':/services/service_down.png',
|
|
||||||
translate('OpenLP.ServiceManager',
|
|
||||||
'Move item down one position in the service.'),
|
'Move item down one position in the service.'),
|
||||||
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
|
shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service,
|
||||||
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
|
triggers=self.onServiceDown)
|
||||||
action_list.add_action(
|
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarAction(
|
||||||
self.serviceManagerList.moveDown, unicode(UiStrings().Service))
|
u'moveBottom',
|
||||||
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
|
text=translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
||||||
translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
icon=u':/services/service_bottom.png', tooltip=translate(
|
||||||
u':/services/service_bottom.png',
|
'OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
||||||
translate('OpenLP.ServiceManager',
|
shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service,
|
||||||
'Move item to the end of the service.'),
|
triggers=self.onServiceEnd)
|
||||||
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
|
self.serviceManagerList.down = self.orderToolbar.addToolbarAction(
|
||||||
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
|
u'down', text=translate('OpenLP.ServiceManager', 'Move &down'),
|
||||||
action_list.add_action(
|
tooltip=translate('OpenLP.ServiceManager',
|
||||||
self.serviceManagerList.moveBottom, unicode(UiStrings().Service))
|
'Moves the selection down the window.'), visible=False,
|
||||||
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
|
shortcuts=[QtCore.Qt.Key_Down], triggers=self.onMoveSelectionDown)
|
||||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
|
||||||
None,
|
|
||||||
translate('OpenLP.ServiceManager',
|
|
||||||
'Moves the selection down the window.'),
|
|
||||||
self.onMoveSelectionDown, shortcuts=[QtCore.Qt.Key_Down])
|
|
||||||
self.serviceManagerList.down.setObjectName(u'down')
|
|
||||||
action_list.add_action(self.serviceManagerList.down)
|
action_list.add_action(self.serviceManagerList.down)
|
||||||
self.serviceManagerList.down.setVisible(False)
|
self.serviceManagerList.up = self.orderToolbar.addToolbarAction(
|
||||||
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
|
u'up', text=translate('OpenLP.ServiceManager', 'Move up'),
|
||||||
translate('OpenLP.ServiceManager', 'Move up'),
|
tooltip=translate('OpenLP.ServiceManager',
|
||||||
None,
|
'Moves the selection up the window.'), visible=False,
|
||||||
translate('OpenLP.ServiceManager',
|
shortcuts=[QtCore.Qt.Key_Up], triggers=self.onMoveSelectionUp)
|
||||||
'Moves the selection up the window.'),
|
|
||||||
self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up])
|
|
||||||
self.serviceManagerList.up.setObjectName(u'up')
|
|
||||||
action_list.add_action(self.serviceManagerList.up)
|
action_list.add_action(self.serviceManagerList.up)
|
||||||
self.serviceManagerList.up.setVisible(False)
|
|
||||||
self.orderToolbar.addSeparator()
|
self.orderToolbar.addSeparator()
|
||||||
self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.delete = self.orderToolbar.addToolbarAction(
|
||||||
translate('OpenLP.ServiceManager', '&Delete From Service'),
|
u'delete',
|
||||||
u':/general/general_delete.png',
|
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||||
translate('OpenLP.ServiceManager',
|
icon=u':/general/general_delete.png',
|
||||||
|
tooltip=translate('OpenLP.ServiceManager',
|
||||||
'Delete the selected item from the service.'),
|
'Delete the selected item from the service.'),
|
||||||
self.onDeleteFromService)
|
triggers=self.onDeleteFromService)
|
||||||
self.orderToolbar.addSeparator()
|
self.orderToolbar.addSeparator()
|
||||||
self.serviceManagerList.expand = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.expand = self.orderToolbar.addToolbarAction(
|
||||||
translate('OpenLP.ServiceManager', '&Expand all'),
|
u'expand', text=translate('OpenLP.ServiceManager', '&Expand all'),
|
||||||
u':/services/service_expand_all.png',
|
icon=u':/services/service_expand_all.png', tooltip=translate(
|
||||||
translate('OpenLP.ServiceManager',
|
'OpenLP.ServiceManager', 'Expand all the service items.'),
|
||||||
'Expand all the service items.'),
|
shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service,
|
||||||
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
|
triggers=self.onExpandAll)
|
||||||
self.serviceManagerList.expand.setObjectName(u'expand')
|
self.serviceManagerList.collapse = self.orderToolbar.addToolbarAction(
|
||||||
action_list.add_action(
|
u'collapse',
|
||||||
self.serviceManagerList.expand, unicode(UiStrings().Service))
|
text=translate('OpenLP.ServiceManager', '&Collapse all'),
|
||||||
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
|
icon=u':/services/service_collapse_all.png', tooltip=translate(
|
||||||
translate('OpenLP.ServiceManager', '&Collapse all'),
|
'OpenLP.ServiceManager', 'Collapse all the service items.'),
|
||||||
u':/services/service_collapse_all.png',
|
shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service,
|
||||||
translate('OpenLP.ServiceManager',
|
triggers=self.onCollapseAll)
|
||||||
'Collapse all the service items.'),
|
|
||||||
self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
|
|
||||||
self.serviceManagerList.collapse.setObjectName(u'collapse')
|
|
||||||
action_list.add_action(
|
|
||||||
self.serviceManagerList.collapse, unicode(UiStrings().Service))
|
|
||||||
self.orderToolbar.addSeparator()
|
self.orderToolbar.addSeparator()
|
||||||
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarAction(
|
||||||
translate('OpenLP.ServiceManager', 'Go Live'),
|
u'makeLive', text=translate('OpenLP.ServiceManager', 'Go Live'),
|
||||||
u':/general/general_live.png',
|
icon=u':/general/general_live.png', tooltip=translate(
|
||||||
translate('OpenLP.ServiceManager',
|
'OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
||||||
'Send the selected item to Live.'), self.makeLive,
|
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
||||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
category=UiStrings().Service, triggers=self.makeLive)
|
||||||
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
|
|
||||||
action_list.add_action(
|
|
||||||
self.serviceManagerList.makeLive, unicode(UiStrings().Service))
|
|
||||||
self.layout.addWidget(self.orderToolbar)
|
self.layout.addWidget(self.orderToolbar)
|
||||||
# Connect up our signals and slots
|
# Connect up our signals and slots
|
||||||
QtCore.QObject.connect(self.themeComboBox,
|
QtCore.QObject.connect(self.themeComboBox,
|
||||||
@ -305,34 +284,32 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
|
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||||
# build the context menu
|
# build the context menu
|
||||||
self.menu = QtGui.QMenu()
|
self.menu = QtGui.QMenu()
|
||||||
self.editAction = context_menu_action(
|
self.editAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/general/general_edit.png',
|
text=translate('OpenLP.ServiceManager', '&Edit Item'),
|
||||||
translate('OpenLP.ServiceManager', '&Edit Item'), self.remoteEdit)
|
icon=u':/general/general_edit.png', triggers=self.remoteEdit)
|
||||||
self.maintainAction = context_menu_action(
|
self.maintainAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/general/general_edit.png',
|
text=translate('OpenLP.ServiceManager', '&Reorder Item'),
|
||||||
translate('OpenLP.ServiceManager', '&Reorder Item'),
|
icon=u':/general/general_edit.png',
|
||||||
self.onServiceItemEditForm)
|
triggers=self.onServiceItemEditForm)
|
||||||
self.notesAction = context_menu_action(
|
self.notesAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/services/service_notes.png',
|
text=translate('OpenLP.ServiceManager', '&Notes'),
|
||||||
translate('OpenLP.ServiceManager', '&Notes'),
|
icon=u':/services/service_notes.png',
|
||||||
self.onServiceItemNoteForm)
|
triggers=self.onServiceItemNoteForm)
|
||||||
self.timeAction = context_menu_action(
|
self.timeAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/media/media_time.png',
|
text=translate('OpenLP.ServiceManager', '&Start Time'),
|
||||||
translate('OpenLP.ServiceManager', '&Start Time'),
|
icon=u':/media/media_time.png', triggers=self.onStartTimeForm)
|
||||||
self.onStartTimeForm)
|
self.deleteAction = create_widget_action(self.menu,
|
||||||
self.deleteAction = context_menu_action(
|
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||||
self.menu, u':/general/general_delete.png',
|
icon=u':/general/general_delete.png',
|
||||||
translate('OpenLP.ServiceManager', '&Delete From Service'),
|
triggers=self.onDeleteFromService)
|
||||||
self.onDeleteFromService)
|
self.menu.addSeparator()
|
||||||
context_menu_separator(self.menu)
|
self.previewAction = create_widget_action(self.menu,
|
||||||
self.previewAction = context_menu_action(
|
text=translate('OpenLP.ServiceManager', 'Show &Preview'),
|
||||||
self.menu, u':/general/general_preview.png',
|
icon=u':/general/general_preview.png', triggers=self.makePreview)
|
||||||
translate('OpenLP.ServiceManager', 'Show &Preview'),
|
self.liveAction = create_widget_action(self.menu,
|
||||||
self.makePreview)
|
text=translate('OpenLP.ServiceManager', 'Show &Live'),
|
||||||
self.liveAction = context_menu_action(
|
icon=u':/general/general_live.png', triggers=self.makeLive)
|
||||||
self.menu, u':/general/general_live.png',
|
self.menu.addSeparator()
|
||||||
translate('OpenLP.ServiceManager', 'Show &Live'), self.makeLive)
|
|
||||||
context_menu_separator(self.menu)
|
|
||||||
self.themeMenu = QtGui.QMenu(
|
self.themeMenu = QtGui.QMenu(
|
||||||
translate('OpenLP.ServiceManager', '&Change Item Theme'))
|
translate('OpenLP.ServiceManager', '&Change Item Theme'))
|
||||||
self.menu.addMenu(self.themeMenu)
|
self.menu.addMenu(self.themeMenu)
|
||||||
@ -484,7 +461,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
log.debug(temp_file_name)
|
log.debug(temp_file_name)
|
||||||
path_file_name = unicode(self.fileName())
|
path_file_name = unicode(self.fileName())
|
||||||
path, file_name = os.path.split(path_file_name)
|
path, file_name = os.path.split(path_file_name)
|
||||||
basename, extension = os.path.splitext(file_name)
|
basename = os.path.splitext(file_name)[0]
|
||||||
service_file_name = '%s.osd' % basename
|
service_file_name = '%s.osd' % basename
|
||||||
log.debug(u'ServiceManager.saveFile - %s', path_file_name)
|
log.debug(u'ServiceManager.saveFile - %s', path_file_name)
|
||||||
SettingsManager.set_last_dir(
|
SettingsManager.set_last_dir(
|
||||||
@ -506,8 +483,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
for i, filename in \
|
for i, filename in \
|
||||||
enumerate(service_item[u'header'][u'background_audio']):
|
enumerate(service_item[u'header'][u'background_audio']):
|
||||||
new_file = os.path.join(u'audio',
|
new_file = os.path.join(u'audio',
|
||||||
item[u'service_item']._uuid,
|
item[u'service_item']._uuid, filename)
|
||||||
os.path.split(filename)[1])
|
|
||||||
audio_files.append((filename, new_file))
|
audio_files.append((filename, new_file))
|
||||||
service_item[u'header'][u'background_audio'][i] = new_file
|
service_item[u'header'][u'background_audio'][i] = new_file
|
||||||
# Add the service item to the service.
|
# Add the service item to the service.
|
||||||
@ -596,7 +572,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:
|
||||||
|
try:
|
||||||
shutil.copy(temp_file_name, path_file_name)
|
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 +589,39 @@ 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 may not contain any of the following characters: '
|
||||||
|
'/\\?*|<>\[\]":+\nSee http://docs.python.org/library/'
|
||||||
|
'datetime.html#strftime-strptime-behavior for more '
|
||||||
|
'information.')).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,14 +644,17 @@ 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'
|
||||||
'The content encoding is not UTF-8.'))
|
'The content encoding is not UTF-8.'))
|
||||||
continue
|
continue
|
||||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
osfile = ucsfile.replace(u'/', os.path.sep)
|
||||||
if not osfile.startswith(u'audio'):
|
if not osfile.startswith(u'audio'):
|
||||||
osfile = os.path.split(osfile)[1]
|
osfile = os.path.split(osfile)[1]
|
||||||
log.debug(u'Extract file: %s', osfile)
|
log.debug(u'Extract file: %s', osfile)
|
||||||
@ -821,7 +832,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 +840,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):
|
||||||
@ -1092,12 +1114,9 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
sure the theme combo box is in the correct state.
|
sure the theme combo box is in the correct state.
|
||||||
"""
|
"""
|
||||||
log.debug(u'themeChange')
|
log.debug(u'themeChange')
|
||||||
if self.mainwindow.renderer.theme_level == ThemeLevel.Global:
|
visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global
|
||||||
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
|
self.themeLabel.setVisible(visible)
|
||||||
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
|
self.themeComboBox.setVisible(visible)
|
||||||
else:
|
|
||||||
self.toolbar.actions[u'ThemeLabel'].setVisible(True)
|
|
||||||
self.toolbar.actions[u'ThemeWidget'].setVisible(True)
|
|
||||||
|
|
||||||
def regenerateServiceItems(self):
|
def regenerateServiceItems(self):
|
||||||
"""
|
"""
|
||||||
@ -1334,15 +1353,15 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
Handle of the event pint passed
|
Handle of the event pint passed
|
||||||
"""
|
"""
|
||||||
link = event.mimeData()
|
link = event.mimeData()
|
||||||
if event.mimeData().hasUrls():
|
if link.hasUrls():
|
||||||
event.setDropAction(QtCore.Qt.CopyAction)
|
event.setDropAction(QtCore.Qt.CopyAction)
|
||||||
event.accept()
|
event.accept()
|
||||||
for url in event.mimeData().urls():
|
for url in link.urls():
|
||||||
filename = unicode(url.toLocalFile())
|
filename = unicode(url.toLocalFile())
|
||||||
if filename.endswith(u'.osz'):
|
if filename.endswith(u'.osz'):
|
||||||
self.onLoadServiceClicked(filename)
|
self.onLoadServiceClicked(filename)
|
||||||
elif event.mimeData().hasText():
|
elif link.hasText():
|
||||||
plugin = unicode(event.mimeData().text())
|
plugin = unicode(link.text())
|
||||||
item = self.serviceManagerList.itemAt(event.pos())
|
item = self.serviceManagerList.itemAt(event.pos())
|
||||||
# ServiceManager started the drag and drop
|
# ServiceManager started the drag and drop
|
||||||
if plugin == u'ServiceManager':
|
if plugin == u'ServiceManager':
|
||||||
@ -1399,19 +1418,16 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
themeGroup.setObjectName(u'themeGroup')
|
themeGroup.setObjectName(u'themeGroup')
|
||||||
# Create a "Default" theme, which allows the user to reset the item's
|
# Create a "Default" theme, which allows the user to reset the item's
|
||||||
# theme to the service theme or global theme.
|
# theme to the service theme or global theme.
|
||||||
defaultTheme = context_menu_action(self.themeMenu, None,
|
defaultTheme = create_widget_action(self.themeMenu,
|
||||||
UiStrings().Default, self.onThemeChangeAction)
|
text=UiStrings().Default, checked=False,
|
||||||
defaultTheme.setCheckable(True)
|
triggers=self.onThemeChangeAction)
|
||||||
self.themeMenu.setDefaultAction(defaultTheme)
|
self.themeMenu.setDefaultAction(defaultTheme)
|
||||||
themeGroup.addAction(defaultTheme)
|
themeGroup.addAction(defaultTheme)
|
||||||
context_menu_separator(self.themeMenu)
|
self.themeMenu.addSeparator()
|
||||||
for theme in theme_list:
|
for theme in theme_list:
|
||||||
self.themeComboBox.addItem(theme)
|
self.themeComboBox.addItem(theme)
|
||||||
themeAction = context_menu_action(self.themeMenu, None, theme,
|
themeGroup.addAction(create_widget_action(self.themeMenu, theme,
|
||||||
self.onThemeChangeAction)
|
text=theme, checked=False, triggers=self.onThemeChangeAction))
|
||||||
themeAction.setObjectName(theme)
|
|
||||||
themeAction.setCheckable(True)
|
|
||||||
themeGroup.addAction(themeAction)
|
|
||||||
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
|
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
|
||||||
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||||
self.regenerateServiceItems()
|
self.regenerateServiceItems()
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
@ -57,7 +57,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
def exec_(self):
|
def exec_(self):
|
||||||
# load all the settings
|
# load all the settings
|
||||||
self.settingListWidget.clear()
|
self.settingListWidget.clear()
|
||||||
for tabIndex in range(0, self.stackedLayout.count() + 1):
|
while self.stackedLayout.count():
|
||||||
# take at 0 and the rest shuffle up.
|
# take at 0 and the rest shuffle up.
|
||||||
self.stackedLayout.takeAt(0)
|
self.stackedLayout.takeAt(0)
|
||||||
self.insertTab(self.generalTab, 0, PluginStatus.Active)
|
self.insertTab(self.generalTab, 0, PluginStatus.Active)
|
||||||
|
@ -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, #
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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, create_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,26 +84,29 @@ class SlideController(Controller):
|
|||||||
"""
|
"""
|
||||||
Controller.__init__(self, parent, isLive)
|
Controller.__init__(self, parent, isLive)
|
||||||
self.screens = ScreenList.get_instance()
|
self.screens = ScreenList.get_instance()
|
||||||
|
try:
|
||||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||||
float(self.screens.current[u'size'].height())
|
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 = [
|
||||||
u'Play Slides Menu',
|
u'playSlidesMenu',
|
||||||
u'Loop Separator',
|
u'loopSeparator',
|
||||||
u'Image SpinBox'
|
u'delaySpinBox'
|
||||||
]
|
]
|
||||||
self.songEditList = [
|
self.audioList = [
|
||||||
u'Edit Song',
|
u'songMenu',
|
||||||
]
|
u'audioPauseItem',
|
||||||
self.nextPreviousList = [
|
u'audioTimeLabel'
|
||||||
u'Previous 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
|
||||||
@ -116,10 +121,14 @@ class SlideController(Controller):
|
|||||||
self.typePrefix = u'live'
|
self.typePrefix = u'live'
|
||||||
self.keypress_queue = deque()
|
self.keypress_queue = deque()
|
||||||
self.keypress_loop = False
|
self.keypress_loop = False
|
||||||
|
self.category = UiStrings().LiveToolbar
|
||||||
|
ActionList.get_instance().add_category(
|
||||||
|
unicode(self.category), CategoryOrder.standardToolbar)
|
||||||
else:
|
else:
|
||||||
self.typeLabel.setText(UiStrings().Preview)
|
self.typeLabel.setText(UiStrings().Preview)
|
||||||
self.split = 0
|
self.split = 0
|
||||||
self.typePrefix = u'preview'
|
self.typePrefix = u'preview'
|
||||||
|
self.category = None
|
||||||
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
||||||
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
|
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
self.panelLayout.addWidget(self.typeLabel)
|
self.panelLayout.addWidget(self.typeLabel)
|
||||||
@ -162,72 +171,71 @@ class SlideController(Controller):
|
|||||||
sizeToolbarPolicy.setHeightForWidth(
|
sizeToolbarPolicy.setHeightForWidth(
|
||||||
self.toolbar.sizePolicy().hasHeightForWidth())
|
self.toolbar.sizePolicy().hasHeightForWidth())
|
||||||
self.toolbar.setSizePolicy(sizeToolbarPolicy)
|
self.toolbar.setSizePolicy(sizeToolbarPolicy)
|
||||||
self.previousItem = self.toolbar.addToolbarButton(
|
self.previousItem = create_action(self,
|
||||||
u'Previous Slide',
|
u'previousItem_' + self.typePrefix,
|
||||||
u':/slides/slide_previous.png',
|
text=translate('OpenLP.SlideController', 'Previous Slide'),
|
||||||
translate('OpenLP.SlideController', 'Move to previous.'),
|
icon=u':/slides/slide_previous.png',
|
||||||
self.onSlideSelectedPrevious,
|
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
|
shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
self.nextItem = self.toolbar.addToolbarButton(
|
category=self.category, triggers=self.onSlideSelectedPrevious)
|
||||||
u'Next Slide',
|
self.toolbar.addAction(self.previousItem)
|
||||||
u':/slides/slide_next.png',
|
self.nextItem = create_action(self, u'nextItem_' + self.typePrefix,
|
||||||
translate('OpenLP.SlideController', 'Move to next.'),
|
text=translate('OpenLP.SlideController', 'Next Slide'),
|
||||||
self.onSlideSelectedNext,
|
icon=u':/slides/slide_next.png',
|
||||||
|
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
|
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
category=self.category, triggers=self.onSlideSelectedNextAction)
|
||||||
|
self.toolbar.addAction(self.nextItem)
|
||||||
|
self.toolbar.addSeparator()
|
||||||
if self.isLive:
|
if self.isLive:
|
||||||
# Hide Menu
|
# Hide Menu
|
||||||
self.hideMenu = QtGui.QToolButton(self.toolbar)
|
self.hideMenu = QtGui.QToolButton(self.toolbar)
|
||||||
|
self.hideMenu.setObjectName(u'hideMenu')
|
||||||
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
|
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
|
||||||
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
||||||
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
|
|
||||||
self.hideMenu.setMenu(QtGui.QMenu(
|
self.hideMenu.setMenu(QtGui.QMenu(
|
||||||
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
||||||
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
|
self.toolbar.addToolbarWidget(self.hideMenu)
|
||||||
[QtCore.Qt.Key_Period], self.onBlankDisplay,
|
self.blankScreen = create_action(self, u'blankScreen',
|
||||||
u':/slides/slide_blank.png', False,
|
text=translate('OpenLP.SlideController', 'Blank Screen'),
|
||||||
unicode(UiStrings().LiveToolbar))
|
icon=u':/slides/slide_blank.png', checked=False,
|
||||||
self.blankScreen.setText(
|
shortcuts=[QtCore.Qt.Key_Period],
|
||||||
translate('OpenLP.SlideController', 'Blank Screen'))
|
category=self.category, triggers=self.onBlankDisplay)
|
||||||
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
|
self.themeScreen = create_action(self, u'themeScreen',
|
||||||
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
|
text=translate('OpenLP.SlideController', 'Blank to Theme'),
|
||||||
u':/slides/slide_theme.png', False,
|
icon=u':/slides/slide_theme.png', checked=False,
|
||||||
unicode(UiStrings().LiveToolbar))
|
shortcuts=[QtGui.QKeySequence(u'T')],
|
||||||
self.themeScreen.setText(
|
category=self.category, triggers=self.onThemeDisplay)
|
||||||
translate('OpenLP.SlideController', 'Blank to Theme'))
|
self.desktopScreen = create_action(self, u'desktopScreen',
|
||||||
self.desktopScreen = shortcut_action(self.hideMenu,
|
text=translate('OpenLP.SlideController', 'Show Desktop'),
|
||||||
u'desktopScreen', [QtGui.QKeySequence(u'D')],
|
icon=u':/slides/slide_desktop.png', checked=False,
|
||||||
self.onHideDisplay, u':/slides/slide_desktop.png', False,
|
shortcuts=[QtGui.QKeySequence(u'D')],
|
||||||
unicode(UiStrings().LiveToolbar))
|
category=self.category, triggers=self.onHideDisplay)
|
||||||
self.desktopScreen.setText(
|
|
||||||
translate('OpenLP.SlideController', 'Show Desktop'))
|
|
||||||
self.hideMenu.setDefaultAction(self.blankScreen)
|
self.hideMenu.setDefaultAction(self.blankScreen)
|
||||||
self.hideMenu.menu().addAction(self.blankScreen)
|
self.hideMenu.menu().addAction(self.blankScreen)
|
||||||
self.hideMenu.menu().addAction(self.themeScreen)
|
self.hideMenu.menu().addAction(self.themeScreen)
|
||||||
self.hideMenu.menu().addAction(self.desktopScreen)
|
self.hideMenu.menu().addAction(self.desktopScreen)
|
||||||
self.toolbar.addToolbarSeparator(u'Loop Separator')
|
self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
|
||||||
# Play Slides Menu
|
# Play Slides Menu
|
||||||
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
|
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
|
||||||
|
self.playSlidesMenu.setObjectName(u'playSlidesMenu')
|
||||||
self.playSlidesMenu.setText(translate('OpenLP.SlideController',
|
self.playSlidesMenu.setText(translate('OpenLP.SlideController',
|
||||||
'Play Slides'))
|
'Play Slides'))
|
||||||
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
||||||
self.toolbar.addToolbarWidget(u'Play Slides Menu',
|
|
||||||
self.playSlidesMenu)
|
|
||||||
self.playSlidesMenu.setMenu(QtGui.QMenu(
|
self.playSlidesMenu.setMenu(QtGui.QMenu(
|
||||||
translate('OpenLP.SlideController', 'Play Slides'),
|
translate('OpenLP.SlideController', 'Play Slides'),
|
||||||
self.toolbar))
|
self.toolbar))
|
||||||
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
|
self.toolbar.addToolbarWidget(self.playSlidesMenu)
|
||||||
u'playSlidesLoop', [], self.onPlaySlidesLoop,
|
self.playSlidesLoop = create_action(self, u'playSlidesLoop',
|
||||||
u':/media/media_time.png', False,
|
text=UiStrings().PlaySlidesInLoop,
|
||||||
unicode(UiStrings().LiveToolbar))
|
icon=u':/media/media_time.png', checked=False, shortcuts=[],
|
||||||
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
|
category=self.category, triggers=self.onPlaySlidesLoop)
|
||||||
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
|
self.playSlidesOnce = create_action(self, u'playSlidesOnce',
|
||||||
u'playSlidesOnce', [], self.onPlaySlidesOnce,
|
text=UiStrings().PlaySlidesToEnd,
|
||||||
u':/media/media_time.png', False,
|
icon=u':/media/media_time.png', checked=False, shortcuts=[],
|
||||||
unicode(UiStrings().LiveToolbar))
|
category=self.category, triggers=self.onPlaySlidesOnce)
|
||||||
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
|
|
||||||
if QtCore.QSettings().value(self.parent().generalSettingsSection +
|
if QtCore.QSettings().value(self.parent().generalSettingsSection +
|
||||||
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||||
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
|
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
|
||||||
@ -237,47 +245,75 @@ class SlideController(Controller):
|
|||||||
self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
|
self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
|
||||||
# Loop Delay Spinbox
|
# Loop Delay Spinbox
|
||||||
self.delaySpinBox = QtGui.QSpinBox()
|
self.delaySpinBox = QtGui.QSpinBox()
|
||||||
|
self.delaySpinBox.setObjectName(u'delaySpinBox')
|
||||||
self.delaySpinBox.setRange(1, 180)
|
self.delaySpinBox.setRange(1, 180)
|
||||||
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
|
|
||||||
self.delaySpinBox.setSuffix(UiStrings().Seconds)
|
self.delaySpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
||||||
'Delay between slides in seconds.'))
|
'Delay between slides in seconds.'))
|
||||||
|
self.toolbar.addToolbarWidget(self.delaySpinBox)
|
||||||
else:
|
else:
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarAction(u'goLive',
|
||||||
# Does not need translating - control string.
|
icon=u':/general/general_live.png',
|
||||||
u'Go Live', u':/general/general_live.png',
|
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
|
||||||
translate('OpenLP.SlideController', 'Move to live.'),
|
triggers=self.onGoLive)
|
||||||
self.onGoLive)
|
self.toolbar.addToolbarAction(u'addToService',
|
||||||
self.toolbar.addToolbarButton(
|
icon=u':/general/general_add.png',
|
||||||
# Does not need translating - control string.
|
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
|
||||||
u'Add to Service', u':/general/general_add.png',
|
triggers=self.onPreviewAddToService)
|
||||||
translate('OpenLP.SlideController', 'Add to Service.'),
|
self.toolbar.addSeparator()
|
||||||
self.onPreviewAddToService)
|
self.toolbar.addToolbarAction(u'editSong',
|
||||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
icon=u':/general/general_edit.png',
|
||||||
self.toolbar.addToolbarButton(
|
tooltip=translate('OpenLP.SlideController',
|
||||||
# Does not need translating - control string.
|
'Edit and reload song preview.'), triggers=self.onEditSong)
|
||||||
u'Edit Song', u':/general/general_edit.png',
|
|
||||||
translate('OpenLP.SlideController',
|
|
||||||
'Edit and reload song preview.'),
|
|
||||||
self.onEditSong)
|
|
||||||
self.controllerLayout.addWidget(self.toolbar)
|
self.controllerLayout.addWidget(self.toolbar)
|
||||||
# Build the Media Toolbar
|
# Build the Media Toolbar
|
||||||
self.mediaController.add_controller_items(self, self.controllerLayout)
|
self.mediaController.add_controller_items(self, self.controllerLayout)
|
||||||
if self.isLive:
|
if self.isLive:
|
||||||
# Build the Song Toolbar
|
# Build the Song Toolbar
|
||||||
self.songMenu = QtGui.QToolButton(self.toolbar)
|
self.songMenu = QtGui.QToolButton(self.toolbar)
|
||||||
|
self.songMenu.setObjectName(u'songMenu')
|
||||||
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
|
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
|
||||||
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
|
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
|
||||||
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'])
|
self.toolbar.addToolbarWidget(self.songMenu)
|
||||||
# Stuff for items with background audio.
|
# Stuff for items with background audio.
|
||||||
self.audioPauseItem = self.toolbar.addToolbarButton(
|
self.audioPauseItem = self.toolbar.addToolbarAction(
|
||||||
u'Pause Audio', u':/slides/media_playback_pause.png',
|
u'audioPauseItem', icon=u':/slides/media_playback_pause.png',
|
||||||
translate('OpenLP.SlideController', 'Pause audio.'),
|
text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||||
self.onAudioPauseClicked, True)
|
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||||
self.audioPauseItem.setVisible(False)
|
checked=False, visible=False, category=self.category,
|
||||||
|
triggers=self.onAudioPauseClicked)
|
||||||
|
self.audioMenu = QtGui.QMenu(
|
||||||
|
translate('OpenLP.SlideController', 'Background Audio'), self)
|
||||||
|
self.audioPauseItem.setMenu(self.audioMenu)
|
||||||
|
self.audioPauseItem.setParent(self)
|
||||||
|
self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
|
||||||
|
QtGui.QToolButton.MenuButtonPopup)
|
||||||
|
self.nextTrackItem = create_action(self, u'nextTrackItem',
|
||||||
|
text=translate('OpenLP.SlideController', 'Next Track'),
|
||||||
|
icon=u':/slides/media_playback_next.png', tooltip=translate(
|
||||||
|
'OpenLP.SlideController', 'Go to next audio track.'),
|
||||||
|
category=self.category, context=QtCore.Qt.WindowShortcut,
|
||||||
|
triggers=self.onNextTrackClicked)
|
||||||
|
self.audioMenu.addAction(self.nextTrackItem)
|
||||||
|
self.trackMenu = self.audioMenu.addMenu(
|
||||||
|
translate('OpenLP.SlideController', 'Tracks'))
|
||||||
|
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(self.audioTimeLabel)
|
||||||
|
self.toolbar.setWidgetVisible(self.audioList, False)
|
||||||
# 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))
|
||||||
@ -322,89 +358,31 @@ class SlideController(Controller):
|
|||||||
self.shortcutTimer = QtCore.QTimer()
|
self.shortcutTimer = QtCore.QTimer()
|
||||||
self.shortcutTimer.setObjectName(u'shortcutTimer')
|
self.shortcutTimer.setObjectName(u'shortcutTimer')
|
||||||
self.shortcutTimer.setSingleShot(True)
|
self.shortcutTimer.setSingleShot(True)
|
||||||
self.verseShortcut = shortcut_action(self, u'verseShortcut',
|
shortcuts = [{u'key': u'V', u'configurable': True,
|
||||||
[QtGui.QKeySequence(u'V')], self.slideShortcutActivated,
|
u'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
{u'key': u'C', u'configurable': True,
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
|
||||||
self.verseShortcut.setText(translate(
|
{u'key': u'B', u'configurable': True,
|
||||||
'OpenLP.SlideController', 'Go to "Verse"'))
|
u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
|
||||||
self.shortcut0 = shortcut_action(self, u'0',
|
{u'key': u'P', u'configurable': True,
|
||||||
[QtGui.QKeySequence(u'0')], self.slideShortcutActivated,
|
u'text': translate('OpenLP.SlideController',
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
'Go to "Pre-Chorus"')},
|
||||||
self.shortcut1 = shortcut_action(self, u'1',
|
{u'key': u'I', u'configurable': True,
|
||||||
[QtGui.QKeySequence(u'1')], self.slideShortcutActivated,
|
u'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
{u'key': u'E', u'configurable': True,
|
||||||
self.shortcut2 = shortcut_action(self, u'2',
|
u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
|
||||||
[QtGui.QKeySequence(u'2')], self.slideShortcutActivated,
|
{u'key': u'O', u'configurable': True,
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
|
||||||
self.shortcut3 = shortcut_action(self, u'3',
|
shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
|
||||||
[QtGui.QKeySequence(u'3')], self.slideShortcutActivated,
|
self.previewListWidget.addActions([create_action(self,
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
|
||||||
self.shortcut4 = shortcut_action(self, u'4',
|
shortcuts=[QtGui.QKeySequence(s[u'key'])],
|
||||||
[QtGui.QKeySequence(u'4')], self.slideShortcutActivated,
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
category=self.category if s.get(u'configurable') else None,
|
||||||
self.shortcut5 = shortcut_action(self, u'5',
|
triggers=self._slideShortcutActivated) for s in shortcuts])
|
||||||
[QtGui.QKeySequence(u'5')], self.slideShortcutActivated,
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.shortcut6 = shortcut_action(self, u'6',
|
|
||||||
[QtGui.QKeySequence(u'6')], self.slideShortcutActivated,
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.shortcut7 = shortcut_action(self, u'7',
|
|
||||||
[QtGui.QKeySequence(u'7')], self.slideShortcutActivated,
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.shortcut8 = shortcut_action(self, u'8',
|
|
||||||
[QtGui.QKeySequence(u'8')], self.slideShortcutActivated,
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.shortcut9 = shortcut_action(self, u'9',
|
|
||||||
[QtGui.QKeySequence(u'9')], self.slideShortcutActivated,
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.chorusShortcut = shortcut_action(self, u'chorusShortcut',
|
|
||||||
[QtGui.QKeySequence(u'C')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.chorusShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Chorus"'))
|
|
||||||
self.bridgeShortcut = shortcut_action(self, u'bridgeShortcut',
|
|
||||||
[QtGui.QKeySequence(u'B')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.bridgeShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Bridge"'))
|
|
||||||
self.preChorusShortcut = shortcut_action(self, u'preChorusShortcut',
|
|
||||||
[QtGui.QKeySequence(u'P')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.preChorusShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Pre-Chorus"'))
|
|
||||||
self.introShortcut = shortcut_action(self, u'introShortcut',
|
|
||||||
[QtGui.QKeySequence(u'I')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.introShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Intro"'))
|
|
||||||
self.endingShortcut = shortcut_action(self, u'endingShortcut',
|
|
||||||
[QtGui.QKeySequence(u'E')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.endingShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Ending"'))
|
|
||||||
self.otherShortcut = shortcut_action(self, u'otherShortcut',
|
|
||||||
[QtGui.QKeySequence(u'O')], self.slideShortcutActivated,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.otherShortcut.setText(translate(
|
|
||||||
'OpenLP.SlideController', 'Go to "Other"'))
|
|
||||||
self.previewListWidget.addActions([
|
|
||||||
self.shortcut0, self.shortcut1, self.shortcut2, self.shortcut3,
|
|
||||||
self.shortcut4, self.shortcut5, self.shortcut6, self.shortcut7,
|
|
||||||
self.shortcut8, self.shortcut9, self.verseShortcut,
|
|
||||||
self.chorusShortcut, self.bridgeShortcut,
|
|
||||||
self.preChorusShortcut, self.introShortcut, self.endingShortcut,
|
|
||||||
self.otherShortcut
|
|
||||||
])
|
|
||||||
QtCore.QObject.connect(
|
QtCore.QObject.connect(
|
||||||
self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
|
self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
|
||||||
self.slideShortcutActivated)
|
self._slideShortcutActivated)
|
||||||
# Signals
|
# Signals
|
||||||
QtCore.QObject.connect(self.previewListWidget,
|
QtCore.QObject.connect(self.previewListWidget,
|
||||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
||||||
@ -412,20 +390,21 @@ 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)
|
||||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'slidecontroller_toggle_display'),
|
||||||
|
self.toggleDisplay)
|
||||||
|
self.toolbar.setWidgetVisible(self.loopList, False)
|
||||||
else:
|
else:
|
||||||
QtCore.QObject.connect(self.previewListWidget,
|
QtCore.QObject.connect(self.previewListWidget,
|
||||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||||
self.onGoLiveClick)
|
self.onGoLiveClick)
|
||||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
self.toolbar.setWidgetVisible([u'editSong'], False)
|
||||||
if self.isLive:
|
if self.isLive:
|
||||||
self.setLiveHotkeys(self)
|
self.setLiveHotkeys(self)
|
||||||
self.__addActionsToWidget(self.previewListWidget)
|
self.__addActionsToWidget(self.previewListWidget)
|
||||||
else:
|
else:
|
||||||
self.setPreviewHotkeys()
|
|
||||||
self.previewListWidget.addActions(
|
self.previewListWidget.addActions(
|
||||||
[self.nextItem,
|
[self.nextItem, self.previousItem])
|
||||||
self.previousItem])
|
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
|
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
|
||||||
self.onStopLoop)
|
self.onStopLoop)
|
||||||
@ -447,8 +426,11 @@ 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):
|
||||||
"""
|
"""
|
||||||
Called, when a shortcut has been activated to jump to a chorus, verse,
|
Called, when a shortcut has been activated to jump to a chorus, verse,
|
||||||
etc.
|
etc.
|
||||||
@ -464,52 +446,38 @@ class SlideController(Controller):
|
|||||||
SONGS_PLUGIN_AVAILABLE = True
|
SONGS_PLUGIN_AVAILABLE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
SONGS_PLUGIN_AVAILABLE = False
|
SONGS_PLUGIN_AVAILABLE = False
|
||||||
verse_type = unicode(self.sender().objectName())
|
sender_name = unicode(self.sender().objectName())
|
||||||
if verse_type.startswith(u'verseShortcut'):
|
verse_type = sender_name[15:] \
|
||||||
|
if sender_name[:15] == u'shortcutAction_' else u''
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
if SONGS_PLUGIN_AVAILABLE:
|
||||||
|
if verse_type == u'V':
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Verse]
|
VerseType.TranslatedTags[VerseType.Verse]
|
||||||
else:
|
elif verse_type == u'C':
|
||||||
self.current_shortcut = u'V'
|
|
||||||
elif verse_type.startswith(u'chorusShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Chorus]
|
VerseType.TranslatedTags[VerseType.Chorus]
|
||||||
else:
|
elif verse_type == u'B':
|
||||||
self.current_shortcut = u'C'
|
|
||||||
elif verse_type.startswith(u'bridgeShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Bridge]
|
VerseType.TranslatedTags[VerseType.Bridge]
|
||||||
else:
|
elif verse_type == u'P':
|
||||||
self.current_shortcut = u'B'
|
|
||||||
elif verse_type.startswith(u'preChorusShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.PreChorus]
|
VerseType.TranslatedTags[VerseType.PreChorus]
|
||||||
else:
|
elif verse_type == u'I':
|
||||||
self.current_shortcut = u'P'
|
|
||||||
elif verse_type.startswith(u'introShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Intro]
|
VerseType.TranslatedTags[VerseType.Intro]
|
||||||
else:
|
elif verse_type == u'E':
|
||||||
self.current_shortcut = u'I'
|
|
||||||
elif verse_type.startswith(u'endingShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Ending]
|
VerseType.TranslatedTags[VerseType.Ending]
|
||||||
else:
|
elif verse_type == u'O':
|
||||||
self.current_shortcut = u'E'
|
|
||||||
elif verse_type.startswith(u'otherShortcut'):
|
|
||||||
if SONGS_PLUGIN_AVAILABLE:
|
|
||||||
self.current_shortcut = \
|
self.current_shortcut = \
|
||||||
VerseType.TranslatedTags[VerseType.Other]
|
VerseType.TranslatedTags[VerseType.Other]
|
||||||
else:
|
|
||||||
self.current_shortcut = u'O'
|
|
||||||
elif verse_type.isnumeric():
|
elif verse_type.isnumeric():
|
||||||
self.current_shortcut += verse_type
|
self.current_shortcut += verse_type
|
||||||
self.current_shortcut = self.current_shortcut.upper()
|
self.current_shortcut = self.current_shortcut.upper()
|
||||||
|
elif verse_type.isnumeric():
|
||||||
|
self.current_shortcut += verse_type
|
||||||
|
elif verse_type:
|
||||||
|
self.current_shortcut = verse_type
|
||||||
keys = self.slideList.keys()
|
keys = self.slideList.keys()
|
||||||
matches = [match for match in keys
|
matches = [match for match in keys
|
||||||
if match.startswith(self.current_shortcut)]
|
if match.startswith(self.current_shortcut)]
|
||||||
@ -518,7 +486,7 @@ class SlideController(Controller):
|
|||||||
self.current_shortcut = u''
|
self.current_shortcut = u''
|
||||||
self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
|
self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
|
||||||
self.slideSelected()
|
self.slideSelected()
|
||||||
elif verse_type != u'shortcutTimer':
|
elif sender_name != u'shortcutTimer':
|
||||||
# Start the time as we did not have any match.
|
# Start the time as we did not have any match.
|
||||||
self.shortcutTimer.start(350)
|
self.shortcutTimer.start(350)
|
||||||
else:
|
else:
|
||||||
@ -532,56 +500,54 @@ class SlideController(Controller):
|
|||||||
# Reset the shortcut.
|
# Reset the shortcut.
|
||||||
self.current_shortcut = u''
|
self.current_shortcut = u''
|
||||||
|
|
||||||
def setPreviewHotkeys(self, parent=None):
|
|
||||||
self.previousItem.setObjectName(u'previousItemPreview')
|
|
||||||
self.nextItem.setObjectName(u'nextItemPreview')
|
|
||||||
action_list = ActionList.get_instance()
|
|
||||||
action_list.add_action(self.previousItem)
|
|
||||||
action_list.add_action(self.nextItem)
|
|
||||||
|
|
||||||
def setLiveHotkeys(self, parent=None):
|
def setLiveHotkeys(self, parent=None):
|
||||||
self.previousItem.setObjectName(u'previousItemLive')
|
self.previousService = create_action(parent, u'previousService',
|
||||||
self.nextItem.setObjectName(u'nextItemLive')
|
text=translate('OpenLP.SlideController', 'Previous Service'),
|
||||||
action_list = ActionList.get_instance()
|
shortcuts=[QtCore.Qt.Key_Left],
|
||||||
action_list.add_category(
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar)
|
category=self.category, triggers=self.servicePrevious)
|
||||||
action_list.add_action(self.previousItem)
|
self.nextService = create_action(parent, 'nextService',
|
||||||
action_list.add_action(self.nextItem)
|
text=translate('OpenLP.SlideController', 'Next Service'),
|
||||||
self.previousService = shortcut_action(parent, u'previousService',
|
shortcuts=[QtCore.Qt.Key_Right],
|
||||||
[QtCore.Qt.Key_Left], self.servicePrevious,
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
category=self.category, triggers=self.serviceNext)
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
self.escapeItem = create_action(parent, 'escapeItem',
|
||||||
self.previousService.setText(
|
text=translate('OpenLP.SlideController', 'Escape Item'),
|
||||||
translate('OpenLP.SlideController', 'Previous Service'))
|
shortcuts=[QtCore.Qt.Key_Escape],
|
||||||
self.nextService = shortcut_action(parent, 'nextService',
|
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||||
[QtCore.Qt.Key_Right], self.serviceNext,
|
category=self.category, triggers=self.liveEscape)
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.nextService.setText(
|
|
||||||
translate('OpenLP.SlideController', 'Next Service'))
|
|
||||||
self.escapeItem = shortcut_action(parent, 'escapeItem',
|
|
||||||
[QtCore.Qt.Key_Escape], self.liveEscape,
|
|
||||||
category=unicode(UiStrings().LiveToolbar),
|
|
||||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
|
||||||
self.escapeItem.setText(
|
|
||||||
translate('OpenLP.SlideController', 'Escape Item'))
|
|
||||||
|
|
||||||
def liveEscape(self):
|
def liveEscape(self):
|
||||||
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 +558,13 @@ 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 +582,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.
|
||||||
|
try:
|
||||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||||
float(self.screens.current[u'size'].height())
|
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 +658,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
|
||||||
@ -699,9 +683,9 @@ class SlideController(Controller):
|
|||||||
# Work-around for OS X, hide and then show the toolbar
|
# Work-around for OS X, hide and then show the toolbar
|
||||||
# See bug #791050
|
# See bug #791050
|
||||||
self.toolbar.hide()
|
self.toolbar.hide()
|
||||||
self.mediabar.setVisible(False)
|
self.mediabar.hide()
|
||||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
self.songMenu.hide()
|
||||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
self.toolbar.setWidgetVisible(self.loopList, False)
|
||||||
# Reset the button
|
# Reset the button
|
||||||
self.playSlidesOnce.setChecked(False)
|
self.playSlidesOnce.setChecked(False)
|
||||||
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
|
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
@ -711,17 +695,16 @@ class SlideController(Controller):
|
|||||||
if QtCore.QSettings().value(
|
if QtCore.QSettings().value(
|
||||||
self.parent().songsSettingsSection + u'/display songbar',
|
self.parent().songsSettingsSection + u'/display songbar',
|
||||||
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
|
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
|
||||||
self.toolbar.makeWidgetsVisible([u'Song Menu'])
|
self.songMenu.show()
|
||||||
if item.is_capable(ItemCapabilities.CanLoop) and \
|
if item.is_capable(ItemCapabilities.CanLoop) and \
|
||||||
len(item.get_frames()) > 1:
|
len(item.get_frames()) > 1:
|
||||||
self.toolbar.makeWidgetsVisible(self.loopList)
|
self.toolbar.setWidgetVisible(self.loopList)
|
||||||
if item.is_media():
|
if item.is_media():
|
||||||
self.mediabar.setVisible(True)
|
self.mediabar.show()
|
||||||
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
|
self.previousItem.setVisible(not item.is_media())
|
||||||
else:
|
self.nextItem.setVisible(not item.is_media())
|
||||||
# Work-around for OS X, hide and then show the toolbar
|
# Work-around for OS X, hide and then show the toolbar
|
||||||
# See bug #791050
|
# See bug #791050
|
||||||
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
|
|
||||||
self.toolbar.show()
|
self.toolbar.show()
|
||||||
|
|
||||||
def enablePreviewToolBar(self, item):
|
def enablePreviewToolBar(self, item):
|
||||||
@ -731,17 +714,16 @@ class SlideController(Controller):
|
|||||||
# Work-around for OS X, hide and then show the toolbar
|
# Work-around for OS X, hide and then show the toolbar
|
||||||
# See bug #791050
|
# See bug #791050
|
||||||
self.toolbar.hide()
|
self.toolbar.hide()
|
||||||
self.mediabar.setVisible(False)
|
self.mediabar.hide()
|
||||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
self.toolbar.setWidgetVisible([u'editSong'], False)
|
||||||
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
|
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
|
||||||
self.toolbar.makeWidgetsVisible(self.songEditList)
|
self.toolbar.setWidgetVisible([u'editSong'])
|
||||||
elif item.is_media():
|
elif item.is_media():
|
||||||
self.mediabar.setVisible(True)
|
self.mediabar.show()
|
||||||
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
|
self.previousItem.setVisible(not item.is_media())
|
||||||
if not item.is_media():
|
self.nextItem.setVisible(not item.is_media())
|
||||||
# Work-around for OS X, hide and then show the toolbar
|
# Work-around for OS X, hide and then show the toolbar
|
||||||
# See bug #791050
|
# See bug #791050
|
||||||
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
|
|
||||||
self.toolbar.show()
|
self.toolbar.show()
|
||||||
|
|
||||||
def refreshServiceItem(self):
|
def refreshServiceItem(self):
|
||||||
@ -818,10 +800,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 +868,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 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 +933,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 +945,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 +1070,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
|
||||||
"""
|
"""
|
||||||
@ -1087,7 +1083,7 @@ class SlideController(Controller):
|
|||||||
"""
|
"""
|
||||||
row = self.previewListWidget.currentRow()
|
row = self.previewListWidget.currentRow()
|
||||||
self.selectedRow = 0
|
self.selectedRow = 0
|
||||||
if row > -1 and row < self.previewListWidget.rowCount():
|
if -1 < row < self.previewListWidget.rowCount():
|
||||||
if self.serviceItem.is_command():
|
if self.serviceItem.is_command():
|
||||||
if self.isLive and not start:
|
if self.isLive and not start:
|
||||||
Receiver.send_message(
|
Receiver.send_message(
|
||||||
@ -1144,6 +1140,13 @@ class SlideController(Controller):
|
|||||||
rect.y(), rect.width(), rect.height())
|
rect.y(), rect.width(), rect.height())
|
||||||
self.slidePreview.setPixmap(winimg)
|
self.slidePreview.setPixmap(winimg)
|
||||||
|
|
||||||
|
def onSlideSelectedNextAction(self, checked):
|
||||||
|
"""
|
||||||
|
Wrapper function from create_action so we can throw away the
|
||||||
|
incorrect parameter
|
||||||
|
"""
|
||||||
|
self.onSlideSelectedNext()
|
||||||
|
|
||||||
def onSlideSelectedNext(self, wrap=None):
|
def onSlideSelectedNext(self, wrap=None):
|
||||||
"""
|
"""
|
||||||
Go to the next slide.
|
Go to the next slide.
|
||||||
@ -1158,10 +1161,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 +1188,13 @@ 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)
|
||||||
@ -1216,7 +1227,7 @@ class SlideController(Controller):
|
|||||||
"""
|
"""
|
||||||
Stop the timer loop running
|
Stop the timer loop running
|
||||||
"""
|
"""
|
||||||
if self.timer_id != 0:
|
if self.timer_id:
|
||||||
self.killTimer(self.timer_id)
|
self.killTimer(self.timer_id)
|
||||||
self.timer_id = 0
|
self.timer_id = 0
|
||||||
|
|
||||||
@ -1263,7 +1274,7 @@ class SlideController(Controller):
|
|||||||
self.onToggleLoop()
|
self.onToggleLoop()
|
||||||
|
|
||||||
def setAudioItemsVisibility(self, visible):
|
def setAudioItemsVisibility(self, visible):
|
||||||
self.audioPauseItem.setVisible(visible)
|
self.toolbar.setWidgetVisible(self.audioList, visible)
|
||||||
|
|
||||||
def onAudioPauseClicked(self, checked):
|
def onAudioPauseClicked(self, checked):
|
||||||
if not self.audioPauseItem.isVisible():
|
if not self.audioPauseItem.isVisible():
|
||||||
@ -1317,7 +1328,7 @@ class SlideController(Controller):
|
|||||||
If preview copy slide item to live
|
If preview copy slide item to live
|
||||||
"""
|
"""
|
||||||
row = self.previewListWidget.currentRow()
|
row = self.previewListWidget.currentRow()
|
||||||
if row > -1 and row < self.previewListWidget.rowCount():
|
if -1 < row < self.previewListWidget.rowCount():
|
||||||
if self.serviceItem.from_service:
|
if self.serviceItem.from_service:
|
||||||
Receiver.send_message('servicemanager_preview_live',
|
Receiver.send_message('servicemanager_preview_live',
|
||||||
u'%s:%s' % (self.serviceItem._uuid, row))
|
u'%s:%s' % (self.serviceItem._uuid, row))
|
||||||
@ -1374,3 +1385,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)
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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))
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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
|
||||||
@ -40,11 +41,10 @@ from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \
|
|||||||
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
|
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
|
||||||
BackgroundGradientType
|
BackgroundGradientType
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
||||||
context_menu_action, context_menu_separator
|
create_widget_action
|
||||||
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__)
|
||||||
|
|
||||||
@ -64,32 +64,32 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.layout.setMargin(0)
|
self.layout.setMargin(0)
|
||||||
self.layout.setObjectName(u'layout')
|
self.layout.setObjectName(u'layout')
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(UiStrings().NewTheme,
|
|
||||||
u':/themes/theme_new.png',
|
|
||||||
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
|
||||||
self.onAddTheme)
|
|
||||||
self.toolbar.addToolbarButton(
|
|
||||||
translate('OpenLP.ThemeManager', 'Edit Theme'),
|
|
||||||
u':/themes/theme_edit.png',
|
|
||||||
translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
|
||||||
self.onEditTheme)
|
|
||||||
self.deleteToolbarAction = self.toolbar.addToolbarButton(
|
|
||||||
translate('OpenLP.ThemeManager', 'Delete Theme'),
|
|
||||||
u':/general/general_delete.png',
|
|
||||||
translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
|
||||||
self.onDeleteTheme)
|
|
||||||
self.toolbar.addSeparator()
|
|
||||||
self.toolbar.addToolbarButton(
|
|
||||||
translate('OpenLP.ThemeManager', 'Import Theme'),
|
|
||||||
u':/general/general_import.png',
|
|
||||||
translate('OpenLP.ThemeManager', 'Import a theme.'),
|
|
||||||
self.onImportTheme)
|
|
||||||
self.toolbar.addToolbarButton(
|
|
||||||
translate('OpenLP.ThemeManager', 'Export Theme'),
|
|
||||||
u':/general/general_export.png',
|
|
||||||
translate('OpenLP.ThemeManager', 'Export a theme.'),
|
|
||||||
self.onExportTheme)
|
|
||||||
self.toolbar.setObjectName(u'toolbar')
|
self.toolbar.setObjectName(u'toolbar')
|
||||||
|
self.toolbar.addToolbarAction(u'newTheme',
|
||||||
|
text=UiStrings().NewTheme, icon=u':/themes/theme_new.png',
|
||||||
|
tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
||||||
|
triggers=self.onAddTheme)
|
||||||
|
self.toolbar.addToolbarAction(u'editTheme',
|
||||||
|
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
|
||||||
|
icon=u':/themes/theme_edit.png',
|
||||||
|
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
||||||
|
triggers=self.onEditTheme)
|
||||||
|
self.deleteToolbarAction = self.toolbar.addToolbarAction(u'deleteTheme',
|
||||||
|
text=translate('OpenLP.ThemeManager', 'Delete Theme'),
|
||||||
|
icon=u':/general/general_delete.png',
|
||||||
|
tooltip=translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
||||||
|
triggers=self.onDeleteTheme)
|
||||||
|
self.toolbar.addSeparator()
|
||||||
|
self.toolbar.addToolbarAction(u'importTheme',
|
||||||
|
text=translate('OpenLP.ThemeManager', 'Import Theme'),
|
||||||
|
icon=u':/general/general_import.png',
|
||||||
|
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
|
||||||
|
triggers=self.onImportTheme)
|
||||||
|
self.toolbar.addToolbarAction(u'exportTheme',
|
||||||
|
text=translate('OpenLP.ThemeManager', 'Export Theme'),
|
||||||
|
icon=u':/general/general_export.png',
|
||||||
|
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
|
||||||
|
triggers=self.onExportTheme)
|
||||||
self.layout.addWidget(self.toolbar)
|
self.layout.addWidget(self.toolbar)
|
||||||
self.themeWidget = QtGui.QWidgetAction(self.toolbar)
|
self.themeWidget = QtGui.QWidgetAction(self.toolbar)
|
||||||
self.themeWidget.setObjectName(u'themeWidget')
|
self.themeWidget.setObjectName(u'themeWidget')
|
||||||
@ -105,29 +105,26 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.contextMenu)
|
self.contextMenu)
|
||||||
# build the context menu
|
# build the context menu
|
||||||
self.menu = QtGui.QMenu()
|
self.menu = QtGui.QMenu()
|
||||||
self.editAction = context_menu_action(
|
self.editAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/themes/theme_edit.png',
|
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
|
||||||
translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme)
|
icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
|
||||||
self.copyAction = context_menu_action(
|
self.copyAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/themes/theme_edit.png',
|
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
|
||||||
translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme)
|
icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
|
||||||
self.renameAction = context_menu_action(
|
self.renameAction = create_widget_action(self.menu,
|
||||||
self.menu, u':/themes/theme_edit.png',
|
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
|
||||||
translate('OpenLP.ThemeManager', '&Rename Theme'),
|
icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
|
||||||
self.onRenameTheme)
|
self.deleteAction = create_widget_action(self.menu,
|
||||||
self.deleteAction = context_menu_action(
|
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
|
||||||
self.menu, u':/general/general_delete.png',
|
icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
|
||||||
translate('OpenLP.ThemeManager', '&Delete Theme'),
|
self.menu.addSeparator()
|
||||||
self.onDeleteTheme)
|
self.globalAction = create_widget_action(self.menu,
|
||||||
context_menu_separator(self.menu)
|
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
||||||
self.globalAction = context_menu_action(
|
icon=u':/general/general_export.png',
|
||||||
self.menu, u':/general/general_export.png',
|
triggers=self.changeGlobalFromScreen)
|
||||||
translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
self.exportAction = create_widget_action(self.menu,
|
||||||
self.changeGlobalFromScreen)
|
text=translate('OpenLP.ThemeManager', '&Export Theme'),
|
||||||
self.exportAction = context_menu_action(
|
icon=u':/general/general_export.png', triggers=self.onExportTheme)
|
||||||
self.menu, u':/general/general_export.png',
|
|
||||||
translate('OpenLP.ThemeManager', '&Export Theme'),
|
|
||||||
self.onExportTheme)
|
|
||||||
# Signals
|
# Signals
|
||||||
QtCore.QObject.connect(self.themeListWidget,
|
QtCore.QObject.connect(self.themeListWidget,
|
||||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||||
@ -140,13 +137,14 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
|
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
|
||||||
# Variables
|
# Variables
|
||||||
self.themelist = []
|
self.theme_list = []
|
||||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||||
check_directory_exists(self.path)
|
check_directory_exists(self.path)
|
||||||
self.thumbPath = os.path.join(self.path, u'thumbnails')
|
self.thumb_path = os.path.join(self.path, u'thumbnails')
|
||||||
check_directory_exists(self.thumbPath)
|
check_directory_exists(self.thumb_path)
|
||||||
self.themeForm.path = self.path
|
self.themeForm.path = self.path
|
||||||
self.oldBackgroundImage = None
|
self.old_background_image = 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()
|
||||||
|
|
||||||
@ -155,10 +153,9 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
Import new themes downloaded by the first time wizard
|
Import new themes downloaded by the first time wizard
|
||||||
"""
|
"""
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
encoding = get_filesystem_encoding()
|
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
||||||
for file in files:
|
for file in files:
|
||||||
file = os.path.join(self.path, file).encode(encoding)
|
file = os.path.join(self.path, file)
|
||||||
self.unzipTheme(file, self.path)
|
self.unzipTheme(file, self.path)
|
||||||
delete_file(file)
|
delete_file(file)
|
||||||
Receiver.send_message(u'cursor_normal')
|
Receiver.send_message(u'cursor_normal')
|
||||||
@ -177,10 +174,10 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
if item is None:
|
if item is None:
|
||||||
return
|
return
|
||||||
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
themeName = unicode(item.text())
|
theme_name = unicode(item.text())
|
||||||
# If default theme restrict actions
|
# If default theme restrict actions
|
||||||
if realThemeName == themeName:
|
if real_theme_name == theme_name:
|
||||||
self.deleteToolbarAction.setVisible(True)
|
self.deleteToolbarAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
self.deleteToolbarAction.setVisible(False)
|
self.deleteToolbarAction.setVisible(False)
|
||||||
@ -193,35 +190,35 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
item = self.themeListWidget.itemAt(point)
|
item = self.themeListWidget.itemAt(point)
|
||||||
if item is None:
|
if item is None:
|
||||||
return
|
return
|
||||||
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
themeName = unicode(item.text())
|
theme_name = unicode(item.text())
|
||||||
self.deleteAction.setVisible(False)
|
self.deleteAction.setVisible(False)
|
||||||
self.renameAction.setVisible(False)
|
self.renameAction.setVisible(False)
|
||||||
self.globalAction.setVisible(False)
|
self.globalAction.setVisible(False)
|
||||||
# If default theme restrict actions
|
# If default theme restrict actions
|
||||||
if realThemeName == themeName:
|
if real_theme_name == theme_name:
|
||||||
self.deleteAction.setVisible(True)
|
self.deleteAction.setVisible(True)
|
||||||
self.renameAction.setVisible(True)
|
self.renameAction.setVisible(True)
|
||||||
self.globalAction.setVisible(True)
|
self.globalAction.setVisible(True)
|
||||||
self.menu.exec_(self.themeListWidget.mapToGlobal(point))
|
self.menu.exec_(self.themeListWidget.mapToGlobal(point))
|
||||||
|
|
||||||
def changeGlobalFromTab(self, themeName):
|
def changeGlobalFromTab(self, theme_name):
|
||||||
"""
|
"""
|
||||||
Change the global theme when it is changed through the Themes settings
|
Change the global theme when it is changed through the Themes settings
|
||||||
tab
|
tab
|
||||||
"""
|
"""
|
||||||
log.debug(u'changeGlobalFromTab %s', themeName)
|
log.debug(u'changeGlobalFromTab %s', theme_name)
|
||||||
for count in range (0, self.themeListWidget.count()):
|
for count in range (0, self.themeListWidget.count()):
|
||||||
# reset the old name
|
# reset the old name
|
||||||
item = self.themeListWidget.item(count)
|
item = self.themeListWidget.item(count)
|
||||||
oldName = item.text()
|
old_name = item.text()
|
||||||
newName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
new_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
if oldName != newName:
|
if old_name != new_name:
|
||||||
self.themeListWidget.item(count).setText(newName)
|
self.themeListWidget.item(count).setText(new_name)
|
||||||
# Set the new name
|
# Set the new name
|
||||||
if themeName == newName:
|
if theme_name == new_name:
|
||||||
name = unicode(translate('OpenLP.ThemeManager',
|
name = unicode(translate('OpenLP.ThemeManager',
|
||||||
'%s (default)')) % newName
|
'%s (default)')) % new_name
|
||||||
self.themeListWidget.item(count).setText(name)
|
self.themeListWidget.item(count).setText(name)
|
||||||
|
|
||||||
def changeGlobalFromScreen(self, index=-1):
|
def changeGlobalFromScreen(self, index=-1):
|
||||||
@ -233,9 +230,9 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
selected_row = self.themeListWidget.currentRow()
|
selected_row = self.themeListWidget.currentRow()
|
||||||
for count in range (0, self.themeListWidget.count()):
|
for count in range (0, self.themeListWidget.count()):
|
||||||
item = self.themeListWidget.item(count)
|
item = self.themeListWidget.item(count)
|
||||||
oldName = item.text()
|
old_name = item.text()
|
||||||
# reset the old name
|
# reset the old name
|
||||||
if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
|
if old_name != unicode(item.data(QtCore.Qt.UserRole).toString()):
|
||||||
self.themeListWidget.item(count).setText(
|
self.themeListWidget.item(count).setText(
|
||||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||||
# Set the new name
|
# Set the new name
|
||||||
@ -271,19 +268,19 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
|
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
|
||||||
False, False):
|
False, False):
|
||||||
item = self.themeListWidget.currentItem()
|
item = self.themeListWidget.currentItem()
|
||||||
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
|
self.fileRenameForm.fileNameEdit.setText(old_theme_name)
|
||||||
if self.fileRenameForm.exec_():
|
if self.fileRenameForm.exec_():
|
||||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||||
if oldThemeName == newThemeName:
|
if old_theme_name == new_theme_name:
|
||||||
return
|
return
|
||||||
if self.checkIfThemeExists(newThemeName):
|
if self.checkIfThemeExists(new_theme_name):
|
||||||
oldThemeData = self.getThemeData(oldThemeName)
|
old_theme_data = self.getThemeData(old_theme_name)
|
||||||
self.cloneThemeData(oldThemeData, newThemeName)
|
self.cloneThemeData(old_theme_data, new_theme_name)
|
||||||
self.deleteTheme(oldThemeName)
|
self.deleteTheme(old_theme_name)
|
||||||
for plugin in self.mainwindow.pluginManager.plugins:
|
for plugin in self.mainwindow.pluginManager.plugins:
|
||||||
if plugin.usesTheme(oldThemeName):
|
if plugin.usesTheme(old_theme_name):
|
||||||
plugin.renameTheme(oldThemeName, newThemeName)
|
plugin.renameTheme(old_theme_name, new_theme_name)
|
||||||
self.loadThemes()
|
self.loadThemes()
|
||||||
|
|
||||||
def onCopyTheme(self):
|
def onCopyTheme(self):
|
||||||
@ -291,30 +288,30 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
Copies an existing theme to a new name
|
Copies an existing theme to a new name
|
||||||
"""
|
"""
|
||||||
item = self.themeListWidget.currentItem()
|
item = self.themeListWidget.currentItem()
|
||||||
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
self.fileRenameForm.fileNameEdit.setText(
|
self.fileRenameForm.fileNameEdit.setText(
|
||||||
unicode(translate('OpenLP.ThemeManager',
|
unicode(translate('OpenLP.ThemeManager',
|
||||||
'Copy of %s','Copy of <theme name>')) % oldThemeName)
|
'Copy of %s', 'Copy of <theme name>')) % old_theme_name)
|
||||||
if self.fileRenameForm.exec_(True):
|
if self.fileRenameForm.exec_(True):
|
||||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||||
if self.checkIfThemeExists(newThemeName):
|
if self.checkIfThemeExists(new_theme_name):
|
||||||
themeData = self.getThemeData(oldThemeName)
|
theme_data = self.getThemeData(old_theme_name)
|
||||||
self.cloneThemeData(themeData, newThemeName)
|
self.cloneThemeData(theme_data, new_theme_name)
|
||||||
|
|
||||||
def cloneThemeData(self, themeData, newThemeName):
|
def cloneThemeData(self, theme_data, new_theme_name):
|
||||||
"""
|
"""
|
||||||
Takes a theme and makes a new copy of it as well as saving it.
|
Takes a theme and makes a new copy of it as well as saving it.
|
||||||
"""
|
"""
|
||||||
log.debug(u'cloneThemeData')
|
log.debug(u'cloneThemeData')
|
||||||
saveTo = None
|
save_to = None
|
||||||
saveFrom = None
|
save_from = None
|
||||||
if themeData.background_type == u'image':
|
if theme_data.background_type == u'image':
|
||||||
saveTo = os.path.join(self.path, newThemeName,
|
save_to = os.path.join(self.path, new_theme_name,
|
||||||
os.path.split(unicode(themeData.background_filename))[1])
|
os.path.split(unicode(theme_data.background_filename))[1])
|
||||||
saveFrom = themeData.background_filename
|
save_from = theme_data.background_filename
|
||||||
themeData.theme_name = newThemeName
|
theme_data.theme_name = new_theme_name
|
||||||
themeData.extend_image_filename(self.path)
|
theme_data.extend_image_filename(self.path)
|
||||||
self.saveTheme(themeData, saveFrom, saveTo)
|
self.saveTheme(theme_data, save_from, save_to)
|
||||||
|
|
||||||
def onEditTheme(self):
|
def onEditTheme(self):
|
||||||
"""
|
"""
|
||||||
@ -328,10 +325,10 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
theme = self.getThemeData(
|
theme = self.getThemeData(
|
||||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||||
if theme.background_type == u'image':
|
if theme.background_type == u'image':
|
||||||
self.oldBackgroundImage = theme.background_filename
|
self.old_background_image = theme.background_filename
|
||||||
self.themeForm.theme = theme
|
self.themeForm.theme = theme
|
||||||
self.themeForm.exec_(True)
|
self.themeForm.exec_(True)
|
||||||
self.oldBackgroundImage = None
|
self.old_background_image = None
|
||||||
|
|
||||||
def onDeleteTheme(self):
|
def onDeleteTheme(self):
|
||||||
"""
|
"""
|
||||||
@ -357,10 +354,10 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
``theme``
|
``theme``
|
||||||
The theme to delete.
|
The theme to delete.
|
||||||
"""
|
"""
|
||||||
self.themelist.remove(theme)
|
self.theme_list.remove(theme)
|
||||||
thumb = u'%s.png' % theme
|
thumb = u'%s.png' % theme
|
||||||
delete_file(os.path.join(self.path, thumb))
|
delete_file(os.path.join(self.path, thumb))
|
||||||
delete_file(os.path.join(self.thumbPath, thumb))
|
delete_file(os.path.join(self.thumb_path, thumb))
|
||||||
try:
|
try:
|
||||||
encoding = get_filesystem_encoding()
|
encoding = get_filesystem_encoding()
|
||||||
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
||||||
@ -385,10 +382,10 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
if path:
|
if path:
|
||||||
SettingsManager.set_last_dir(self.settingsSection, path, 1)
|
SettingsManager.set_last_dir(self.settingsSection, path, 1)
|
||||||
themePath = os.path.join(path, theme + u'.otz')
|
theme_path = os.path.join(path, theme + u'.otz')
|
||||||
zip = None
|
zip = None
|
||||||
try:
|
try:
|
||||||
zip = zipfile.ZipFile(themePath, u'w')
|
zip = zipfile.ZipFile(theme_path, u'w')
|
||||||
source = os.path.join(self.path, theme)
|
source = os.path.join(self.path, theme)
|
||||||
for files in os.walk(source):
|
for files in os.walk(source):
|
||||||
for name in files[2]:
|
for name in files[2]:
|
||||||
@ -438,9 +435,8 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
The plugins will call back in to get the real list if they want it.
|
The plugins will call back in to get the real list if they want it.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Load themes from dir')
|
log.debug(u'Load themes from dir')
|
||||||
self.themelist = []
|
self.theme_list = []
|
||||||
self.themeListWidget.clear()
|
self.themeListWidget.clear()
|
||||||
dirList = os.listdir(self.path)
|
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||||
if firstTime:
|
if firstTime:
|
||||||
self.firstTime()
|
self.firstTime()
|
||||||
@ -457,29 +453,29 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||||
# Sort the themes by its name considering language specific characters.
|
# Sort the themes by its name considering language specific characters.
|
||||||
# lower() is needed for windows!
|
# lower() is needed for windows!
|
||||||
files.sort(key=lambda filename: unicode(filename).lower(),
|
files.sort(key=lambda file_name: unicode(file_name).lower(),
|
||||||
cmp=locale.strcoll)
|
cmp=locale.strcoll)
|
||||||
# now process the file list of png files
|
# now process the file list of png files
|
||||||
for name in files:
|
for name in files:
|
||||||
# check to see file is in theme root directory
|
# check to see file is in theme root directory
|
||||||
theme = os.path.join(self.path, name)
|
theme = os.path.join(self.path, name)
|
||||||
if os.path.exists(theme):
|
if os.path.exists(theme):
|
||||||
textName = os.path.splitext(name)[0]
|
text_name = os.path.splitext(name)[0]
|
||||||
if textName == self.global_theme:
|
if text_name == self.global_theme:
|
||||||
name = unicode(translate('OpenLP.ThemeManager',
|
name = unicode(translate('OpenLP.ThemeManager',
|
||||||
'%s (default)')) % textName
|
'%s (default)')) % text_name
|
||||||
else:
|
else:
|
||||||
name = textName
|
name = text_name
|
||||||
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
|
thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
|
||||||
item_name = QtGui.QListWidgetItem(name)
|
item_name = QtGui.QListWidgetItem(name)
|
||||||
if validate_thumb(theme, thumb):
|
if validate_thumb(theme, thumb):
|
||||||
icon = build_icon(thumb)
|
icon = build_icon(thumb)
|
||||||
else:
|
else:
|
||||||
icon = create_thumb(theme, thumb)
|
icon = create_thumb(theme, thumb)
|
||||||
item_name.setIcon(icon)
|
item_name.setIcon(icon)
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(text_name))
|
||||||
self.themeListWidget.addItem(item_name)
|
self.themeListWidget.addItem(item_name)
|
||||||
self.themelist.append(textName)
|
self.theme_list.append(text_name)
|
||||||
self._pushThemes()
|
self._pushThemes()
|
||||||
|
|
||||||
def _pushThemes(self):
|
def _pushThemes(self):
|
||||||
@ -492,86 +488,111 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
Return the list of loaded themes
|
Return the list of loaded themes
|
||||||
"""
|
"""
|
||||||
return self.themelist
|
return self.theme_list
|
||||||
|
|
||||||
def getThemeData(self, themeName):
|
def getThemeData(self, theme_name):
|
||||||
"""
|
"""
|
||||||
Returns a theme object from an XML file
|
Returns a theme object from an XML file
|
||||||
|
|
||||||
``themeName``
|
``theme_name``
|
||||||
Name of the theme to load from file
|
Name of the theme to load from file
|
||||||
"""
|
"""
|
||||||
log.debug(u'getthemedata for theme %s', themeName)
|
log.debug(u'getthemedata for theme %s', theme_name)
|
||||||
xmlFile = os.path.join(self.path, unicode(themeName),
|
xml_file = os.path.join(self.path, unicode(theme_name),
|
||||||
unicode(themeName) + u'.xml')
|
unicode(theme_name) + u'.xml')
|
||||||
xml = get_text_file_string(xmlFile)
|
xml = get_text_file_string(xml_file)
|
||||||
if not xml:
|
if not xml:
|
||||||
log.debug("No theme data - using default theme")
|
log.debug("No theme data - using default theme")
|
||||||
return ThemeXML()
|
return ThemeXML()
|
||||||
else:
|
else:
|
||||||
return self._createThemeFromXml(xml, self.path)
|
return self._createThemeFromXml(xml, self.path)
|
||||||
|
|
||||||
def unzipTheme(self, filename, dir):
|
def overWriteMessageBox(self, theme_name):
|
||||||
|
ret = QtGui.QMessageBox.question(self,
|
||||||
|
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||||
|
translate('OpenLP.ThemeManager',
|
||||||
|
'Theme %s already exists. Do you want to replace it?'
|
||||||
|
% theme_name),
|
||||||
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||||
|
QtGui.QMessageBox.No),
|
||||||
|
QtGui.QMessageBox.No)
|
||||||
|
return ret == QtGui.QMessageBox.Yes
|
||||||
|
|
||||||
|
def unzipTheme(self, file_name, dir):
|
||||||
"""
|
"""
|
||||||
Unzip the theme, remove the preview file if stored
|
Unzip the theme, remove the preview file if stored
|
||||||
Generate a new preview file. Check the XML theme version and upgrade if
|
Generate a new preview file. Check the XML theme version and upgrade if
|
||||||
necessary.
|
necessary.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Unzipping theme %s', filename)
|
log.debug(u'Unzipping theme %s', file_name)
|
||||||
filename = unicode(filename)
|
file_name = unicode(file_name)
|
||||||
zip = None
|
zip = None
|
||||||
outfile = None
|
out_file = None
|
||||||
filexml = None
|
file_xml = None
|
||||||
try:
|
try:
|
||||||
zip = zipfile.ZipFile(filename)
|
zip = zipfile.ZipFile(file_name)
|
||||||
themename = None
|
xml_file = filter(lambda name:
|
||||||
for file in zip.namelist():
|
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
|
||||||
# Handle UTF-8 files
|
if len(xml_file) != 1:
|
||||||
ucsfile = file_is_unicode(file)
|
log.exception(u'Theme contains "%s" XML files' % len(xml_file))
|
||||||
if not ucsfile:
|
raise Exception(u'validation')
|
||||||
# Handle native Unicode files from Windows
|
xml_tree = ElementTree(element=XML(zip.read(xml_file[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
|
theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
|
||||||
if osfile.endswith(os.path.sep):
|
xml_file[0], xml_tree, v1_background, out_file)
|
||||||
theme_dir = os.path.join(dir, osfile)
|
|
||||||
check_directory_exists(theme_dir)
|
|
||||||
else:
|
else:
|
||||||
fullpath = os.path.join(dir, osfile)
|
theme_name = xml_tree.find(u'name').text.strip()
|
||||||
names = osfile.split(os.path.sep)
|
theme_folder = os.path.join(dir, theme_name)
|
||||||
if len(names) > 1:
|
theme_exists = os.path.exists(theme_folder)
|
||||||
# not preview file
|
if theme_exists and not self.overWriteMessageBox(theme_name):
|
||||||
if themename is None:
|
abort_import = True
|
||||||
themename = names[0]
|
return
|
||||||
if theme_dir is None:
|
|
||||||
theme_dir = os.path.join(dir, names[0])
|
|
||||||
check_directory_exists(theme_dir)
|
|
||||||
if os.path.splitext(ucsfile)[1].lower() in [u'.xml']:
|
|
||||||
xml_data = zip.read(file)
|
|
||||||
xml_data = file_is_unicode(xml_data)
|
|
||||||
if not xml_data:
|
|
||||||
break
|
|
||||||
filexml = self._checkVersionAndConvert(xml_data)
|
|
||||||
outfile = open(fullpath, u'w')
|
|
||||||
outfile.write(filexml.encode(u'utf-8'))
|
|
||||||
else:
|
else:
|
||||||
outfile = open(fullpath, u'wb')
|
abort_import = False
|
||||||
outfile.write(zip.read(file))
|
for name in zip.namelist():
|
||||||
except (IOError, NameError, zipfile.BadZipfile):
|
try:
|
||||||
critical_error_message_box(
|
uname = unicode(name, u'utf-8')
|
||||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
except UnicodeDecodeError:
|
||||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
log.exception(u'Theme file contains non utf-8 filename'
|
||||||
log.exception(u'Importing theme from zip failed %s' % filename)
|
u' "%s"' % name.decode(u'utf-8', u'replace'))
|
||||||
|
raise Exception(u'validation')
|
||||||
|
uname = uname.replace(u'/', os.path.sep)
|
||||||
|
split_name = uname.split(os.path.sep)
|
||||||
|
if split_name[-1] == u'' or len(split_name) == 1:
|
||||||
|
# is directory or preview file
|
||||||
|
continue
|
||||||
|
full_name = os.path.join(dir, uname)
|
||||||
|
check_directory_exists(os.path.dirname(full_name))
|
||||||
|
if os.path.splitext(uname)[1].lower() == u'.xml':
|
||||||
|
file_xml = unicode(zip.read(name), u'utf-8')
|
||||||
|
out_file = open(full_name, u'w')
|
||||||
|
out_file.write(file_xml.encode(u'utf-8'))
|
||||||
|
else:
|
||||||
|
out_file = open(full_name, u'wb')
|
||||||
|
out_file.write(zip.read(name))
|
||||||
|
out_file.close()
|
||||||
|
except (IOError, zipfile.BadZipfile):
|
||||||
|
log.exception(u'Importing theme from zip failed %s' % file_name)
|
||||||
|
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:
|
||||||
zip.close()
|
zip.close()
|
||||||
if outfile:
|
if out_file:
|
||||||
outfile.close()
|
out_file.close()
|
||||||
|
if not abort_import:
|
||||||
# As all files are closed, we can create the Theme.
|
# As all files are closed, we can create the Theme.
|
||||||
if filexml:
|
if file_xml:
|
||||||
theme = self._createThemeFromXml(filexml, self.path)
|
theme = self._createThemeFromXml(file_xml, self.path)
|
||||||
self.generateAndSaveImage(dir, themename, theme)
|
self.generateAndSaveImage(dir, theme_name, theme)
|
||||||
# Only show the error message, when IOError was not raised (in this
|
# Only show the error message, when IOError was not raised (in this
|
||||||
# case the error message has already been shown).
|
# case the error message has already been shown).
|
||||||
elif zip is not None:
|
elif zip is not None:
|
||||||
@ -580,16 +601,50 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager',
|
||||||
'File is not a valid theme.'))
|
'File is not a valid theme.'))
|
||||||
log.exception(u'Theme file does not contain XML data %s' %
|
log.exception(u'Theme file does not contain XML data %s' %
|
||||||
filename)
|
file_name)
|
||||||
|
|
||||||
def checkIfThemeExists(self, themeName):
|
def unzipVersion122(self, dir, zip, xml_file, xml_tree, background, out_file):
|
||||||
|
"""
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
theme_name = xml_tree.find(u'Name').text.strip()
|
||||||
|
theme_name = self.bad_v1_name_chars.sub(u'', theme_name)
|
||||||
|
theme_folder = os.path.join(dir, theme_name)
|
||||||
|
theme_exists = os.path.exists(theme_folder)
|
||||||
|
if theme_exists and not self.overWriteMessageBox(theme_name):
|
||||||
|
return '', '', '', True
|
||||||
|
themedir = os.path.join(dir, theme_name)
|
||||||
|
check_directory_exists(themedir)
|
||||||
|
file_xml = unicode(zip.read(xml_file), u'utf-8')
|
||||||
|
file_xml = self._migrateVersion122(file_xml)
|
||||||
|
out_file = open(os.path.join(themedir, theme_name + u'.xml'), u'w')
|
||||||
|
out_file.write(file_xml.encode(u'utf-8'))
|
||||||
|
out_file.close()
|
||||||
|
if background.text.strip() == u'2':
|
||||||
|
image_name = 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(image_name)[1].lower() and name.find(r'/'),
|
||||||
|
zip.namelist())
|
||||||
|
if len(imagefile) >= 1:
|
||||||
|
out_file = open(os.path.join(themedir, image_name), u'wb')
|
||||||
|
out_file.write(zip.read(imagefile[0]))
|
||||||
|
out_file.close()
|
||||||
|
else:
|
||||||
|
log.exception(u'Theme file does not contain image file "%s"' %
|
||||||
|
image_name.decode(u'utf-8', u'replace'))
|
||||||
|
raise Exception(u'validation')
|
||||||
|
return theme_name, file_xml, out_file, False
|
||||||
|
|
||||||
|
def checkIfThemeExists(self, theme_name):
|
||||||
"""
|
"""
|
||||||
Check if theme already exists and displays error message
|
Check if theme already exists and displays error message
|
||||||
|
|
||||||
``themeName``
|
``theme_name``
|
||||||
Name of the Theme to test
|
Name of the Theme to test
|
||||||
"""
|
"""
|
||||||
theme_dir = os.path.join(self.path, themeName)
|
theme_dir = os.path.join(self.path, theme_name)
|
||||||
if os.path.exists(theme_dir):
|
if os.path.exists(theme_dir):
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
@ -598,12 +653,12 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def saveTheme(self, theme, imageFrom, imageTo):
|
def saveTheme(self, theme, image_from, image_to):
|
||||||
"""
|
"""
|
||||||
Called by thememaintenance Dialog to save the theme
|
Called by thememaintenance Dialog to save the theme
|
||||||
and to trigger the reload of the theme list
|
and to trigger the reload of the theme list
|
||||||
"""
|
"""
|
||||||
self._writeTheme(theme, imageFrom, imageTo)
|
self._writeTheme(theme, image_from, image_to)
|
||||||
if theme.background_type == \
|
if theme.background_type == \
|
||||||
BackgroundType.to_string(BackgroundType.Image):
|
BackgroundType.to_string(BackgroundType.Image):
|
||||||
self.mainwindow.imageManager.update_image(theme.theme_name,
|
self.mainwindow.imageManager.update_image(theme.theme_name,
|
||||||
@ -611,7 +666,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.mainwindow.imageManager.process_updates()
|
self.mainwindow.imageManager.process_updates()
|
||||||
self.loadThemes()
|
self.loadThemes()
|
||||||
|
|
||||||
def _writeTheme(self, theme, imageFrom, imageTo):
|
def _writeTheme(self, theme, image_from, image_to):
|
||||||
"""
|
"""
|
||||||
Writes the theme to the disk and handles the background image if
|
Writes the theme to the disk and handles the background image if
|
||||||
necessary
|
necessary
|
||||||
@ -622,24 +677,24 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
theme_dir = os.path.join(self.path, name)
|
theme_dir = os.path.join(self.path, name)
|
||||||
check_directory_exists(theme_dir)
|
check_directory_exists(theme_dir)
|
||||||
theme_file = os.path.join(theme_dir, name + u'.xml')
|
theme_file = os.path.join(theme_dir, name + u'.xml')
|
||||||
if self.oldBackgroundImage and \
|
if self.old_background_image and \
|
||||||
imageTo != self.oldBackgroundImage:
|
image_to != self.old_background_image:
|
||||||
delete_file(self.oldBackgroundImage)
|
delete_file(self.old_background_image)
|
||||||
outfile = None
|
out_file = None
|
||||||
try:
|
try:
|
||||||
outfile = open(theme_file, u'w')
|
out_file = open(theme_file, u'w')
|
||||||
outfile.write(theme_pretty_xml)
|
out_file.write(theme_pretty_xml)
|
||||||
except IOError:
|
except IOError:
|
||||||
log.exception(u'Saving theme to file failed')
|
log.exception(u'Saving theme to file failed')
|
||||||
finally:
|
finally:
|
||||||
if outfile:
|
if out_file:
|
||||||
outfile.close()
|
out_file.close()
|
||||||
if imageFrom and imageFrom != imageTo:
|
if image_from and image_from != image_to:
|
||||||
try:
|
try:
|
||||||
encoding = get_filesystem_encoding()
|
encoding = get_filesystem_encoding()
|
||||||
shutil.copyfile(
|
shutil.copyfile(
|
||||||
unicode(imageFrom).encode(encoding),
|
unicode(image_from).encode(encoding),
|
||||||
unicode(imageTo).encode(encoding))
|
unicode(image_to).encode(encoding))
|
||||||
except IOError:
|
except IOError:
|
||||||
log.exception(u'Failed to save theme image')
|
log.exception(u'Failed to save theme image')
|
||||||
self.generateAndSaveImage(self.path, name, theme)
|
self.generateAndSaveImage(self.path, name, theme)
|
||||||
@ -647,39 +702,39 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
def generateAndSaveImage(self, dir, name, theme):
|
def generateAndSaveImage(self, dir, name, theme):
|
||||||
log.debug(u'generateAndSaveImage %s %s', dir, name)
|
log.debug(u'generateAndSaveImage %s %s', dir, name)
|
||||||
frame = self.generateImage(theme)
|
frame = self.generateImage(theme)
|
||||||
samplepathname = os.path.join(self.path, name + u'.png')
|
sample_path_name = os.path.join(self.path, name + u'.png')
|
||||||
if os.path.exists(samplepathname):
|
if os.path.exists(sample_path_name):
|
||||||
os.unlink(samplepathname)
|
os.unlink(sample_path_name)
|
||||||
frame.save(samplepathname, u'png')
|
frame.save(sample_path_name, u'png')
|
||||||
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
|
thumb = os.path.join(self.thumb_path, u'%s.png' % name)
|
||||||
create_thumb(samplepathname, thumb, False)
|
create_thumb(sample_path_name, thumb, False)
|
||||||
log.debug(u'Theme image written to %s', samplepathname)
|
log.debug(u'Theme image written to %s', sample_path_name)
|
||||||
|
|
||||||
def updatePreviewImages(self):
|
def updatePreviewImages(self):
|
||||||
"""
|
"""
|
||||||
Called to update the themes' preview images.
|
Called to update the themes' preview images.
|
||||||
"""
|
"""
|
||||||
self.mainwindow.displayProgressBar(len(self.themelist))
|
self.mainwindow.displayProgressBar(len(self.theme_list))
|
||||||
for theme in self.themelist:
|
for theme in self.theme_list:
|
||||||
self.mainwindow.incrementProgressBar()
|
self.mainwindow.incrementProgressBar()
|
||||||
self.generateAndSaveImage(
|
self.generateAndSaveImage(
|
||||||
self.path, theme, self.getThemeData(theme))
|
self.path, theme, self.getThemeData(theme))
|
||||||
self.mainwindow.finishedProgressBar()
|
self.mainwindow.finishedProgressBar()
|
||||||
self.loadThemes()
|
self.loadThemes()
|
||||||
|
|
||||||
def generateImage(self, themeData, forcePage=False):
|
def generateImage(self, theme_data, forcePage=False):
|
||||||
"""
|
"""
|
||||||
Call the renderer to build a Sample Image
|
Call the renderer to build a Sample Image
|
||||||
|
|
||||||
``themeData``
|
``theme_data``
|
||||||
The theme to generated a preview for.
|
The theme to generated a preview for.
|
||||||
|
|
||||||
``forcePage``
|
``forcePage``
|
||||||
Flag to tell message lines per page need to be generated.
|
Flag to tell message lines per page need to be generated.
|
||||||
"""
|
"""
|
||||||
log.debug(u'generateImage \n%s ', themeData)
|
log.debug(u'generateImage \n%s ', theme_data)
|
||||||
return self.mainwindow.renderer.generate_preview(
|
return self.mainwindow.renderer.generate_preview(
|
||||||
themeData, forcePage)
|
theme_data, forcePage)
|
||||||
|
|
||||||
def getPreviewImage(self, theme):
|
def getPreviewImage(self, theme):
|
||||||
"""
|
"""
|
||||||
@ -692,31 +747,15 @@ 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):
|
def _createThemeFromXml(self, theme_xml, path):
|
||||||
"""
|
|
||||||
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):
|
|
||||||
"""
|
"""
|
||||||
Return a theme object using information parsed from XML
|
Return a theme object using information parsed from XML
|
||||||
|
|
||||||
``themeXml``
|
``theme_xml``
|
||||||
The XML data to load into the theme
|
The XML data to load into the theme
|
||||||
"""
|
"""
|
||||||
theme = ThemeXML()
|
theme = ThemeXML()
|
||||||
theme.parse(themeXml)
|
theme.parse(theme_xml)
|
||||||
theme.extend_image_filename(path)
|
theme.extend_image_filename(path)
|
||||||
return theme
|
return theme
|
||||||
|
|
||||||
@ -771,50 +810,53 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
Version 1 theme to convert
|
Version 1 theme to convert
|
||||||
"""
|
"""
|
||||||
theme = Theme(xml_data)
|
theme = Theme(xml_data)
|
||||||
newtheme = ThemeXML()
|
new_theme = ThemeXML()
|
||||||
newtheme.theme_name = theme.Name
|
new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
|
||||||
if theme.BackgroundType == 0:
|
if theme.BackgroundType == 0:
|
||||||
newtheme.background_type = \
|
new_theme.background_type = \
|
||||||
BackgroundType.to_string(BackgroundType.Solid)
|
BackgroundType.to_string(BackgroundType.Solid)
|
||||||
newtheme.background_color = \
|
new_theme.background_color = \
|
||||||
unicode(theme.BackgroundParameter1.name())
|
unicode(theme.BackgroundParameter1.name())
|
||||||
elif theme.BackgroundType == 1:
|
elif theme.BackgroundType == 1:
|
||||||
newtheme.background_type = \
|
new_theme.background_type = \
|
||||||
BackgroundType.to_string(BackgroundType.Gradient)
|
BackgroundType.to_string(BackgroundType.Gradient)
|
||||||
newtheme.background_direction = \
|
new_theme.background_direction = \
|
||||||
BackgroundGradientType. \
|
BackgroundGradientType. \
|
||||||
to_string(BackgroundGradientType.Horizontal)
|
to_string(BackgroundGradientType.Horizontal)
|
||||||
if theme.BackgroundParameter3.name() == 1:
|
if theme.BackgroundParameter3.name() == 1:
|
||||||
newtheme.background_direction = \
|
new_theme.background_direction = \
|
||||||
BackgroundGradientType. \
|
BackgroundGradientType. \
|
||||||
to_string(BackgroundGradientType.Horizontal)
|
to_string(BackgroundGradientType.Horizontal)
|
||||||
newtheme.background_start_color = \
|
new_theme.background_start_color = \
|
||||||
unicode(theme.BackgroundParameter1.name())
|
unicode(theme.BackgroundParameter1.name())
|
||||||
newtheme.background_end_color = \
|
new_theme.background_end_color = \
|
||||||
unicode(theme.BackgroundParameter2.name())
|
unicode(theme.BackgroundParameter2.name())
|
||||||
else:
|
elif theme.BackgroundType == 2:
|
||||||
newtheme.background_type = \
|
new_theme.background_type = \
|
||||||
BackgroundType.to_string(BackgroundType.Image)
|
BackgroundType.to_string(BackgroundType.Image)
|
||||||
newtheme.background_filename = unicode(theme.BackgroundParameter1)
|
new_theme.background_filename = unicode(theme.BackgroundParameter1)
|
||||||
newtheme.font_main_name = theme.FontName
|
elif theme.BackgroundType == 3:
|
||||||
newtheme.font_main_color = unicode(theme.FontColor.name())
|
new_theme.background_type = \
|
||||||
newtheme.font_main_size = theme.FontProportion * 3
|
BackgroundType.to_string(BackgroundType.Transparent)
|
||||||
newtheme.font_footer_name = theme.FontName
|
new_theme.font_main_name = theme.FontName
|
||||||
newtheme.font_footer_color = unicode(theme.FontColor.name())
|
new_theme.font_main_color = unicode(theme.FontColor.name())
|
||||||
newtheme.font_main_shadow = False
|
new_theme.font_main_size = theme.FontProportion * 3
|
||||||
|
new_theme.font_footer_name = theme.FontName
|
||||||
|
new_theme.font_footer_color = unicode(theme.FontColor.name())
|
||||||
|
new_theme.font_main_shadow = False
|
||||||
if theme.Shadow == 1:
|
if theme.Shadow == 1:
|
||||||
newtheme.font_main_shadow = True
|
new_theme.font_main_shadow = True
|
||||||
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
|
new_theme.font_main_shadow_color = unicode(theme.ShadowColor.name())
|
||||||
if theme.Outline == 1:
|
if theme.Outline == 1:
|
||||||
newtheme.font_main_outline = True
|
new_theme.font_main_outline = True
|
||||||
newtheme.font_main_outline_color = \
|
new_theme.font_main_outline_color = \
|
||||||
unicode(theme.OutlineColor.name())
|
unicode(theme.OutlineColor.name())
|
||||||
vAlignCorrection = VerticalType.Top
|
vAlignCorrection = VerticalType.Top
|
||||||
if theme.VerticalAlign == 2:
|
if theme.VerticalAlign == 2:
|
||||||
vAlignCorrection = VerticalType.Middle
|
vAlignCorrection = VerticalType.Middle
|
||||||
elif theme.VerticalAlign == 1:
|
elif theme.VerticalAlign == 1:
|
||||||
vAlignCorrection = VerticalType.Bottom
|
vAlignCorrection = VerticalType.Bottom
|
||||||
newtheme.display_horizontal_align = theme.HorizontalAlign
|
new_theme.display_horizontal_align = theme.HorizontalAlign
|
||||||
newtheme.display_vertical_align = vAlignCorrection
|
new_theme.display_vertical_align = vAlignCorrection
|
||||||
return newtheme.extract_xml()
|
return new_theme.extract_xml()
|
||||||
|
|
||||||
|
@ -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, #
|
||||||
|
@ -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:'))
|
||||||
|
@ -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'
|
||||||
|
@ -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, #
|
||||||
@ -53,6 +53,8 @@ APPLICATION_VERSION = {}
|
|||||||
IMAGES_FILTER = None
|
IMAGES_FILTER = None
|
||||||
UNO_CONNECTION_TYPE = u'pipe'
|
UNO_CONNECTION_TYPE = u'pipe'
|
||||||
#UNO_CONNECTION_TYPE = u'socket'
|
#UNO_CONNECTION_TYPE = u'socket'
|
||||||
|
CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]', re.UNICODE)
|
||||||
|
INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]', re.UNICODE)
|
||||||
VERSION_SPLITTER = re.compile(r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
|
VERSION_SPLITTER = re.compile(r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
|
||||||
|
|
||||||
class VersionThread(QtCore.QThread):
|
class VersionThread(QtCore.QThread):
|
||||||
@ -400,7 +402,7 @@ def clean_filename(filename):
|
|||||||
"""
|
"""
|
||||||
if not isinstance(filename, unicode):
|
if not isinstance(filename, unicode):
|
||||||
filename = unicode(filename, u'utf-8')
|
filename = unicode(filename, u'utf-8')
|
||||||
return re.sub(r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
|
return INVALID_FILE_CHARS.sub(u'_', CONTROL_CHARS.sub(u'', filename))
|
||||||
|
|
||||||
def delete_file(file_path_name):
|
def delete_file(file_path_name):
|
||||||
"""
|
"""
|
||||||
@ -455,26 +457,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 +489,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']
|
||||||
|
@ -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
|
||||||
@ -252,8 +281,17 @@ class ActionList(object):
|
|||||||
return
|
return
|
||||||
self.categories[category].actions.remove(action)
|
self.categories[category].actions.remove(action)
|
||||||
# Remove empty categories.
|
# Remove empty categories.
|
||||||
if len(self.categories[category].actions) == 0:
|
if not self.categories[category].actions:
|
||||||
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,73 @@ 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.
|
||||||
|
"""
|
||||||
|
local = action.shortcutContext() in \
|
||||||
|
[QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
|
||||||
|
affected_actions = filter(lambda a: isinstance(a, QtGui.QAction),
|
||||||
|
self.getAllChildObjects(action.parent())) if local else []
|
||||||
|
for existing_action in existing_actions:
|
||||||
|
if action is existing_action:
|
||||||
|
continue
|
||||||
|
if not local or existing_action in affected_actions:
|
||||||
|
return False
|
||||||
|
if existing_action.shortcutContext() \
|
||||||
|
in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||||
|
return False
|
||||||
|
elif action in self.getAllChildObjects(existing_action.parent()):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getAllChildObjects(self, qobject):
|
||||||
|
"""
|
||||||
|
Goes recursively through the children of ``qobject`` and returns a list
|
||||||
|
of all child objects.
|
||||||
|
"""
|
||||||
|
children = [child for child in qobject.children()]
|
||||||
|
for child in qobject.children():
|
||||||
|
children.append(self.getAllChildObjects(child))
|
||||||
|
return children
|
||||||
|
|
||||||
|
|
||||||
class CategoryOrder(object):
|
class CategoryOrder(object):
|
||||||
"""
|
"""
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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,7 +31,7 @@ from PyQt4 import QtCore
|
|||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.db import Manager
|
from openlp.core.lib.db import Manager
|
||||||
from openlp.core.lib.ui import icon_action, UiStrings
|
from openlp.core.lib.ui import create_action, UiStrings
|
||||||
from openlp.core.lib.theme import VerticalType
|
from openlp.core.lib.theme import VerticalType
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
|
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
|
||||||
@ -133,16 +133,12 @@ class AlertsPlugin(Plugin):
|
|||||||
use it as their parent.
|
use it as their parent.
|
||||||
"""
|
"""
|
||||||
log.info(u'add tools menu')
|
log.info(u'add tools menu')
|
||||||
self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem',
|
self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
|
||||||
u':/plugins/plugin_alerts.png')
|
text=translate('AlertsPlugin', '&Alert'),
|
||||||
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
|
icon=u':/plugins/plugin_alerts.png',
|
||||||
self.toolsAlertItem.setStatusTip(
|
statustip=translate('AlertsPlugin', 'Show an alert message.'),
|
||||||
translate('AlertsPlugin', 'Show an alert message.'))
|
visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
|
||||||
self.toolsAlertItem.setShortcut(u'F7')
|
|
||||||
self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem)
|
self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem)
|
||||||
QtCore.QObject.connect(self.toolsAlertItem,
|
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onAlertsTrigger)
|
|
||||||
self.toolsAlertItem.setVisible(False)
|
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
log.info(u'Alerts Initialising')
|
log.info(u'Alerts Initialising')
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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,10 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.ui import base_action, UiStrings
|
from openlp.core.lib.ui import create_action, UiStrings
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
||||||
from openlp.plugins.bibles.forms import BibleUpgradeForm
|
from openlp.plugins.bibles.forms import BibleUpgradeForm
|
||||||
@ -93,19 +93,16 @@ class BiblePlugin(Plugin):
|
|||||||
self.onToolsUpgradeItemTriggered()
|
self.onToolsUpgradeItemTriggered()
|
||||||
|
|
||||||
def addImportMenuItem(self, import_menu):
|
def addImportMenuItem(self, import_menu):
|
||||||
self.importBibleItem = base_action(import_menu, u'importBibleItem')
|
self.importBibleItem = create_action(import_menu, u'importBibleItem',
|
||||||
self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
|
text=translate('BiblesPlugin', '&Bible'), visible=False,
|
||||||
|
triggers=self.onBibleImportClick)
|
||||||
import_menu.addAction(self.importBibleItem)
|
import_menu.addAction(self.importBibleItem)
|
||||||
# signals and slots
|
|
||||||
QtCore.QObject.connect(self.importBibleItem,
|
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
|
|
||||||
self.importBibleItem.setVisible(False)
|
|
||||||
|
|
||||||
def addExportMenuItem(self, export_menu):
|
def addExportMenuItem(self, export_menu):
|
||||||
self.exportBibleItem = base_action(export_menu, u'exportBibleItem')
|
self.exportBibleItem = create_action(export_menu, u'exportBibleItem',
|
||||||
self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
|
text=translate('BiblesPlugin', '&Bible'),
|
||||||
|
visible=False)
|
||||||
export_menu.addAction(self.exportBibleItem)
|
export_menu.addAction(self.exportBibleItem)
|
||||||
self.exportBibleItem.setVisible(False)
|
|
||||||
|
|
||||||
def addToolsMenuItem(self, tools_menu):
|
def addToolsMenuItem(self, tools_menu):
|
||||||
"""
|
"""
|
||||||
@ -117,17 +114,12 @@ class BiblePlugin(Plugin):
|
|||||||
use it as their parent.
|
use it as their parent.
|
||||||
"""
|
"""
|
||||||
log.debug(u'add tools menu')
|
log.debug(u'add tools menu')
|
||||||
self.toolsUpgradeItem = QtGui.QAction(tools_menu)
|
self.toolsUpgradeItem = create_action(tools_menu, u'toolsUpgradeItem',
|
||||||
self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
|
text=translate('BiblesPlugin', '&Upgrade older Bibles'),
|
||||||
self.toolsUpgradeItem.setText(
|
statustip=translate('BiblesPlugin',
|
||||||
translate('BiblesPlugin', '&Upgrade older Bibles'))
|
'Upgrade the Bible databases to the latest format.'),
|
||||||
self.toolsUpgradeItem.setStatusTip(
|
visible=False, triggers=self.onToolsUpgradeItemTriggered)
|
||||||
translate('BiblesPlugin', 'Upgrade the Bible databases to the '
|
|
||||||
'latest format.'))
|
|
||||||
tools_menu.addAction(self.toolsUpgradeItem)
|
tools_menu.addAction(self.toolsUpgradeItem)
|
||||||
QtCore.QObject.connect(self.toolsUpgradeItem,
|
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
|
|
||||||
self.toolsUpgradeItem.setVisible(False)
|
|
||||||
|
|
||||||
def onToolsUpgradeItemTriggered(self):
|
def onToolsUpgradeItemTriggered(self):
|
||||||
"""
|
"""
|
||||||
|
@ -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, #
|
||||||
|
@ -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, #
|
||||||
|
@ -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 #
|
||||||
|
@ -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 #
|
||||||
|
@ -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 #
|
||||||
|
@ -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 #
|
||||||
|
@ -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 #
|
||||||
|
@ -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,16 @@ plugin.
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||||
|
|
||||||
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,41 +60,198 @@ class DisplayStyle(object):
|
|||||||
Square = 3
|
Square = 3
|
||||||
|
|
||||||
|
|
||||||
|
class LanguageSelection(object):
|
||||||
|
"""
|
||||||
|
An enumeration for bible bookname language.
|
||||||
|
And standard strings for use throughout the bibles plugin.
|
||||||
|
"""
|
||||||
|
Bible = 0
|
||||||
|
Application = 1
|
||||||
|
English = 2
|
||||||
|
|
||||||
|
|
||||||
|
class BibleStrings(object):
|
||||||
|
"""
|
||||||
|
Provide standard strings for objects to use.
|
||||||
|
"""
|
||||||
|
__instance__ = None
|
||||||
|
|
||||||
|
def __new__(cls):
|
||||||
|
"""
|
||||||
|
Override the default object creation method to return a single instance.
|
||||||
|
"""
|
||||||
|
if not cls.__instance__:
|
||||||
|
cls.__instance__ = object.__new__(cls)
|
||||||
|
return cls.__instance__
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
These strings should need a good reason to be retranslated elsewhere.
|
||||||
|
"""
|
||||||
|
self.Booknames = {
|
||||||
|
u'Gen': translate('BiblesPlugin', 'Genesis'),
|
||||||
|
u'Exod': translate('BiblesPlugin', 'Exodus'),
|
||||||
|
u'Lev': translate('BiblesPlugin', 'Leviticus'),
|
||||||
|
u'Num': translate('BiblesPlugin', 'Numbers'),
|
||||||
|
u'Deut': translate('BiblesPlugin', 'Deuteronomy'),
|
||||||
|
u'Josh': translate('BiblesPlugin', 'Joshua'),
|
||||||
|
u'Judg': translate('BiblesPlugin', 'Judges'),
|
||||||
|
u'Ruth': translate('BiblesPlugin', 'Ruth'),
|
||||||
|
u'1Sam': translate('BiblesPlugin', '1 Samuel'),
|
||||||
|
u'2Sam': translate('BiblesPlugin', '2 Samuel'),
|
||||||
|
u'1Kgs': translate('BiblesPlugin', '1 Kings'),
|
||||||
|
u'2Kgs': translate('BiblesPlugin', '2 Kings'),
|
||||||
|
u'1Chr': translate('BiblesPlugin', '1 Chronicles'),
|
||||||
|
u'2Chr': translate('BiblesPlugin', '2 Chronicles'),
|
||||||
|
u'Esra': translate('BiblesPlugin', 'Ezra'),
|
||||||
|
u'Neh': translate('BiblesPlugin', 'Nehemiah'),
|
||||||
|
u'Esth': translate('BiblesPlugin', 'Esther'),
|
||||||
|
u'Job': translate('BiblesPlugin', 'Job'),
|
||||||
|
u'Ps': translate('BiblesPlugin', 'Psalms'),
|
||||||
|
u'Prov': translate('BiblesPlugin', 'Proverbs'),
|
||||||
|
u'Eccl': translate('BiblesPlugin', 'Ecclesiastes'),
|
||||||
|
u'Song': translate('BiblesPlugin', 'Song of Solomon'),
|
||||||
|
u'Isa': translate('BiblesPlugin', 'Isaiah'),
|
||||||
|
u'Jer': translate('BiblesPlugin', 'Jeremiah'),
|
||||||
|
u'Lam': translate('BiblesPlugin', 'Lamentations'),
|
||||||
|
u'Ezek': translate('BiblesPlugin', 'Ezekiel'),
|
||||||
|
u'Dan': translate('BiblesPlugin', 'Daniel'),
|
||||||
|
u'Hos': translate('BiblesPlugin', 'Hosea'),
|
||||||
|
u'Joel': translate('BiblesPlugin', 'Joel'),
|
||||||
|
u'Amos': translate('BiblesPlugin', 'Amos'),
|
||||||
|
u'Obad': translate('BiblesPlugin', 'Obadiah'),
|
||||||
|
u'Jonah': translate('BiblesPlugin', 'Jonah'),
|
||||||
|
u'Mic': translate('BiblesPlugin', 'Micah'),
|
||||||
|
u'Nah': translate('BiblesPlugin', 'Nahum'),
|
||||||
|
u'Hab': translate('BiblesPlugin', 'Habakkuk'),
|
||||||
|
u'Zeph': translate('BiblesPlugin', 'Zephaniah'),
|
||||||
|
u'Hag': translate('BiblesPlugin', 'Haggai'),
|
||||||
|
u'Zech': translate('BiblesPlugin', 'Zechariah'),
|
||||||
|
u'Mal': translate('BiblesPlugin', 'Malachi'),
|
||||||
|
u'Matt': translate('BiblesPlugin', 'Matthew'),
|
||||||
|
u'Mark': translate('BiblesPlugin', 'Mark'),
|
||||||
|
u'Luke': translate('BiblesPlugin', 'Luke'),
|
||||||
|
u'John': translate('BiblesPlugin', 'John'),
|
||||||
|
u'Acts': translate('BiblesPlugin', 'Acts'),
|
||||||
|
u'Rom': translate('BiblesPlugin', 'Romans'),
|
||||||
|
u'1Cor': translate('BiblesPlugin', '1 Corinthians'),
|
||||||
|
u'2Cor': translate('BiblesPlugin', '2 Corinthians'),
|
||||||
|
u'Gal': translate('BiblesPlugin', 'Galatians'),
|
||||||
|
u'Eph': translate('BiblesPlugin', 'Ephesians'),
|
||||||
|
u'Phil': translate('BiblesPlugin', 'Philippians'),
|
||||||
|
u'Col': translate('BiblesPlugin', 'Colossians'),
|
||||||
|
u'1Thess': translate('BiblesPlugin', '1 Thessalonians'),
|
||||||
|
u'2Thess': translate('BiblesPlugin', '2 Thessalonians'),
|
||||||
|
u'1Tim': translate('BiblesPlugin', '1 Timothy'),
|
||||||
|
u'2Tim': translate('BiblesPlugin', '2 Timothy'),
|
||||||
|
u'Titus': translate('BiblesPlugin', 'Titus'),
|
||||||
|
u'Phlm': translate('BiblesPlugin', 'Philemon'),
|
||||||
|
u'Heb': translate('BiblesPlugin', 'Hebrews'),
|
||||||
|
u'Jas': translate('BiblesPlugin', 'James'),
|
||||||
|
u'1Pet': translate('BiblesPlugin', '1 Peter'),
|
||||||
|
u'2Pet': translate('BiblesPlugin', '2 Peter'),
|
||||||
|
u'1John': translate('BiblesPlugin', '1 John'),
|
||||||
|
u'2John': translate('BiblesPlugin', '2 John'),
|
||||||
|
u'3John': translate('BiblesPlugin', '3 John'),
|
||||||
|
u'Jude': translate('BiblesPlugin', 'Jude'),
|
||||||
|
u'Rev': translate('BiblesPlugin', 'Revelation'),
|
||||||
|
u'Jdt': translate('BiblesPlugin', 'Judith'),
|
||||||
|
u'Wis': translate('BiblesPlugin', 'Wisdom'),
|
||||||
|
u'Tob': translate('BiblesPlugin', 'Tobit'),
|
||||||
|
u'Sir': translate('BiblesPlugin', 'Sirach'),
|
||||||
|
u'Bar': translate('BiblesPlugin', 'Baruch'),
|
||||||
|
u'1Macc': translate('BiblesPlugin', '1 Maccabees'),
|
||||||
|
u'2Macc': translate('BiblesPlugin', '2 Maccabees'),
|
||||||
|
u'3Macc': translate('BiblesPlugin', '3 Maccabees'),
|
||||||
|
u'4Macc': translate('BiblesPlugin', '4 Maccabees'),
|
||||||
|
u'AddDan': translate('BiblesPlugin', 'Rest of Daniel'),
|
||||||
|
u'AddEsth': translate('BiblesPlugin', 'Rest of Esther'),
|
||||||
|
u'PrMan': translate('BiblesPlugin', 'Prayer of Manasses'),
|
||||||
|
u'LetJer': translate('BiblesPlugin', 'Letter of Jeremiah'),
|
||||||
|
u'PrAza': translate('BiblesPlugin', 'Prayer of Azariah'),
|
||||||
|
u'Sus': translate('BiblesPlugin', 'Susanna'),
|
||||||
|
u'Bel': translate('BiblesPlugin', 'Bel'),
|
||||||
|
u'1Esdr': translate('BiblesPlugin', '1 Esdras'),
|
||||||
|
u'2Esdr': translate('BiblesPlugin', '2 Esdras')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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',
|
||||||
|
'Double-semicolon delimited separators for parsing references. '
|
||||||
|
'Consult the developers for further information.')).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)?)?
|
def parse_reference(reference, bible, language_selection, book_ref_id=False):
|
||||||
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):
|
|
||||||
"""
|
"""
|
||||||
This is the next generation über-awesome function that takes a person's
|
This is the next generation über-awesome function that takes a person's
|
||||||
typed in string and converts it to a list of references to be queried from
|
typed in string and converts it to a list of references to be queried from
|
||||||
@ -95,6 +260,16 @@ def parse_reference(reference):
|
|||||||
``reference``
|
``reference``
|
||||||
A string. The Bible reference to parse.
|
A string. The Bible reference to parse.
|
||||||
|
|
||||||
|
``bible``
|
||||||
|
A object. The Bible database object.
|
||||||
|
|
||||||
|
``language_selection``
|
||||||
|
An int. The language selection the user has choosen in settings
|
||||||
|
section.
|
||||||
|
|
||||||
|
``book_ref_id``
|
||||||
|
A string. The book reference id.
|
||||||
|
|
||||||
Returns ``None`` or a reference list.
|
Returns ``None`` or a reference list.
|
||||||
|
|
||||||
The reference list is a list of tuples, with each tuple structured like
|
The reference list is a list of tuples, with each tuple structured like
|
||||||
@ -140,7 +315,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 +344,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)
|
||||||
@ -179,6 +354,51 @@ def parse_reference(reference):
|
|||||||
if match:
|
if match:
|
||||||
log.debug(u'Matched reference %s' % reference)
|
log.debug(u'Matched reference %s' % reference)
|
||||||
book = match.group(u'book')
|
book = match.group(u'book')
|
||||||
|
if not book_ref_id:
|
||||||
|
booknames = BibleStrings().Booknames
|
||||||
|
# escape reserved characters
|
||||||
|
book_escaped = book
|
||||||
|
for character in u'\\.^$*+?{}[]()':
|
||||||
|
book_escaped = book_escaped.replace(
|
||||||
|
character, u'\\' + character)
|
||||||
|
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
|
||||||
|
book_escaped.split()), re.UNICODE | re.IGNORECASE)
|
||||||
|
if language_selection == LanguageSelection.Bible:
|
||||||
|
db_book = bible.get_book(book)
|
||||||
|
if db_book:
|
||||||
|
book_ref_id = db_book.book_reference_id
|
||||||
|
elif language_selection == LanguageSelection.Application:
|
||||||
|
book_list = []
|
||||||
|
for key, value in booknames.iteritems():
|
||||||
|
if regex_book.match(unicode(value)):
|
||||||
|
book_list.append(key)
|
||||||
|
books = []
|
||||||
|
if book_list:
|
||||||
|
for value in book_list:
|
||||||
|
item = BiblesResourcesDB.get_book(value)
|
||||||
|
if item:
|
||||||
|
books.append(item)
|
||||||
|
if books:
|
||||||
|
for value in books:
|
||||||
|
if bible.get_book_by_book_ref_id(value[u'id']):
|
||||||
|
book_ref_id = value[u'id']
|
||||||
|
break
|
||||||
|
elif language_selection == LanguageSelection.English:
|
||||||
|
books = BiblesResourcesDB.get_books_like(book)
|
||||||
|
if books:
|
||||||
|
book_list = []
|
||||||
|
for value in books:
|
||||||
|
if regex_book.match(value[u'name']):
|
||||||
|
book_list.append(value)
|
||||||
|
if not book_list:
|
||||||
|
book_list = books
|
||||||
|
for value in book_list:
|
||||||
|
if bible.get_book_by_book_ref_id(value[u'id']):
|
||||||
|
book_ref_id = value[u'id']
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if not bible.get_book_by_book_ref_id(book_ref_id):
|
||||||
|
book_ref_id = False
|
||||||
ranges = match.group(u'ranges')
|
ranges = match.group(u'ranges')
|
||||||
range_list = get_reference_match(u'range_separator').split(ranges)
|
range_list = get_reference_match(u'range_separator').split(ranges)
|
||||||
ref_list = []
|
ref_list = []
|
||||||
@ -224,16 +444,18 @@ def parse_reference(reference):
|
|||||||
if not to_verse:
|
if not to_verse:
|
||||||
to_verse = -1
|
to_verse = -1
|
||||||
if to_chapter > from_chapter:
|
if to_chapter > from_chapter:
|
||||||
ref_list.append((book, from_chapter, from_verse, -1))
|
ref_list.append((book_ref_id, from_chapter, from_verse, -1))
|
||||||
for i in range(from_chapter + 1, to_chapter):
|
for i in range(from_chapter + 1, to_chapter):
|
||||||
ref_list.append((book, i, 1, -1))
|
ref_list.append((book_ref_id, i, 1, -1))
|
||||||
ref_list.append((book, to_chapter, 1, to_verse))
|
ref_list.append((book_ref_id, to_chapter, 1, to_verse))
|
||||||
elif to_verse >= from_verse or to_verse == -1:
|
elif to_verse >= from_verse or to_verse == -1:
|
||||||
ref_list.append((book, from_chapter, from_verse, to_verse))
|
ref_list.append((book_ref_id, from_chapter,
|
||||||
|
from_verse, to_verse))
|
||||||
elif from_verse:
|
elif from_verse:
|
||||||
ref_list.append((book, from_chapter, from_verse, from_verse))
|
ref_list.append((book_ref_id, from_chapter,
|
||||||
|
from_verse, from_verse))
|
||||||
else:
|
else:
|
||||||
ref_list.append((book, from_chapter, 1, -1))
|
ref_list.append((book_ref_id, from_chapter, 1, -1))
|
||||||
return ref_list
|
return ref_list
|
||||||
else:
|
else:
|
||||||
log.debug(u'Invalid reference: %s' % reference)
|
log.debug(u'Invalid reference: %s' % reference)
|
||||||
|
@ -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, LanguageSelection
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -90,9 +91,74 @@ 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.leftLayout.addStretch()
|
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.rightColumn.setSizePolicy(
|
self.rightColumn.setSizePolicy(
|
||||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
|
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
|
||||||
|
self.languageSelectionGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
|
self.languageSelectionGroupBox.setObjectName(
|
||||||
|
u'languageSelectionGroupBox')
|
||||||
|
self.languageSelectionLayout = QtGui.QVBoxLayout(
|
||||||
|
self.languageSelectionGroupBox)
|
||||||
|
self.languageSelectionLabel = QtGui.QLabel(
|
||||||
|
self.languageSelectionGroupBox)
|
||||||
|
self.languageSelectionLabel.setObjectName(u'languageSelectionLabel')
|
||||||
|
self.languageSelectionComboBox = QtGui.QComboBox(
|
||||||
|
self.languageSelectionGroupBox)
|
||||||
|
self.languageSelectionComboBox.setObjectName(
|
||||||
|
u'languageSelectionComboBox')
|
||||||
|
self.languageSelectionComboBox.addItems([u'', u'', u''])
|
||||||
|
self.languageSelectionLayout.addWidget(self.languageSelectionLabel)
|
||||||
|
self.languageSelectionLayout.addWidget(self.languageSelectionComboBox)
|
||||||
|
self.rightLayout.addWidget(self.languageSelectionGroupBox)
|
||||||
|
self.leftLayout.addStretch()
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
QtCore.QObject.connect(
|
QtCore.QObject.connect(
|
||||||
@ -110,8 +176,47 @@ 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)
|
||||||
|
QtCore.QObject.connect(
|
||||||
|
self.languageSelectionComboBox, QtCore.SIGNAL(u'activated(int)'),
|
||||||
|
self.onLanguageSelectionComboBoxChanged)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.verseDisplayGroupBox.setTitle(
|
self.verseDisplayGroupBox.setTitle(
|
||||||
@ -141,6 +246,53 @@ 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.'))
|
||||||
|
self.languageSelectionGroupBox.setTitle(
|
||||||
|
translate('BiblesPlugin.BiblesTab', 'Preferred Bookname Language'))
|
||||||
|
self.languageSelectionLabel.setText(translate('BiblesPlugin.BiblesTab',
|
||||||
|
'Choose the language in which the book names of the\nBible should '
|
||||||
|
'be displayed in the Bible search:'))
|
||||||
|
self.languageSelectionComboBox.setItemText(LanguageSelection.Bible,
|
||||||
|
translate('BiblesPlugin.BiblesTab', 'Bible language'))
|
||||||
|
self.languageSelectionComboBox.setItemText(
|
||||||
|
LanguageSelection.Application,
|
||||||
|
translate('BiblesPlugin.BiblesTab', 'Application language'))
|
||||||
|
self.languageSelectionComboBox.setItemText(LanguageSelection.English,
|
||||||
|
translate('BiblesPlugin.BiblesTab', 'English'))
|
||||||
|
self.languageSelectionComboBox.setToolTip(
|
||||||
|
translate('BiblesPlugin.BiblesTab', 'Multiple options:\n '
|
||||||
|
'Bible language - the language in which the Bible book names '
|
||||||
|
'were imported\n Application language - the language you have '
|
||||||
|
'chosen for OpenLP\n English - always use English book names'))
|
||||||
|
|
||||||
def onBibleThemeComboBoxChanged(self):
|
def onBibleThemeComboBoxChanged(self):
|
||||||
self.bible_theme = self.bibleThemeComboBox.currentText()
|
self.bible_theme = self.bibleThemeComboBox.currentText()
|
||||||
@ -151,6 +303,9 @@ class BiblesTab(SettingsTab):
|
|||||||
def onLayoutStyleComboBoxChanged(self):
|
def onLayoutStyleComboBoxChanged(self):
|
||||||
self.layout_style = self.layoutStyleComboBox.currentIndex()
|
self.layout_style = self.layoutStyleComboBox.currentIndex()
|
||||||
|
|
||||||
|
def onLanguageSelectionComboBoxChanged(self):
|
||||||
|
self.language_selection = self.languageSelectionComboBox.currentIndex()
|
||||||
|
|
||||||
def onNewChaptersCheckBoxChanged(self, check_state):
|
def onNewChaptersCheckBoxChanged(self, check_state):
|
||||||
self.show_new_chapters = False
|
self.show_new_chapters = False
|
||||||
# We have a set value convert to True/False.
|
# We have a set value convert to True/False.
|
||||||
@ -163,6 +318,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 +435,61 @@ 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)
|
||||||
|
self.language_selection = settings.value(
|
||||||
|
u'bookname language', QtCore.QVariant(0)).toInt()[0]
|
||||||
|
self.languageSelectionComboBox.setCurrentIndex(self.language_selection)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -191,8 +501,32 @@ class BiblesTab(SettingsTab):
|
|||||||
QtCore.QVariant(self.display_style))
|
QtCore.QVariant(self.display_style))
|
||||||
settings.setValue(u'verse layout style',
|
settings.setValue(u'verse layout style',
|
||||||
QtCore.QVariant(self.layout_style))
|
QtCore.QVariant(self.layout_style))
|
||||||
|
settings.setValue(u'bookname language',
|
||||||
|
QtCore.QVariant(self.language_selection))
|
||||||
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()
|
||||||
|
Receiver.send_message(u'bibles_load_list')
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def updateThemeList(self, theme_list):
|
def updateThemeList(self, theme_list):
|
||||||
@ -209,3 +543,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
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user