forked from openlp/openlp
r1922
This commit is contained in:
commit
f6067002c0
|
@ -21,3 +21,5 @@ openlp/core/resources.py.old
|
|||
*.qm
|
||||
resources/windows/warnOpenLP.txt
|
||||
openlp.cfg
|
||||
.idea
|
||||
openlp.pro
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -32,7 +32,7 @@ import logging
|
|||
import os.path
|
||||
import types
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4 import QtCore, QtGui, Qt
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -43,6 +43,26 @@ class MediaType(object):
|
|||
Audio = 1
|
||||
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,
|
||||
encoding=QtCore.QCoreApplication.CodecForTr, n=-1,
|
||||
translate=QtCore.QCoreApplication.translate):
|
||||
|
@ -298,6 +318,34 @@ def check_directory_exists(dir):
|
|||
except IOError:
|
||||
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 listwidgetwithdnd import ListWidgetWithDnD
|
||||
from formattingtags import FormattingTags
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -33,7 +33,8 @@ from urllib import quote_plus as urlquote
|
|||
|
||||
from PyQt4 import QtCore
|
||||
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.pool import NullPool
|
||||
|
||||
|
@ -199,6 +200,10 @@ class Manager(object):
|
|||
urlquote(unicode(settings.value(u'db password').toString())),
|
||||
urlquote(unicode(settings.value(u'db hostname').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()
|
||||
if upgrade_mod:
|
||||
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
|
||||
|
@ -239,6 +244,17 @@ class Manager(object):
|
|||
self.session.commit()
|
||||
self.is_dirty = 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:
|
||||
self.session.rollback()
|
||||
log.exception(u'Object save failed')
|
||||
|
@ -260,6 +276,17 @@ class Manager(object):
|
|||
self.session.commit()
|
||||
self.is_dirty = 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:
|
||||
self.session.rollback()
|
||||
log.exception(u'Object list save failed')
|
||||
|
@ -278,6 +305,14 @@ class Manager(object):
|
|||
if not key:
|
||||
return object_class()
|
||||
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)
|
||||
|
||||
def get_object_filtered(self, object_class, filter_clause):
|
||||
|
@ -290,6 +325,14 @@ class Manager(object):
|
|||
``filter_clause``
|
||||
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()
|
||||
|
||||
def get_all_objects(self, object_class, filter_clause=None,
|
||||
|
@ -311,9 +354,17 @@ class Manager(object):
|
|||
if filter_clause is not None:
|
||||
query = query.filter(filter_clause)
|
||||
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:
|
||||
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()
|
||||
|
||||
def get_object_count(self, object_class, filter_clause=None):
|
||||
|
@ -330,6 +381,14 @@ class Manager(object):
|
|||
query = self.session.query(object_class)
|
||||
if filter_clause is not None:
|
||||
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()
|
||||
|
||||
def delete_object(self, object_class, key):
|
||||
|
@ -349,6 +408,16 @@ class Manager(object):
|
|||
self.session.commit()
|
||||
self.is_dirty = 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:
|
||||
self.session.rollback()
|
||||
log.exception(u'Failed to delete object')
|
||||
|
@ -378,6 +447,19 @@ class Manager(object):
|
|||
self.session.commit()
|
||||
self.is_dirty = 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:
|
||||
self.session.rollback()
|
||||
log.exception(u'Failed to delete %s records', object_class.__name__)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -112,6 +112,9 @@ class EventReceiver(QtCore.QObject):
|
|||
``slidecontroller_live_spin_delay``
|
||||
Pushes out the loop delay.
|
||||
|
||||
``slidecontroller_update_slide_limits``
|
||||
Updates the slide_limits variable from the saved settings.
|
||||
|
||||
``slidecontroller_live_stop_loop``
|
||||
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
|
||||
loaded.
|
||||
|
||||
``{plugin}_config_updated``
|
||||
The config has changed so tell the plugin about it.
|
||||
|
||||
``alerts_text``
|
||||
Displays an alert message.
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -45,6 +45,7 @@ HTMLSRC = u"""
|
|||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body {
|
||||
%s;
|
||||
|
@ -288,6 +289,9 @@ def build_background_css(item, width, height):
|
|||
background = u'background-color: black'
|
||||
if theme:
|
||||
if theme.background_type == \
|
||||
BackgroundType.to_string(BackgroundType.Transparent):
|
||||
background = u''
|
||||
elif theme.background_type == \
|
||||
BackgroundType.to_string(BackgroundType.Solid):
|
||||
background = u'background-color: %s' % theme.background_color
|
||||
else:
|
||||
|
@ -454,13 +458,18 @@ def build_lyrics_format_css(theme, width, height):
|
|||
# fix tag incompatibilities
|
||||
if theme.display_horizontal_align == HorizontalType.Justify:
|
||||
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; ' \
|
||||
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
||||
'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,
|
||||
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 webkit_version() <= 534.3:
|
||||
lyrics += u' letter-spacing: 1px;'
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -166,7 +166,7 @@ class ImageManager(QtCore.QObject):
|
|||
self.height = current_screen[u'size'].height()
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for key, image in self._cache.iteritems():
|
||||
for image in self._cache.values():
|
||||
self._reset_image(image)
|
||||
|
||||
def update_images(self, image_type, background):
|
||||
|
@ -176,7 +176,7 @@ class ImageManager(QtCore.QObject):
|
|||
log.debug(u'update_images')
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for key, image in self._cache.iteritems():
|
||||
for image in self._cache.values():
|
||||
if image.source == image_type:
|
||||
image.background = background
|
||||
self._reset_image(image)
|
||||
|
@ -188,7 +188,7 @@ class ImageManager(QtCore.QObject):
|
|||
log.debug(u'update_images')
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# 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:
|
||||
image.background = background
|
||||
self._reset_image(image)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -35,8 +35,9 @@ from PyQt4 import QtCore, QtGui
|
|||
|
||||
from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
|
||||
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
|
||||
from openlp.core.lib.ui import UiStrings, context_menu_action, \
|
||||
context_menu_separator, critical_error_message_box
|
||||
from openlp.core.lib.searchedit import SearchEdit
|
||||
from openlp.core.lib.ui import UiStrings, create_widget_action, \
|
||||
critical_error_message_box
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -146,43 +147,6 @@ class MediaManagerItem(QtGui.QWidget):
|
|||
self.toolbar = OpenLPToolbar(self)
|
||||
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):
|
||||
"""
|
||||
This method sets up the interface on the button. Plugin
|
||||
|
@ -207,40 +171,41 @@ class MediaManagerItem(QtGui.QWidget):
|
|||
toolbar_actions = []
|
||||
## Import Button ##
|
||||
if self.hasImportIcon:
|
||||
toolbar_actions.append([StringContent.Import,
|
||||
toolbar_actions.append([u'Import', StringContent.Import,
|
||||
u':/general/general_import.png', self.onImportClick])
|
||||
## Load Button ##
|
||||
if self.hasFileIcon:
|
||||
toolbar_actions.append([StringContent.Load,
|
||||
toolbar_actions.append([u'Load', StringContent.Load,
|
||||
u':/general/general_open.png', self.onFileClick])
|
||||
## New Button ##
|
||||
if self.hasNewIcon:
|
||||
toolbar_actions.append([StringContent.New,
|
||||
toolbar_actions.append([u'New', StringContent.New,
|
||||
u':/general/general_new.png', self.onNewClick])
|
||||
## Edit Button ##
|
||||
if self.hasEditIcon:
|
||||
toolbar_actions.append([StringContent.Edit,
|
||||
toolbar_actions.append([u'Edit', StringContent.Edit,
|
||||
u':/general/general_edit.png', self.onEditClick])
|
||||
## Delete Button ##
|
||||
if self.hasDeleteIcon:
|
||||
toolbar_actions.append([StringContent.Delete,
|
||||
toolbar_actions.append([u'Delete', StringContent.Delete,
|
||||
u':/general/general_delete.png', self.onDeleteClick])
|
||||
## Preview ##
|
||||
toolbar_actions.append([StringContent.Preview,
|
||||
toolbar_actions.append([u'Preview', StringContent.Preview,
|
||||
u':/general/general_preview.png', self.onPreviewClick])
|
||||
## Live Button ##
|
||||
toolbar_actions.append([StringContent.Live,
|
||||
toolbar_actions.append([u'Live', StringContent.Live,
|
||||
u':/general/general_live.png', self.onLiveClick])
|
||||
## Add to service Button ##
|
||||
toolbar_actions.append([StringContent.Service,
|
||||
toolbar_actions.append([u'Service', StringContent.Service,
|
||||
u':/general/general_add.png', self.onAddClick])
|
||||
for action in toolbar_actions:
|
||||
if action[0] == StringContent.Preview:
|
||||
self.addToolbarSeparator()
|
||||
self.addToolbarButton(
|
||||
self.plugin.getString(action[0])[u'title'],
|
||||
self.plugin.getString(action[0])[u'tooltip'],
|
||||
action[1], action[2])
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addToolbarAction(
|
||||
u'%s%sAction' % (self.plugin.name, action[0]),
|
||||
text=self.plugin.getString(action[1])[u'title'], icon=action[2],
|
||||
tooltip=self.plugin.getString(action[1])[u'tooltip'],
|
||||
triggers=action[3])
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
"""
|
||||
|
@ -258,35 +223,37 @@ class MediaManagerItem(QtGui.QWidget):
|
|||
# define and add the context menu
|
||||
self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
if self.hasEditIcon:
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_edit.png',
|
||||
self.plugin.getString(StringContent.Edit)[u'title'],
|
||||
self.onEditClick)
|
||||
context_menu_separator(self.listView)
|
||||
create_widget_action(self.listView,
|
||||
text=self.plugin.getString(StringContent.Edit)[u'title'],
|
||||
icon=u':/general/general_edit.png',
|
||||
triggers=self.onEditClick)
|
||||
create_widget_action(self.listView, separator=True)
|
||||
if self.hasDeleteIcon:
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_delete.png',
|
||||
self.plugin.getString(StringContent.Delete)[u'title'],
|
||||
self.onDeleteClick, [QtCore.Qt.Key_Delete])
|
||||
context_menu_separator(self.listView)
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_preview.png',
|
||||
self.plugin.getString(StringContent.Preview)[u'title'],
|
||||
self.onPreviewClick, [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_live.png',
|
||||
self.plugin.getString(StringContent.Live)[u'title'],
|
||||
self.onLiveClick, [QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Enter,
|
||||
QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Return])
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_add.png',
|
||||
self.plugin.getString(StringContent.Service)[u'title'],
|
||||
self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal])
|
||||
create_widget_action(self.listView,
|
||||
text=self.plugin.getString(StringContent.Delete)[u'title'],
|
||||
icon=u':/general/general_delete.png',
|
||||
shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
|
||||
create_widget_action(self.listView, separator=True)
|
||||
create_widget_action(self.listView,
|
||||
text=self.plugin.getString(StringContent.Preview)[u'title'],
|
||||
icon=u':/general/general_preview.png',
|
||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
||||
triggers=self.onPreviewClick)
|
||||
create_widget_action(self.listView,
|
||||
text=self.plugin.getString(StringContent.Live)[u'title'],
|
||||
icon=u':/general/general_live.png',
|
||||
shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
|
||||
QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
|
||||
triggers=self.onLiveClick)
|
||||
create_widget_action(self.listView,
|
||||
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:
|
||||
context_menu_action(
|
||||
self.listView, u':/general/general_add.png',
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'&Add to selected Service Item'), self.onAddEditClick)
|
||||
create_widget_action(self.listView, text=translate(
|
||||
'OpenLP.MediaManagerItem', '&Add to selected Service Item'),
|
||||
icon=u':/general/general_add.png', triggers=self.onAddEditClick)
|
||||
self.addCustomContextActions()
|
||||
# Create the context menu and add all actions from the listView.
|
||||
self.menu = QtGui.QMenu()
|
||||
|
@ -301,6 +268,40 @@ class MediaManagerItem(QtGui.QWidget):
|
|||
QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
|
||||
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):
|
||||
"""
|
||||
Implement this method in your descendent media manager item to
|
||||
|
@ -640,7 +641,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||
if item:
|
||||
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``
|
||||
"""
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -173,6 +173,9 @@ class Plugin(QtCore.QObject):
|
|||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
|
||||
self.processAddServiceEvent)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_config_updated' % self.name),
|
||||
self.configUpdated)
|
||||
|
||||
def checkPreConditions(self):
|
||||
"""
|
||||
|
@ -395,3 +398,9 @@ class Plugin(QtCore.QObject):
|
|||
Add html code to htmlbuilder.
|
||||
"""
|
||||
return u''
|
||||
|
||||
def configUpdated(self):
|
||||
"""
|
||||
The plugin's config has changed
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -289,7 +289,7 @@ class Renderer(object):
|
|||
|
||||
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']
|
||||
self.width = screen_size.width()
|
||||
|
@ -380,6 +380,7 @@ class Renderer(object):
|
|||
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||
self.web.setHtml(html)
|
||||
self.empty_height = self.web_frame.contentsSize().height()
|
||||
|
||||
def _paginate_slide(self, lines, line_end):
|
||||
"""
|
||||
|
@ -600,7 +601,7 @@ class Renderer(object):
|
|||
"""
|
||||
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
||||
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):
|
||||
"""
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -30,7 +30,7 @@ import logging
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
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__)
|
||||
|
||||
|
@ -122,6 +122,13 @@ class SearchEdit(QtGui.QLineEdit):
|
|||
menu = self.menuButton.menu()
|
||||
for action in menu.actions():
|
||||
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._currentSearchType = 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
|
||||
item in the menu. In short, they should look like this::
|
||||
|
||||
(<identifier>, <icon>, <title>)
|
||||
(<identifier>, <icon>, <title>, <place holder text>)
|
||||
|
||||
For instance::
|
||||
|
||||
(1, <QIcon instance>, "Titles")
|
||||
(1, <QIcon instance>, "Titles", "Search Song Titles...")
|
||||
|
||||
Or::
|
||||
|
||||
(2, ":/songs/authors.png", "Authors")
|
||||
(2, ":/songs/authors.png", "Authors", "Search Authors...")
|
||||
"""
|
||||
menu = QtGui.QMenu(self)
|
||||
first = None
|
||||
for identifier, icon, title in items:
|
||||
action = icon_action(menu, u'', icon)
|
||||
action.setText(title)
|
||||
action.setData(QtCore.QVariant(identifier))
|
||||
menu.addAction(action)
|
||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
|
||||
self._onMenuActionTriggered)
|
||||
for identifier, icon, title, placeholder in items:
|
||||
action = create_widget_action(menu, text=title, icon=icon,
|
||||
data=identifier, triggers=self._onMenuActionTriggered)
|
||||
action.placeholderText = placeholder
|
||||
if first is None:
|
||||
first = action
|
||||
self._currentSearchType = identifier
|
||||
|
@ -206,5 +210,12 @@ class SearchEdit(QtGui.QLineEdit):
|
|||
action.setChecked(False)
|
||||
self.menuButton.setDefaultAction(sender)
|
||||
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._currentSearchType)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -300,6 +300,7 @@ class ServiceItem(object):
|
|||
``path``
|
||||
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']
|
||||
self.title = header[u'title']
|
||||
self.name = header[u'name']
|
||||
|
@ -325,7 +326,10 @@ class ServiceItem(object):
|
|||
if u'media_length' in header:
|
||||
self.media_length = header[u'media_length']
|
||||
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)
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -40,7 +40,7 @@ except ImportError:
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
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__)
|
||||
|
||||
|
@ -90,9 +90,8 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
|||
lang_menu = QtGui.QMenu(
|
||||
translate('OpenLP.SpellTextEdit', 'Language:'))
|
||||
for lang in enchant.list_languages():
|
||||
action = checkable_action(
|
||||
lang_menu, lang, lang == self.dictionary.tag)
|
||||
action.setText(lang)
|
||||
action = create_action(lang_menu, lang, text=lang,
|
||||
checked=lang == self.dictionary.tag)
|
||||
lang_menu.addAction(action)
|
||||
popupMenu.insertSeparator(popupMenu.actions()[0])
|
||||
popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -100,6 +100,7 @@ class BackgroundType(object):
|
|||
Solid = 0
|
||||
Gradient = 1
|
||||
Image = 2
|
||||
Transparent = 3
|
||||
|
||||
@staticmethod
|
||||
def to_string(background_type):
|
||||
|
@ -112,6 +113,8 @@ class BackgroundType(object):
|
|||
return u'gradient'
|
||||
elif background_type == BackgroundType.Image:
|
||||
return u'image'
|
||||
elif background_type == BackgroundType.Transparent:
|
||||
return u'transparent'
|
||||
|
||||
@staticmethod
|
||||
def from_string(type_string):
|
||||
|
@ -124,6 +127,8 @@ class BackgroundType(object):
|
|||
return BackgroundType.Gradient
|
||||
elif type_string == u'image':
|
||||
return BackgroundType.Image
|
||||
elif type_string == u'transparent':
|
||||
return BackgroundType.Transparent
|
||||
|
||||
|
||||
class BackgroundGradientType(object):
|
||||
|
@ -246,7 +251,7 @@ class ThemeXML(object):
|
|||
Add a transparent background.
|
||||
"""
|
||||
background = self.theme_xml.createElement(u'background')
|
||||
background.setAttribute(u'mode', u'transparent')
|
||||
background.setAttribute(u'type', u'transparent')
|
||||
self.theme.appendChild(background)
|
||||
|
||||
def add_background_solid(self, bkcolor):
|
||||
|
@ -487,25 +492,25 @@ class ThemeXML(object):
|
|||
return
|
||||
xml_iter = theme_xml.getiterator()
|
||||
for element in xml_iter:
|
||||
parent = element.getparent()
|
||||
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 element.getparent().tag == u'font':
|
||||
master = element.getparent().tag + u'_' + \
|
||||
element.getparent().attrib[u'type']
|
||||
if parent.tag == u'font':
|
||||
master = parent.tag + u'_' + parent.attrib[u'type']
|
||||
# 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 \
|
||||
element.tag.startswith(u'outline'):
|
||||
self._create_attr(u'font_main', element.tag,
|
||||
element.text)
|
||||
master = element.getparent().tag
|
||||
if element.getparent().tag == u'background':
|
||||
master = element.getparent().tag
|
||||
if element.getparent().attrib:
|
||||
for attr in element.getparent().attrib:
|
||||
self._create_attr(master, attr, \
|
||||
element.getparent().attrib[attr])
|
||||
master = parent.tag
|
||||
if parent.tag == u'background':
|
||||
master = parent.tag
|
||||
if master:
|
||||
self._create_attr(master, element.tag, element.text)
|
||||
if element.attrib:
|
||||
|
@ -599,9 +604,13 @@ class ThemeXML(object):
|
|||
self.background_start_color,
|
||||
self.background_end_color,
|
||||
self.background_direction)
|
||||
else:
|
||||
elif self.background_type == \
|
||||
BackgroundType.to_string(BackgroundType.Image):
|
||||
filename = os.path.split(self.background_filename)[1]
|
||||
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.font_main_color,
|
||||
self.font_main_size,
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -31,7 +31,7 @@ import logging
|
|||
|
||||
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__)
|
||||
|
||||
|
@ -46,122 +46,41 @@ class OpenLPToolbar(QtGui.QToolBar):
|
|||
"""
|
||||
QtGui.QToolBar.__init__(self, parent)
|
||||
# useful to be able to reuse button icons...
|
||||
self.icons = {}
|
||||
self.setIconSize(QtCore.QSize(20, 20))
|
||||
self.actions = {}
|
||||
log.debug(u'Init done for %s' % parent.__class__.__name__)
|
||||
|
||||
def addToolbarButton(self, title, icon, tooltip=None, slot=None,
|
||||
checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
|
||||
def addToolbarAction(self, name, **kwargs):
|
||||
"""
|
||||
A method to help developers easily add a button to the toolbar.
|
||||
|
||||
``title``
|
||||
The title of 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 ':/'.
|
||||
|
||||
``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
|
||||
A new QAction is created by calling ``create_action()``. The action is
|
||||
added to the toolbar and the toolbar is set as parent.
|
||||
For more details please look at openlp.core.lib.ui.create_action()
|
||||
"""
|
||||
if icon:
|
||||
actionIcon = build_icon(icon)
|
||||
if slot and not checkable:
|
||||
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
|
||||
action = create_widget_action(self, name, **kwargs)
|
||||
self.actions[name] = action
|
||||
return action
|
||||
|
||||
def addToolbarSeparator(self, handle):
|
||||
def addToolbarWidget(self, widget):
|
||||
"""
|
||||
Add a Separator bar to the toolbar and store it's Handle
|
||||
"""
|
||||
action = self.addSeparator()
|
||||
self.actions[handle] = action
|
||||
|
||||
def addToolbarWidget(self, handle, widget):
|
||||
"""
|
||||
Add a Widget to the toolbar and store it's Handle
|
||||
Add a widget and store it's handle under the widgets object name.
|
||||
"""
|
||||
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,
|
||||
and return that icon.
|
||||
Set the visibitity for a widget or a list of widgets.
|
||||
|
||||
``title``
|
||||
The title of the icon to search for.
|
||||
"""
|
||||
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()
|
||||
``widget``
|
||||
A list of string with widget object names.
|
||||
|
||||
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 #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -93,6 +93,7 @@ class UiStrings(object):
|
|||
self.New = translate('OpenLP.Ui', 'New')
|
||||
self.NewService = translate('OpenLP.Ui', 'New Service')
|
||||
self.NewTheme = translate('OpenLP.Ui', 'New Theme')
|
||||
self.NextTrack = translate('OpenLP.Ui', 'Next Track')
|
||||
self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
|
||||
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
|
||||
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
||||
|
@ -114,6 +115,8 @@ class UiStrings(object):
|
|||
'The abbreviated unit for seconds')
|
||||
self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
|
||||
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 '
|
||||
'to delete.')
|
||||
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)
|
||||
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``
|
||||
The category the action should be listed in the shortcut dialog. If you
|
||||
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
|
||||
``parent``
|
||||
A QtCore.QObject for the actions parent (required).
|
||||
|
||||
def checkable_action(parent, name, checked=None, category=None):
|
||||
"""
|
||||
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
|
||||
``name``
|
||||
A string which is set as object name (required).
|
||||
|
||||
``text``
|
||||
The text to display for this action
|
||||
A string for the action text.
|
||||
|
||||
``slot``
|
||||
The code to run when this action is triggered
|
||||
``icon``
|
||||
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``
|
||||
The action's 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.
|
||||
A QList<QKeySequence> (or a list of strings) which are set as shortcuts.
|
||||
|
||||
``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)
|
||||
if icon:
|
||||
action.setIcon(build_icon(icon))
|
||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot)
|
||||
if shortcuts is not None:
|
||||
action.setShortcuts(shortcuts)
|
||||
action.setShortcutContext(context)
|
||||
action = QtGui.QAction(parent)
|
||||
action.setObjectName(name)
|
||||
if kwargs.get(u'text'):
|
||||
action.setText(kwargs.pop(u'text'))
|
||||
if kwargs.get(u'icon'):
|
||||
action.setIcon(build_icon(kwargs.pop(u'icon')))
|
||||
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.add_action(action)
|
||||
base.addAction(action)
|
||||
action_list.add_action(action, unicode(kwargs.pop(u'category')))
|
||||
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
|
||||
|
||||
def context_menu(base, icon, text):
|
||||
|
@ -393,18 +398,6 @@ def context_menu(base, icon, text):
|
|||
action.setIcon(build_icon(icon))
|
||||
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):
|
||||
"""
|
||||
Adds a text autocompleter to a widget.
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -126,7 +126,8 @@ class Ui_AboutDialog(object):
|
|||
u'Tim "TRB143" Bentley (Fedora and Android)',
|
||||
u'Matthias "matthub" Hub (Mac OS X)',
|
||||
u'Stevan "ElderP" Pettit (Windows)',
|
||||
u'Raoul "superfly" Snyman (Ubuntu)']
|
||||
u'Raoul "superfly" Snyman (Ubuntu)',
|
||||
u'Garrett "floft" Wilson (Arch Linux)']
|
||||
translators = {
|
||||
u'af': [u'Johan "nuvolari" Mynhardt'],
|
||||
u'de': [u'Patrick "madmuffin" Br\xfcckner',
|
||||
|
@ -226,8 +227,8 @@ class Ui_AboutDialog(object):
|
|||
self.aboutNotebook.indexOf(self.creditsTab),
|
||||
translate('OpenLP.AboutForm', 'Credits'))
|
||||
copyright = unicode(translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2011 %s\n'
|
||||
'Portions copyright \xa9 2004-2011 %s')) % (u'Raoul Snyman',
|
||||
'Copyright \xa9 2004-2012 %s\n'
|
||||
'Portions copyright \xa9 2004-2012 %s')) % (u'Raoul Snyman',
|
||||
u'Tim Bentley, Jonathan Corwin, Michael Gorven, Gerald Britton, '
|
||||
u'Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin K\xf6hler, '
|
||||
u'Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias '
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -27,10 +27,13 @@
|
|||
"""
|
||||
The :mod:`advancedtab` provides an advanced settings facility.
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
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 import SlideLimits
|
||||
from openlp.core.utils import get_images_filter
|
||||
|
||||
class AdvancedTab(SettingsTab):
|
||||
|
@ -42,11 +45,23 @@ class AdvancedTab(SettingsTab):
|
|||
"""
|
||||
Initialise the settings tab
|
||||
"""
|
||||
advancedTranslated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
self.default_image = u':/graphics/openlp-splash-screen.png'
|
||||
self.default_color = u'#ffffff'
|
||||
self.displayChanged = False
|
||||
# 7 stands for now, 0 to 6 is Monday to Sunday.
|
||||
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'
|
||||
SettingsTab.__init__(self, parent, u'Advanced', advancedTranslated)
|
||||
advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
SettingsTab.__init__(self, parent, u'Advanced', advanced_translated)
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
|
@ -83,7 +98,61 @@ class AdvancedTab(SettingsTab):
|
|||
u'enableAutoCloseCheckBox')
|
||||
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
||||
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()
|
||||
# Default Image
|
||||
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
|
||||
self.defaultImageLayout = QtGui.QFormLayout(self.defaultImageGroupBox)
|
||||
|
@ -114,7 +183,8 @@ class AdvancedTab(SettingsTab):
|
|||
self.defaultImageLayout.addRow(self.defaultFileLabel,
|
||||
self.defaultFileLayout)
|
||||
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.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
||||
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
||||
|
@ -122,14 +192,76 @@ class AdvancedTab(SettingsTab):
|
|||
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
||||
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
||||
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.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.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
|
||||
QtCore.QObject.connect(self.defaultBrowseButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
|
||||
QtCore.QObject.connect(self.defaultRevertButton,
|
||||
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):
|
||||
"""
|
||||
|
@ -151,6 +283,40 @@ class AdvancedTab(SettingsTab):
|
|||
'Expand new service items on creation'))
|
||||
self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||
'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',
|
||||
'Mouse Cursor'))
|
||||
self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||
|
@ -167,6 +333,29 @@ class AdvancedTab(SettingsTab):
|
|||
'Browse for an image file to display.'))
|
||||
self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||
'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):
|
||||
"""
|
||||
|
@ -198,14 +387,39 @@ class AdvancedTab(SettingsTab):
|
|||
QtCore.QVariant(True)).toBool())
|
||||
self.hideMouseCheckBox.setChecked(
|
||||
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()
|
||||
self.defaultFileEdit.setText(settings.value(u'default image',
|
||||
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
|
||||
.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()
|
||||
self.defaultColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.default_color)
|
||||
u'background-color: %s' % self.defaultColor)
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
|
@ -213,6 +427,21 @@ class AdvancedTab(SettingsTab):
|
|||
"""
|
||||
settings = QtCore.QSettings()
|
||||
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',
|
||||
QtCore.QVariant(self.recentSpinBox.value()))
|
||||
settings.setValue(u'save current plugin',
|
||||
|
@ -227,17 +456,67 @@ class AdvancedTab(SettingsTab):
|
|||
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
|
||||
settings.setValue(u'hide mouse',
|
||||
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'slide limits', QtCore.QVariant(self.slide_limits))
|
||||
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):
|
||||
new_color = QtGui.QColorDialog.getColor(
|
||||
QtGui.QColor(self.default_color), self)
|
||||
QtGui.QColor(self.defaultColor), self)
|
||||
if new_color.isValid():
|
||||
self.default_color = new_color.name()
|
||||
self.defaultColor = new_color.name()
|
||||
self.defaultColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.default_color)
|
||||
u'background-color: %s' % self.defaultColor)
|
||||
|
||||
def onDefaultBrowseButtonPressed(self):
|
||||
file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(),
|
||||
|
@ -252,3 +531,21 @@ class AdvancedTab(SettingsTab):
|
|||
def onDefaultRevertButtonPressed(self):
|
||||
self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
|
||||
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 #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -32,7 +32,7 @@ import platform
|
|||
import sqlalchemy
|
||||
import BeautifulSoup
|
||||
from lxml import etree
|
||||
from PyQt4 import Qt, QtCore, QtGui
|
||||
from PyQt4 import Qt, QtCore, QtGui, QtWebKit
|
||||
|
||||
try:
|
||||
from PyQt4.phonon import Phonon
|
||||
|
@ -77,6 +77,11 @@ try:
|
|||
UNO_VERSION = node.getByName(u'ooSetupVersion')
|
||||
except ImportError:
|
||||
UNO_VERSION = u'-'
|
||||
try:
|
||||
WEBKIT_VERSION = QtWebKit.qWebKitVersion()
|
||||
except AttributeError:
|
||||
WEBKIT_VERSION = u'-'
|
||||
|
||||
|
||||
from openlp.core.lib import translate, SettingsManager
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
@ -111,6 +116,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
|||
u'Qt4: %s\n' % Qt.qVersion() + \
|
||||
u'Phonon: %s\n' % PHONON_VERSION + \
|
||||
u'PyQt4: %s\n' % Qt.PYQT_VERSION_STR + \
|
||||
u'QtWebkit: %s\n' % WEBKIT_VERSION + \
|
||||
u'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \
|
||||
u'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \
|
||||
u'BeautifulSoup: %s\n' % BeautifulSoup.__version__ + \
|
||||
|
@ -144,7 +150,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
|||
translate('OpenLP.ExceptionForm',
|
||||
'Text files (*.txt *.log *.text)'))
|
||||
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(
|
||||
filename))
|
||||
report_text = report_text % self._createReport()
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -41,7 +41,7 @@ class Ui_FileRenameDialog(object):
|
|||
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
|
||||
self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
|
||||
self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
|
||||
QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self))
|
||||
QtCore.QRegExp(r'[^/\\?*|<>\[\]":+%]+'), self))
|
||||
self.fileNameEdit.setObjectName(u'fileNameEdit')
|
||||
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
|
||||
self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -29,6 +29,7 @@ import io
|
|||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
import urllib2
|
||||
from tempfile import gettempdir
|
||||
|
@ -43,6 +44,29 @@ from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
|
|||
|
||||
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):
|
||||
"""
|
||||
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.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||
self.biblesTreeWidget.expandAll()
|
||||
themes = self.config.get(u'themes', u'files')
|
||||
themes = themes.split(u',')
|
||||
for theme in themes:
|
||||
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)
|
||||
# Download the theme screenshots.
|
||||
self.themeScreenshotThread = ThemeScreenshotThread(self)
|
||||
self.themeScreenshotThread.start()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def nextId(self):
|
||||
|
@ -156,6 +168,14 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||
return -1
|
||||
elif self.currentId() == FirstTimePage.NoInternet:
|
||||
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:
|
||||
return self.currentId() + 1
|
||||
|
||||
|
@ -264,6 +284,23 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||
if self.downloadCanceled:
|
||||
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):
|
||||
site = urllib.urlopen(url)
|
||||
meta = site.info()
|
||||
|
@ -421,6 +458,8 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||
if self.displayComboBox.currentIndex() != -1:
|
||||
QtCore.QSettings().setValue(u'General/monitor',
|
||||
QtCore.QVariant(self.displayComboBox.currentIndex()))
|
||||
self.screens.set_current_display(
|
||||
self.displayComboBox.currentIndex())
|
||||
# Set Global Theme
|
||||
if self.themeComboBox.currentIndex() != -1:
|
||||
QtCore.QSettings().setValue(u'themes/global theme',
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.utils import LanguageManager
|
||||
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
|
||||
|
||||
|
@ -55,8 +56,7 @@ class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
|
|||
LanguageManager.set_language(False, False)
|
||||
else:
|
||||
LanguageManager.auto_language = False
|
||||
action = QtGui.QAction(None)
|
||||
action.setObjectName(unicode(self.languageComboBox.currentText()))
|
||||
action = create_action(None, self.languageComboBox.currentText())
|
||||
LanguageManager.set_language(action, False)
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -53,63 +53,64 @@ class GeneralTab(SettingsTab):
|
|||
"""
|
||||
self.setObjectName(u'GeneralTab')
|
||||
SettingsTab.setupUi(self)
|
||||
self.tabLayout.setStretch(1, 1)
|
||||
# Monitors
|
||||
self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.monitorGroupBox.setObjectName(u'monitorGroupBox')
|
||||
self.monitorLayout = QtGui.QFormLayout(self.monitorGroupBox)
|
||||
self.monitorLayout = QtGui.QGridLayout(self.monitorGroupBox)
|
||||
self.monitorLayout.setObjectName(u'monitorLayout')
|
||||
self.monitorLabel = QtGui.QLabel(self.monitorGroupBox)
|
||||
self.monitorLabel.setObjectName(u'monitorLabel')
|
||||
self.monitorLayout.addRow(self.monitorLabel)
|
||||
self.monitorRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
|
||||
self.monitorRadioButton.setObjectName(u'monitorRadioButton')
|
||||
self.monitorLayout.addWidget(self.monitorRadioButton, 0, 0, 1, 5)
|
||||
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
|
||||
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.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.startupGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
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.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)
|
||||
# CCLI Details
|
||||
self.ccliGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.ccliGroupBox.setObjectName(u'ccliGroupBox')
|
||||
self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox)
|
||||
self.ccliLayout.setObjectName(u'ccliLayout')
|
||||
|
@ -130,59 +131,64 @@ class GeneralTab(SettingsTab):
|
|||
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
|
||||
self.passwordEdit.setObjectName(u'passwordEdit')
|
||||
self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit)
|
||||
self.rightLayout.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)
|
||||
self.leftLayout.addWidget(self.ccliGroupBox)
|
||||
# Background audio
|
||||
self.audioGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.audioGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.audioGroupBox.setObjectName(u'audioGroupBox')
|
||||
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
|
||||
self.audioLayout.setObjectName(u'audioLayout')
|
||||
self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
|
||||
self.startPausedCheckBox.setObjectName(u'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()
|
||||
# Signals and slots
|
||||
QtCore.QObject.connect(self.overrideCheckBox,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled)
|
||||
QtCore.QObject.connect(self.overrideRadioButton,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideRadioButtonPressed)
|
||||
QtCore.QObject.connect(self.customHeightValueEdit,
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged)
|
||||
QtCore.QObject.connect(self.customWidthValueEdit,
|
||||
|
@ -209,7 +215,7 @@ class GeneralTab(SettingsTab):
|
|||
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
|
||||
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
|
||||
'Monitors'))
|
||||
self.monitorLabel.setText(translate('OpenLP.GeneralTab',
|
||||
self.monitorRadioButton.setText(translate('OpenLP.GeneralTab',
|
||||
'Select monitor for output display:'))
|
||||
self.displayOnMonitorCheck.setText(
|
||||
translate('OpenLP.GeneralTab', 'Display if a single screen'))
|
||||
|
@ -231,8 +237,6 @@ class GeneralTab(SettingsTab):
|
|||
'Unblank display when adding new live item'))
|
||||
self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab',
|
||||
'Automatically preview next item in service'))
|
||||
self.enableLoopCheckBox.setText(translate('OpenLP.GeneralTab',
|
||||
'Enable slide wrap-around'))
|
||||
self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
|
||||
'Timed slide interval:'))
|
||||
self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
|
||||
|
@ -244,10 +248,8 @@ class GeneralTab(SettingsTab):
|
|||
self.passwordLabel.setText(
|
||||
translate('OpenLP.GeneralTab', 'SongSelect password:'))
|
||||
# Moved from display tab
|
||||
self.displayGroupBox.setTitle(
|
||||
translate('OpenLP.GeneralTab', 'Display Position'))
|
||||
self.overrideCheckBox.setText(translate('OpenLP.GeneralTab',
|
||||
'Override display position'))
|
||||
self.overrideRadioButton.setText(translate('OpenLP.GeneralTab',
|
||||
'Override display position:'))
|
||||
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
|
||||
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
|
||||
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
|
||||
|
@ -256,6 +258,8 @@ class GeneralTab(SettingsTab):
|
|||
translate('OpenLP.GeneralTab', 'Background Audio'))
|
||||
self.startPausedCheckBox.setText(
|
||||
translate('OpenLP.GeneralTab', 'Start background audio paused'))
|
||||
self.repeatListCheckBox.setText(
|
||||
translate('OpenLP.GeneralTab', 'Repeat track list'))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
|
@ -289,11 +293,12 @@ class GeneralTab(SettingsTab):
|
|||
QtCore.QVariant(True)).toBool())
|
||||
self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview',
|
||||
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',
|
||||
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())
|
||||
self.customXValueEdit.setValue(settings.value(u'x position',
|
||||
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])
|
||||
self.startPausedCheckBox.setChecked(settings.value(
|
||||
u'audio start paused', QtCore.QVariant(True)).toBool())
|
||||
self.repeatListCheckBox.setChecked(settings.value(
|
||||
u'audio repeat list', QtCore.QVariant(False)).toBool())
|
||||
settings.endGroup()
|
||||
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||
self.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked())
|
||||
self.displayOnMonitorCheck.setDisabled(
|
||||
self.overrideRadioButton.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
|
||||
settings.beginGroup(self.settingsSection)
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
|
@ -336,8 +349,6 @@ class GeneralTab(SettingsTab):
|
|||
QtCore.QVariant(self.autoUnblankCheckBox.isChecked()))
|
||||
settings.setValue(u'auto preview',
|
||||
QtCore.QVariant(self.autoPreviewCheckBox.isChecked()))
|
||||
settings.setValue(u'enable slide loop',
|
||||
QtCore.QVariant(self.enableLoopCheckBox.isChecked()))
|
||||
settings.setValue(u'loop delay',
|
||||
QtCore.QVariant(self.timeoutSpinBox.value()))
|
||||
settings.setValue(u'ccli number',
|
||||
|
@ -355,9 +366,11 @@ class GeneralTab(SettingsTab):
|
|||
settings.setValue(u'width',
|
||||
QtCore.QVariant(self.customWidthValueEdit.value()))
|
||||
settings.setValue(u'override position',
|
||||
QtCore.QVariant(self.overrideCheckBox.isChecked()))
|
||||
QtCore.QVariant(self.overrideRadioButton.isChecked()))
|
||||
settings.setValue(u'audio start paused',
|
||||
QtCore.QVariant(self.startPausedCheckBox.isChecked()))
|
||||
settings.setValue(u'audio repeat list',
|
||||
QtCore.QVariant(self.repeatListCheckBox.isChecked()))
|
||||
settings.endGroup()
|
||||
# On save update the screens as well
|
||||
self.postSetUp(True)
|
||||
|
@ -379,7 +392,7 @@ class GeneralTab(SettingsTab):
|
|||
self.customYValueEdit.value(),
|
||||
self.customWidthValueEdit.value(),
|
||||
self.customHeightValueEdit.value())
|
||||
if self.overrideCheckBox.isChecked():
|
||||
if self.overrideRadioButton.isChecked():
|
||||
self.screens.set_override_display()
|
||||
else:
|
||||
self.screens.reset_current_display()
|
||||
|
@ -387,13 +400,15 @@ class GeneralTab(SettingsTab):
|
|||
Receiver.send_message(u'config_screen_changed')
|
||||
self.display_changed = False
|
||||
|
||||
def onOverrideCheckBoxToggled(self, checked):
|
||||
def onOverrideRadioButtonPressed(self, checked):
|
||||
"""
|
||||
Toggle screen state depending on check box state.
|
||||
|
||||
``checked``
|
||||
The state of the check box (boolean).
|
||||
"""
|
||||
self.monitorComboBox.setDisabled(checked)
|
||||
self.displayOnMonitorCheck.setDisabled(checked)
|
||||
self.customXValueEdit.setEnabled(checked)
|
||||
self.customYValueEdit.setEnabled(checked)
|
||||
self.customHeightValueEdit.setEnabled(checked)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -28,13 +28,16 @@
|
|||
The :mod:`maindisplay` module provides the functionality to display screens
|
||||
and play multimedia within OpenLP.
|
||||
"""
|
||||
import cgi
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
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
|
||||
|
||||
|
@ -60,6 +63,11 @@ class Display(QtGui.QGraphicsView):
|
|||
self.controller = controller
|
||||
self.screen = {}
|
||||
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())
|
||||
|
||||
def setup(self):
|
||||
|
@ -74,6 +82,10 @@ class Display(QtGui.QGraphicsView):
|
|||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.webView.settings().setAttribute(
|
||||
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.frame = self.page.mainFrame()
|
||||
if self.isLive and log.getEffectiveLevel() == logging.DEBUG:
|
||||
|
@ -120,10 +132,19 @@ class MainDisplay(Display):
|
|||
self.audioPlayer = None
|
||||
self.firstTime = True
|
||||
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||
QtCore.Qt.WindowStaysOnTopHint |
|
||||
QtCore.Qt.X11BypassWindowManagerHint)
|
||||
windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | \
|
||||
QtCore.Qt.WindowStaysOnTopHint
|
||||
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.setTransparency(False)
|
||||
if self.isLive:
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay)
|
||||
|
@ -134,6 +155,14 @@ class MainDisplay(Display):
|
|||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
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):
|
||||
"""
|
||||
We may need to rebuild the CSS on the live display.
|
||||
|
@ -222,16 +251,17 @@ class MainDisplay(Display):
|
|||
The text to be displayed.
|
||||
"""
|
||||
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 \
|
||||
not self.isVisible():
|
||||
shrink = True
|
||||
js = u'show_alert("%s", "%s")' % (
|
||||
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'),
|
||||
u'top')
|
||||
js = u'show_alert("%s", "%s")' % (text_prepared, u'top')
|
||||
else:
|
||||
shrink = False
|
||||
js = u'show_alert("%s", "")' % (
|
||||
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||
js = u'show_alert("%s", "")' % text_prepared
|
||||
height = self.frame.evaluateJavaScript(js)
|
||||
if shrink:
|
||||
if text:
|
||||
|
@ -332,13 +362,7 @@ class MainDisplay(Display):
|
|||
self.setVisible(True)
|
||||
else:
|
||||
self.setVisible(True)
|
||||
preview = QtGui.QPixmap(self.screen[u'size'].width(),
|
||||
self.screen[u'size'].height())
|
||||
painter = QtGui.QPainter(preview)
|
||||
painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||
self.frame.render(painter)
|
||||
painter.end()
|
||||
return preview
|
||||
return QtGui.QPixmap.grabWidget(self)
|
||||
|
||||
def buildHtml(self, serviceItem, image=None):
|
||||
"""
|
||||
|
@ -364,6 +388,8 @@ class MainDisplay(Display):
|
|||
# replace the background
|
||||
background = self.imageManager. \
|
||||
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:
|
||||
self.serviceItem.bg_image_bytes = self.imageManager. \
|
||||
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
|
||||
"""
|
||||
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:
|
||||
self.frame.evaluateJavaScript(u'show_blank("desktop");')
|
||||
self.setVisible(False)
|
||||
|
@ -422,6 +453,11 @@ class MainDisplay(Display):
|
|||
Make the stored images None to release memory.
|
||||
"""
|
||||
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");')
|
||||
if self.isHidden():
|
||||
self.setVisible(True)
|
||||
|
@ -459,11 +495,15 @@ class AudioPlayer(QtCore.QObject):
|
|||
QtCore.QObject.__init__(self, parent)
|
||||
self.currentIndex = -1
|
||||
self.playlist = []
|
||||
self.repeat = False
|
||||
self.mediaObject = Phonon.MediaObject()
|
||||
self.mediaObject.setTickInterval(100)
|
||||
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
|
||||
Phonon.createPath(self.mediaObject, self.audioObject)
|
||||
QtCore.QObject.connect(self.mediaObject,
|
||||
QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
|
||||
QtCore.QObject.connect(self.mediaObject,
|
||||
QtCore.SIGNAL(u'finished()'), self.onFinished)
|
||||
|
||||
def __del__(self):
|
||||
"""
|
||||
|
@ -482,6 +522,14 @@ class AudioPlayer(QtCore.QObject):
|
|||
if len(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):
|
||||
slider.setAudioOutput(self.audioObject)
|
||||
|
||||
|
@ -529,3 +577,27 @@ class AudioPlayer(QtCore.QObject):
|
|||
for filename in filenames:
|
||||
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 #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui
|
|||
|
||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
||||
PluginManager, Receiver, translate, ImageManager, PluginStatus
|
||||
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||
icon_action, shortcut_action
|
||||
from openlp.core.lib.ui import UiStrings, create_action
|
||||
from openlp.core.lib import SlideLimits
|
||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
||||
ThemeManager, SlideController, PluginForm, MediaDockManager, \
|
||||
ShortcutListForm, FormattingTagForm
|
||||
|
@ -178,75 +178,78 @@ class Ui_MainWindow(object):
|
|||
action_list = ActionList.get_instance()
|
||||
action_list.add_category(unicode(UiStrings().File),
|
||||
CategoryOrder.standardMenu)
|
||||
self.fileNewItem = shortcut_action(mainWindow, u'fileNewItem',
|
||||
[QtGui.QKeySequence(u'Ctrl+N')],
|
||||
self.serviceManagerContents.onNewServiceClicked,
|
||||
u':/general/general_new.png', category=unicode(UiStrings().File))
|
||||
self.fileOpenItem = shortcut_action(mainWindow, u'fileOpenItem',
|
||||
[QtGui.QKeySequence(u'Ctrl+O')],
|
||||
self.serviceManagerContents.onLoadServiceClicked,
|
||||
u':/general/general_open.png', category=unicode(UiStrings().File))
|
||||
self.fileSaveItem = shortcut_action(mainWindow, u'fileSaveItem',
|
||||
[QtGui.QKeySequence(u'Ctrl+S')],
|
||||
self.serviceManagerContents.saveFile,
|
||||
u':/general/general_save.png', category=unicode(UiStrings().File))
|
||||
self.fileSaveAsItem = shortcut_action(mainWindow, u'fileSaveAsItem',
|
||||
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||
self.serviceManagerContents.saveFileAs,
|
||||
category=unicode(UiStrings().File))
|
||||
self.printServiceOrderItem = shortcut_action(mainWindow,
|
||||
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
|
||||
self.serviceManagerContents.printServiceOrder,
|
||||
category=unicode(UiStrings().File))
|
||||
self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
|
||||
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
|
||||
u':/system/system_exit.png', category=unicode(UiStrings().File))
|
||||
self.fileNewItem = create_action(mainWindow, u'fileNewItem',
|
||||
icon=u':/general/general_new.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.onNewServiceClicked)
|
||||
self.fileOpenItem = create_action(mainWindow, u'fileOpenItem',
|
||||
icon=u':/general/general_open.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.onLoadServiceClicked)
|
||||
self.fileSaveItem = create_action(mainWindow, u'fileSaveItem',
|
||||
icon=u':/general/general_save.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.saveFile)
|
||||
self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.saveFileAs)
|
||||
self.printServiceOrderItem = create_action(mainWindow,
|
||||
u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
|
||||
category=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),
|
||||
CategoryOrder.standardMenu)
|
||||
self.importThemeItem = base_action(
|
||||
mainWindow, u'importThemeItem', unicode(UiStrings().Import))
|
||||
self.importLanguageItem = base_action(
|
||||
mainWindow, u'importLanguageItem')#, unicode(UiStrings().Import))
|
||||
self.importThemeItem = create_action(mainWindow,
|
||||
u'importThemeItem', category=UiStrings().Import)
|
||||
self.importLanguageItem = create_action(mainWindow,
|
||||
u'importLanguageItem')#, category=UiStrings().Import)
|
||||
action_list.add_category(unicode(UiStrings().Export),
|
||||
CategoryOrder.standardMenu)
|
||||
self.exportThemeItem = base_action(
|
||||
mainWindow, u'exportThemeItem', unicode(UiStrings().Export))
|
||||
self.exportLanguageItem = base_action(
|
||||
mainWindow, u'exportLanguageItem')#, unicode(UiStrings().Export))
|
||||
self.exportThemeItem = create_action(mainWindow,
|
||||
u'exportThemeItem', category=UiStrings().Export)
|
||||
self.exportLanguageItem = create_action(mainWindow,
|
||||
u'exportLanguageItem')#, category=UiStrings().Export)
|
||||
action_list.add_category(unicode(UiStrings().View),
|
||||
CategoryOrder.standardMenu)
|
||||
self.viewMediaManagerItem = shortcut_action(mainWindow,
|
||||
u'viewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
|
||||
self.toggleMediaManager, u':/system/system_mediamanager.png',
|
||||
self.mediaManagerDock.isVisible(), unicode(UiStrings().View))
|
||||
self.viewThemeManagerItem = shortcut_action(mainWindow,
|
||||
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
||||
self.toggleThemeManager, u':/system/system_thememanager.png',
|
||||
self.themeManagerDock.isVisible(), unicode(UiStrings().View))
|
||||
self.viewServiceManagerItem = shortcut_action(mainWindow,
|
||||
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
||||
self.toggleServiceManager, u':/system/system_servicemanager.png',
|
||||
self.serviceManagerDock.isVisible(), unicode(UiStrings().View))
|
||||
self.viewPreviewPanel = shortcut_action(mainWindow,
|
||||
u'viewPreviewPanel', [QtGui.QKeySequence(u'F11')],
|
||||
self.setPreviewPanelVisibility, checked=previewVisible,
|
||||
category=unicode(UiStrings().View))
|
||||
self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
|
||||
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
|
||||
checked=liveVisible, category=unicode(UiStrings().View))
|
||||
self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
|
||||
None, self.setLockPanel,
|
||||
checked=panelLocked, category=None)
|
||||
self.viewMediaManagerItem = create_action(mainWindow,
|
||||
u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
|
||||
icon=u':/system/system_mediamanager.png',
|
||||
checked=self.mediaManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleMediaManager)
|
||||
self.viewThemeManagerItem = create_action(mainWindow,
|
||||
u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
|
||||
icon=u':/system/system_thememanager.png',
|
||||
checked=self.themeManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleThemeManager)
|
||||
self.viewServiceManagerItem = create_action(mainWindow,
|
||||
u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
|
||||
icon=u':/system/system_servicemanager.png',
|
||||
checked=self.serviceManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleServiceManager)
|
||||
self.viewPreviewPanel = create_action(mainWindow, u'viewPreviewPanel',
|
||||
shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
|
||||
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
|
||||
self.viewLivePanel = create_action(mainWindow, u'viewLivePanel',
|
||||
shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
|
||||
category=UiStrings().View, triggers=self.setLivePanelVisibility)
|
||||
self.lockPanel = create_action(mainWindow, u'lockPanel',
|
||||
checked=panelLocked, triggers=self.setLockPanel)
|
||||
action_list.add_category(unicode(UiStrings().ViewMode),
|
||||
CategoryOrder.standardMenu)
|
||||
self.modeDefaultItem = checkable_action(
|
||||
mainWindow, u'modeDefaultItem',
|
||||
category=unicode(UiStrings().ViewMode))
|
||||
self.modeSetupItem = checkable_action(
|
||||
mainWindow, u'modeSetupItem',
|
||||
category=unicode(UiStrings().ViewMode))
|
||||
self.modeLiveItem = checkable_action(
|
||||
mainWindow, u'modeLiveItem', True, unicode(UiStrings().ViewMode))
|
||||
self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem',
|
||||
checked=False, category=UiStrings().ViewMode)
|
||||
self.modeSetupItem = create_action(mainWindow, u'modeSetupItem',
|
||||
checked=False, category=UiStrings().ViewMode)
|
||||
self.modeLiveItem = create_action(mainWindow, u'modeLiveItem',
|
||||
checked=True, category=UiStrings().ViewMode)
|
||||
self.modeGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.modeGroup.addAction(self.modeDefaultItem)
|
||||
self.modeGroup.addAction(self.modeSetupItem)
|
||||
|
@ -254,25 +257,27 @@ class Ui_MainWindow(object):
|
|||
self.modeDefaultItem.setChecked(True)
|
||||
action_list.add_category(unicode(UiStrings().Tools),
|
||||
CategoryOrder.standardMenu)
|
||||
self.toolsAddToolItem = icon_action(mainWindow, u'toolsAddToolItem',
|
||||
u':/tools/tools_add.png', category=unicode(UiStrings().Tools))
|
||||
self.toolsOpenDataFolder = icon_action(mainWindow,
|
||||
u'toolsOpenDataFolder', u':/general/general_open.png',
|
||||
category=unicode(UiStrings().Tools))
|
||||
self.toolsFirstTimeWizard = icon_action(mainWindow,
|
||||
u'toolsFirstTimeWizard', u':/general/general_revert.png',
|
||||
category=unicode(UiStrings().Tools))
|
||||
self.updateThemeImages = base_action(mainWindow,
|
||||
u'updateThemeImages', category=unicode(UiStrings().Tools))
|
||||
self.toolsAddToolItem = create_action(mainWindow,
|
||||
u'toolsAddToolItem', icon=u':/tools/tools_add.png',
|
||||
category=UiStrings().Tools)
|
||||
self.toolsOpenDataFolder = create_action(mainWindow,
|
||||
u'toolsOpenDataFolder', icon=u':/general/general_open.png',
|
||||
category=UiStrings().Tools)
|
||||
self.toolsFirstTimeWizard = create_action(mainWindow,
|
||||
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
|
||||
category=UiStrings().Tools)
|
||||
self.updateThemeImages = create_action(mainWindow,
|
||||
u'updateThemeImages', category=UiStrings().Tools)
|
||||
action_list.add_category(unicode(UiStrings().Settings),
|
||||
CategoryOrder.standardMenu)
|
||||
self.settingsPluginListItem = shortcut_action(mainWindow,
|
||||
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
|
||||
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
|
||||
category=unicode(UiStrings().Settings))
|
||||
self.settingsPluginListItem = create_action(mainWindow,
|
||||
u'settingsPluginListItem',
|
||||
icon=u':/system/settings_plugin_list.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
|
||||
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
|
||||
# i18n Language Items
|
||||
self.autoLanguageItem = checkable_action(mainWindow,
|
||||
u'autoLanguageItem', LanguageManager.auto_language)
|
||||
self.autoLanguageItem = create_action(mainWindow, u'autoLanguageItem',
|
||||
checked=LanguageManager.auto_language)
|
||||
self.languageGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.languageGroup.setExclusive(True)
|
||||
self.languageGroup.setObjectName(u'languageGroup')
|
||||
|
@ -280,44 +285,43 @@ class Ui_MainWindow(object):
|
|||
qmList = LanguageManager.get_qm_list()
|
||||
savedLanguage = LanguageManager.get_language()
|
||||
for key in sorted(qmList.keys()):
|
||||
languageItem = checkable_action(
|
||||
mainWindow, key, qmList[key] == savedLanguage)
|
||||
languageItem = create_action(mainWindow, key,
|
||||
checked=qmList[key] == savedLanguage)
|
||||
add_actions(self.languageGroup, [languageItem])
|
||||
self.settingsShortcutsItem = icon_action(mainWindow,
|
||||
self.settingsShortcutsItem = create_action(mainWindow,
|
||||
u'settingsShortcutsItem',
|
||||
u':/system/system_configure_shortcuts.png',
|
||||
category=unicode(UiStrings().Settings))
|
||||
icon=u':/system/system_configure_shortcuts.png',
|
||||
category=UiStrings().Settings)
|
||||
# Formatting Tags were also known as display tags.
|
||||
self.formattingTagItem = icon_action(mainWindow,
|
||||
u'displayTagItem', u':/system/tag_editor.png',
|
||||
category=unicode(UiStrings().Settings))
|
||||
self.settingsConfigureItem = icon_action(mainWindow,
|
||||
u'settingsConfigureItem', u':/system/system_settings.png',
|
||||
category=unicode(UiStrings().Settings))
|
||||
self.settingsImportItem = base_action(mainWindow,
|
||||
u'settingsImportItem', category=unicode(UiStrings().Settings))
|
||||
self.settingsExportItem = base_action(mainWindow,
|
||||
u'settingsExportItem', category=unicode(UiStrings().Settings))
|
||||
self.formattingTagItem = create_action(mainWindow,
|
||||
u'displayTagItem', icon=u':/system/tag_editor.png',
|
||||
category=UiStrings().Settings)
|
||||
self.settingsConfigureItem = create_action(mainWindow,
|
||||
u'settingsConfigureItem', icon=u':/system/system_settings.png',
|
||||
category=UiStrings().Settings)
|
||||
self.settingsImportItem = create_action(mainWindow,
|
||||
u'settingsImportItem', category=UiStrings().Settings)
|
||||
self.settingsExportItem = create_action(mainWindow,
|
||||
u'settingsExportItem', category=UiStrings().Settings)
|
||||
action_list.add_category(unicode(UiStrings().Help),
|
||||
CategoryOrder.standardMenu)
|
||||
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
|
||||
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
|
||||
u':/system/system_about.png', category=unicode(UiStrings().Help))
|
||||
self.aboutItem = create_action(mainWindow, u'aboutItem',
|
||||
icon=u':/system/system_about.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
||||
category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
||||
if os.name == u'nt':
|
||||
self.localHelpFile = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
||||
self.offlineHelpItem = shortcut_action(
|
||||
mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
|
||||
self.onOfflineHelpClicked,
|
||||
u':/system/system_help_contents.png',
|
||||
category=unicode(UiStrings().Help))
|
||||
self.onlineHelpItem = shortcut_action(
|
||||
mainWindow, u'onlineHelpItem',
|
||||
[QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
|
||||
u':/system/system_online_help.png',
|
||||
category=unicode(UiStrings().Help))
|
||||
self.webSiteItem = base_action(
|
||||
mainWindow, u'webSiteItem', category=unicode(UiStrings().Help))
|
||||
self.offlineHelpItem = create_action(mainWindow, u'offlineHelpItem',
|
||||
icon=u':/system/system_help_contents.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'F1')],
|
||||
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
|
||||
self.onlineHelpItem = create_action(mainWindow, u'onlineHelpItem',
|
||||
icon=u':/system/system_online_help.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
|
||||
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
|
||||
self.webSiteItem = create_action(mainWindow,
|
||||
u'webSiteItem', category=UiStrings().Help)
|
||||
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
|
||||
self.importThemeItem, self.importLanguageItem))
|
||||
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
|
||||
|
@ -1059,7 +1063,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||
export_settings.endGroup()
|
||||
# Write all the sections and keys.
|
||||
for section_key in keys:
|
||||
section, key = section_key.split(u'/')
|
||||
key_value = settings.value(section_key)
|
||||
export_settings.setValue(section_key, key_value)
|
||||
export_settings.sync()
|
||||
|
@ -1307,6 +1310,19 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||
Load the main window settings.
|
||||
"""
|
||||
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()
|
||||
# Remove obsolete entries.
|
||||
settings.remove(u'custom slide')
|
||||
|
@ -1365,27 +1381,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||
recentFileCount = QtCore.QSettings().value(
|
||||
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
||||
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
||||
if QtCore.QFile.exists(recentFile)]
|
||||
if os.path.isfile(unicode(recentFile))]
|
||||
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
||||
self.recentFilesMenu.clear()
|
||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||
log.debug('Recent file name: %s', filename)
|
||||
action = base_action(self, u'')
|
||||
action.setText(u'&%d %s' %
|
||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
||||
action.setData(QtCore.QVariant(filename))
|
||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
||||
self.serviceManagerContents.onRecentServiceClicked)
|
||||
action = create_action(self, u'',
|
||||
text=u'&%d %s' % (fileId + 1, os.path.splitext(os.path.basename(
|
||||
unicode(filename)))[0]), data=filename,
|
||||
triggers=self.serviceManagerContents.onRecentServiceClicked)
|
||||
self.recentFilesMenu.addAction(action)
|
||||
clearRecentFilesAction = base_action(self, u'')
|
||||
clearRecentFilesAction.setText(
|
||||
translate('OpenLP.MainWindow', 'Clear List',
|
||||
'Clear List of recent files'))
|
||||
clearRecentFilesAction.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Clear the list of recent files.'))
|
||||
clearRecentFilesAction = create_action(self, u'',
|
||||
text=translate('OpenLP.MainWindow', 'Clear List',
|
||||
'Clear List of recent files'),
|
||||
statustip=translate('OpenLP.MainWindow',
|
||||
'Clear the list of recent files.'),
|
||||
enabled=not self.recentFiles.isEmpty(),
|
||||
triggers=self.recentFiles.clear)
|
||||
add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
|
||||
self.connect(clearRecentFilesAction, QtCore.SIGNAL(u'triggered()'),
|
||||
self.recentFiles.clear)
|
||||
clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
|
||||
|
||||
def addRecentFile(self, filename):
|
||||
|
|
|
@ -24,17 +24,21 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class MediaState(object):
|
||||
"""
|
||||
An enumeration for possible States of the Media Player (copied partially
|
||||
from Phonon::State)
|
||||
An enumeration for possible States of the Media Player
|
||||
"""
|
||||
Loading = 0
|
||||
Stopped = 1
|
||||
Off = 0
|
||||
Loaded = 1
|
||||
Playing = 2
|
||||
Paused = 4
|
||||
Off = 6
|
||||
Paused = 3
|
||||
Stopped = 4
|
||||
|
||||
|
||||
class MediaType(object):
|
||||
|
@ -62,4 +66,48 @@ class MediaInfo(object):
|
|||
end_time = 0
|
||||
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
|
||||
|
|
|
@ -32,7 +32,8 @@ from PyQt4 import QtCore, QtGui
|
|||
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
||||
from openlp.core.lib.mediaplayer import MediaPlayer
|
||||
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
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -47,7 +48,6 @@ class MediaController(object):
|
|||
self.parent = parent
|
||||
self.mediaPlayers = {}
|
||||
self.controller = []
|
||||
self.overridenPlayer = ''
|
||||
self.curDisplayMediaPlayer = {}
|
||||
# Timer for video state
|
||||
self.timer = QtCore.QTimer()
|
||||
|
@ -58,23 +58,21 @@ class MediaController(object):
|
|||
QtCore.QObject.connect(self.timer,
|
||||
QtCore.SIGNAL("timeout()"), self.video_state)
|
||||
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.SIGNAL(u'media_playback_pause'), self.video_pause)
|
||||
QtCore.SIGNAL(u'playbackPause'), self.video_pause)
|
||||
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.SIGNAL(u'seek_slider'), self.video_seek)
|
||||
QtCore.SIGNAL(u'seekSlider'), self.video_seek)
|
||||
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.SIGNAL(u'media_hide'), self.video_hide)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'media_blank'), self.video_blank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
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
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
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)
|
||||
|
||||
def set_active_players(self):
|
||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
||||
QtCore.QVariant(u'webkit')).toString())
|
||||
if len(playerSettings) == 0:
|
||||
playerSettings = u'webkit'
|
||||
savedPlayers = playerSettings.split(u',')
|
||||
savedPlayers = get_media_players()[0]
|
||||
for player in self.mediaPlayers.keys():
|
||||
if player in savedPlayers:
|
||||
self.mediaPlayers[player].isActive = True
|
||||
|
@ -100,7 +94,6 @@ class MediaController(object):
|
|||
Register each media Player controller (Webkit, Phonon, etc) and store
|
||||
for later use
|
||||
"""
|
||||
if controller.check_available():
|
||||
self.mediaPlayers[controller.name] = controller
|
||||
|
||||
def check_available_media_players(self):
|
||||
|
@ -130,17 +123,14 @@ class MediaController(object):
|
|||
controller = controller_class(self)
|
||||
self.register_controllers(controller)
|
||||
if self.mediaPlayers:
|
||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
||||
QtCore.QVariant(u'webkit')).toString())
|
||||
savedPlayers = playerSettings.split(u',')
|
||||
savedPlayers, overriddenPlayer = get_media_players()
|
||||
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:
|
||||
for invalidPlayer in invalidMediaPlayers:
|
||||
savedPlayers.remove(invalidPlayer)
|
||||
newPlayerSetting = u','.join(savedPlayers)
|
||||
QtCore.QSettings().setValue(u'media/players',
|
||||
QtCore.QVariant(newPlayerSetting))
|
||||
set_media_players(savedPlayers, overriddenPlayer)
|
||||
self.set_active_players()
|
||||
return True
|
||||
else:
|
||||
|
@ -160,6 +150,11 @@ class MediaController(object):
|
|||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Playing:
|
||||
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()
|
||||
|
||||
def get_media_display_css(self):
|
||||
|
@ -204,47 +199,50 @@ class MediaController(object):
|
|||
controller.media_info = MediaInfo()
|
||||
# Build a Media ToolBar
|
||||
controller.mediabar = OpenLPToolbar(controller)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'media_playback_play', u':/slides/media_playback_start.png',
|
||||
translate('OpenLP.SlideController', 'Start playing media.'),
|
||||
controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'media_playback_pause', u':/slides/media_playback_pause.png',
|
||||
translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||
controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarButton(
|
||||
u'media_playback_stop', u':/slides/media_playback_stop.png',
|
||||
translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||
controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarAction(u'playbackPlay',
|
||||
text=u'media_playback_play',
|
||||
icon=u':/slides/media_playback_start.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
||||
triggers=controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarAction(u'playbackPause',
|
||||
text=u'media_playback_pause',
|
||||
icon=u':/slides/media_playback_pause.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||
triggers=controller.sendToPlugins)
|
||||
controller.mediabar.addToolbarAction(u'playbackStop',
|
||||
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.
|
||||
controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
controller.seekSlider.setMaximum(1000)
|
||||
controller.seekSlider.setTracking(False)
|
||||
controller.seekSlider.setToolTip(translate(
|
||||
'OpenLP.SlideController', 'Video position.'))
|
||||
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
|
||||
controller.seekSlider.setObjectName(u'seek_slider')
|
||||
controller.mediabar.addToolbarWidget(u'Seek Slider',
|
||||
controller.seekSlider)
|
||||
controller.seekSlider.setObjectName(u'seekSlider')
|
||||
controller.mediabar.addToolbarWidget(controller.seekSlider)
|
||||
# Build the volumeSlider.
|
||||
controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
|
||||
controller.volumeSlider.setTickInterval(10)
|
||||
controller.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove)
|
||||
controller.volumeSlider.setMinimum(0)
|
||||
controller.volumeSlider.setMaximum(100)
|
||||
controller.volumeSlider.setTracking(True)
|
||||
controller.volumeSlider.setToolTip(translate(
|
||||
'OpenLP.SlideController', 'Audio Volume.'))
|
||||
controller.volumeSlider.setValue(controller.media_info.volume)
|
||||
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||
controller.volumeSlider.setObjectName(u'volume_slider')
|
||||
controller.mediabar.addToolbarWidget(u'Audio Volume',
|
||||
controller.volumeSlider)
|
||||
controller.volumeSlider.setObjectName(u'volumeSlider')
|
||||
controller.mediabar.addToolbarWidget(controller.volumeSlider)
|
||||
control_panel.addWidget(controller.mediabar)
|
||||
controller.mediabar.setVisible(False)
|
||||
# Signals
|
||||
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.SIGNAL(u'sliderMoved(int)'), controller.sendToPlugins)
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
|
||||
|
||||
def setup_special_controls(self, controller, control_panel):
|
||||
"""
|
||||
|
@ -276,6 +274,11 @@ class MediaController(object):
|
|||
def set_controls_visible(self, controller, value):
|
||||
# Generic controls
|
||||
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
|
||||
# (e.g. for DVD control, ...)
|
||||
# TODO
|
||||
|
@ -316,7 +319,8 @@ class MediaController(object):
|
|||
controller.media_info.start_time = 0
|
||||
controller.media_info.end_time = 0
|
||||
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
|
||||
elif controller.previewDisplay:
|
||||
display = controller.previewDisplay
|
||||
|
@ -353,13 +357,9 @@ class MediaController(object):
|
|||
"""
|
||||
Select the correct media Player type from the prioritized Player list
|
||||
"""
|
||||
playerSettings = str(QtCore.QSettings().value(u'media/players',
|
||||
QtCore.QVariant(u'webkit')).toString())
|
||||
usedPlayers = playerSettings.split(u',')
|
||||
if QtCore.QSettings().value(u'media/override player',
|
||||
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
if self.overridenPlayer != '':
|
||||
usedPlayers = [self.overridenPlayer]
|
||||
usedPlayers, overriddenPlayer = get_media_players()
|
||||
if overriddenPlayer and overriddenPlayer != u'auto':
|
||||
usedPlayers = [overriddenPlayer]
|
||||
if controller.media_info.file_info.isFile():
|
||||
suffix = u'*.%s' % \
|
||||
controller.media_info.file_info.suffix().toLower()
|
||||
|
@ -443,6 +443,7 @@ class MediaController(object):
|
|||
display.frame.evaluateJavaScript(u'show_blank("black");')
|
||||
self.curDisplayMediaPlayer[display].stop(display)
|
||||
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
||||
controller.seekSlider.setSliderPosition(0)
|
||||
|
||||
def video_volume(self, msg):
|
||||
"""
|
||||
|
@ -478,6 +479,7 @@ class MediaController(object):
|
|||
Responds to the request to reset a loaded video
|
||||
"""
|
||||
log.debug(u'video_reset')
|
||||
self.set_controls_visible(controller, False)
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller == controller:
|
||||
display.override = {}
|
||||
|
@ -486,7 +488,6 @@ class MediaController(object):
|
|||
display.frame.evaluateJavaScript(u'show_video( \
|
||||
"setBackBoard", null, null, null,"hidden");')
|
||||
del self.curDisplayMediaPlayer[display]
|
||||
self.set_controls_visible(controller, False)
|
||||
|
||||
def video_hide(self, msg):
|
||||
"""
|
||||
|
@ -569,15 +570,6 @@ class MediaController(object):
|
|||
video_list.append(item)
|
||||
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):
|
||||
self.timer.stop()
|
||||
for controller in self.controller:
|
||||
|
|
|
@ -51,6 +51,7 @@ ADDITIONAL_EXT = {
|
|||
u'video/x-matroska': [u'.mpv', u'.mkv'],
|
||||
u'video/x-wmv': [u'.wmv'],
|
||||
u'video/x-mpg': [u'.mpg'],
|
||||
u'video/mpeg' : [u'.mp4', u'.mts'],
|
||||
u'video/x-ms-wmv': [u'.wmv']}
|
||||
|
||||
|
||||
|
@ -62,6 +63,8 @@ class PhononPlayer(MediaPlayer):
|
|||
|
||||
def __init__(self, parent):
|
||||
MediaPlayer.__init__(self, parent, u'phonon')
|
||||
self.original_name = u'Phonon'
|
||||
self.display_name = u'&Phonon'
|
||||
self.parent = parent
|
||||
self.additional_extensions = ADDITIONAL_EXT
|
||||
mimetypes.init()
|
||||
|
@ -189,6 +192,9 @@ class PhononPlayer(MediaPlayer):
|
|||
display.phononWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
if display.mediaObject.state() == Phonon.PausedState and \
|
||||
self.state != MediaState.Paused:
|
||||
self.stop(display)
|
||||
controller = display.controller
|
||||
if controller.media_info.end_time > 0:
|
||||
if display.mediaObject.currentTime() > \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
vid.currentTime = varVal;
|
||||
break;
|
||||
case 'isEnded':
|
||||
return vid.ended;
|
||||
case 'setVisible':
|
||||
vid.style.visibility = varVal;
|
||||
break;
|
||||
|
@ -211,6 +213,8 @@ FLASH_JS = u"""
|
|||
case 'seek':
|
||||
// flashMovie.GotoFrame(varVal);
|
||||
break;
|
||||
case 'isEnded':
|
||||
return false;//TODO check flash end
|
||||
case 'setVisible':
|
||||
text.style.visibility = varVal;
|
||||
break;
|
||||
|
@ -260,6 +264,8 @@ class WebkitPlayer(MediaPlayer):
|
|||
|
||||
def __init__(self, parent):
|
||||
MediaPlayer.__init__(self, parent, u'webkit')
|
||||
self.original_name = u'WebKit'
|
||||
self.display_name = u'&WebKit'
|
||||
self.parent = parent
|
||||
self.canBackground = True
|
||||
self.audio_extensions_list = AUDIO_EXT
|
||||
|
@ -294,7 +300,7 @@ class WebkitPlayer(MediaPlayer):
|
|||
def load(self, display):
|
||||
log.debug(u'load vid in Webkit Controller')
|
||||
controller = display.controller
|
||||
if display.hasAudio:
|
||||
if display.hasAudio and not controller.media_info.is_background:
|
||||
volume = controller.media_info.volume
|
||||
vol = float(volume) / float(100)
|
||||
else:
|
||||
|
@ -354,7 +360,6 @@ class WebkitPlayer(MediaPlayer):
|
|||
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("stop");')
|
||||
controller.seekSlider.setSliderPosition(0)
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
|
@ -406,6 +411,9 @@ class WebkitPlayer(MediaPlayer):
|
|||
length = display.frame.evaluateJavaScript( \
|
||||
u'show_flash("length");').toInt()[0]
|
||||
else:
|
||||
if display.frame.evaluateJavaScript( \
|
||||
u'show_video("isEnded");').toString() == 'true':
|
||||
self.stop(display)
|
||||
(currentTime, ok) = display.frame.evaluateJavaScript( \
|
||||
u'show_video("currentTime");').toFloat()
|
||||
# check if conversion was ok and value is not 'NaN'
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -405,7 +405,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||
# Only continue when we include the song's text.
|
||||
if not self.slideTextCheckBox.isChecked():
|
||||
return
|
||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||
for item in self.serviceManager.serviceItems:
|
||||
# Trigger Audit requests
|
||||
Receiver.send_message(u'print_service_started',
|
||||
[item[u'service_item']])
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -222,6 +222,21 @@ class ScreenList(object):
|
|||
log.debug(u'reset_current_display')
|
||||
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):
|
||||
"""
|
||||
Loads the screen size and the monitor number from the settings.
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -31,6 +31,7 @@ import os
|
|||
import shutil
|
||||
import zipfile
|
||||
from tempfile import mkstemp
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -40,11 +41,10 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
|
|||
ItemCapabilities, SettingsManager, translate, str_to_bool
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
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.printserviceform import PrintServiceForm
|
||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||
split_filename
|
||||
from openlp.core.utils import AppLocation, delete_file, split_filename
|
||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||
|
||||
class ServiceManagerList(QtGui.QTreeWidget):
|
||||
|
@ -117,22 +117,23 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.layout.setMargin(0)
|
||||
# Create the top toolbar
|
||||
self.toolbar = OpenLPToolbar(self)
|
||||
self.toolbar.addToolbarButton(
|
||||
UiStrings().NewService, u':/general/general_new.png',
|
||||
UiStrings().CreateService, self.onNewServiceClicked)
|
||||
self.toolbar.addToolbarButton(
|
||||
UiStrings().OpenService, u':/general/general_open.png',
|
||||
translate('OpenLP.ServiceManager', 'Load an existing service.'),
|
||||
self.onLoadServiceClicked)
|
||||
self.toolbar.addToolbarButton(
|
||||
UiStrings().SaveService, u':/general/general_save.png',
|
||||
translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||
self.saveFile)
|
||||
self.toolbar.addToolbarAction(u'newService',
|
||||
text=UiStrings().NewService, icon=u':/general/general_new.png',
|
||||
tooltip=UiStrings().CreateService,
|
||||
triggers=self.onNewServiceClicked)
|
||||
self.toolbar.addToolbarAction(u'openService',
|
||||
text=UiStrings().OpenService, icon=u':/general/general_open.png',
|
||||
tooltip=translate('OpenLP.ServiceManager',
|
||||
'Load an existing service.'), triggers=self.onLoadServiceClicked)
|
||||
self.toolbar.addToolbarAction(u'saveService',
|
||||
text=UiStrings().SaveService, icon=u':/general/general_save.png',
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||
triggers=self.saveFile)
|
||||
self.toolbar.addSeparator()
|
||||
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
|
||||
self.themeLabel.setMargin(3)
|
||||
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.setToolTip(translate('OpenLP.ServiceManager',
|
||||
'Select a theme for the service.'))
|
||||
|
@ -141,7 +142,7 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.themeComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.themeComboBox.setObjectName(u'themeComboBox')
|
||||
self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
|
||||
self.toolbar.addToolbarWidget(self.themeComboBox)
|
||||
self.toolbar.setObjectName(u'toolbar')
|
||||
self.layout.addWidget(self.toolbar)
|
||||
# Create the service manager list
|
||||
|
@ -168,99 +169,77 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.layout.addWidget(self.serviceManagerList)
|
||||
# Add the bottom toolbar
|
||||
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.add_category(
|
||||
unicode(UiStrings().Service), CategoryOrder.standardToolbar)
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.moveTop, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Move &up'),
|
||||
u':/services/service_up.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(
|
||||
u'moveTop', text=translate('OpenLP.ServiceManager', 'Move to &top'),
|
||||
icon=u':/services/service_top.png', tooltip=translate(
|
||||
'OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
||||
shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service,
|
||||
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.'),
|
||||
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
|
||||
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.moveUp, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
||||
u':/services/service_down.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service,
|
||||
triggers=self.onServiceUp)
|
||||
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarAction(
|
||||
u'moveDown', text=translate('OpenLP.ServiceManager', 'Move &down'),
|
||||
icon=u':/services/service_down.png',
|
||||
tooltip=translate('OpenLP.ServiceManager',
|
||||
'Move item down one position in the service.'),
|
||||
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
|
||||
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.moveDown, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
||||
u':/services/service_bottom.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Move item to the end of the service.'),
|
||||
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
|
||||
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.moveBottom, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
|
||||
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')
|
||||
shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service,
|
||||
triggers=self.onServiceDown)
|
||||
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarAction(
|
||||
u'moveBottom',
|
||||
text=translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
||||
icon=u':/services/service_bottom.png', tooltip=translate(
|
||||
'OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
||||
shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service,
|
||||
triggers=self.onServiceEnd)
|
||||
self.serviceManagerList.down = self.orderToolbar.addToolbarAction(
|
||||
u'down', text=translate('OpenLP.ServiceManager', 'Move &down'),
|
||||
tooltip=translate('OpenLP.ServiceManager',
|
||||
'Moves the selection down the window.'), visible=False,
|
||||
shortcuts=[QtCore.Qt.Key_Down], triggers=self.onMoveSelectionDown)
|
||||
action_list.add_action(self.serviceManagerList.down)
|
||||
self.serviceManagerList.down.setVisible(False)
|
||||
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Move up'),
|
||||
None,
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Moves the selection up the window.'),
|
||||
self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up])
|
||||
self.serviceManagerList.up.setObjectName(u'up')
|
||||
self.serviceManagerList.up = self.orderToolbar.addToolbarAction(
|
||||
u'up', text=translate('OpenLP.ServiceManager', 'Move up'),
|
||||
tooltip=translate('OpenLP.ServiceManager',
|
||||
'Moves the selection up the window.'), visible=False,
|
||||
shortcuts=[QtCore.Qt.Key_Up], triggers=self.onMoveSelectionUp)
|
||||
action_list.add_action(self.serviceManagerList.up)
|
||||
self.serviceManagerList.up.setVisible(False)
|
||||
self.orderToolbar.addSeparator()
|
||||
self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||
u':/general/general_delete.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
self.serviceManagerList.delete = self.orderToolbar.addToolbarAction(
|
||||
u'delete',
|
||||
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||
icon=u':/general/general_delete.png',
|
||||
tooltip=translate('OpenLP.ServiceManager',
|
||||
'Delete the selected item from the service.'),
|
||||
self.onDeleteFromService)
|
||||
triggers=self.onDeleteFromService)
|
||||
self.orderToolbar.addSeparator()
|
||||
self.serviceManagerList.expand = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', '&Expand all'),
|
||||
u':/services/service_expand_all.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Expand all the service items.'),
|
||||
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
|
||||
self.serviceManagerList.expand.setObjectName(u'expand')
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.expand, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', '&Collapse all'),
|
||||
u':/services/service_collapse_all.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
'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.serviceManagerList.expand = self.orderToolbar.addToolbarAction(
|
||||
u'expand', text=translate('OpenLP.ServiceManager', '&Expand all'),
|
||||
icon=u':/services/service_expand_all.png', tooltip=translate(
|
||||
'OpenLP.ServiceManager', 'Expand all the service items.'),
|
||||
shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service,
|
||||
triggers=self.onExpandAll)
|
||||
self.serviceManagerList.collapse = self.orderToolbar.addToolbarAction(
|
||||
u'collapse',
|
||||
text=translate('OpenLP.ServiceManager', '&Collapse all'),
|
||||
icon=u':/services/service_collapse_all.png', tooltip=translate(
|
||||
'OpenLP.ServiceManager', 'Collapse all the service items.'),
|
||||
shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service,
|
||||
triggers=self.onCollapseAll)
|
||||
self.orderToolbar.addSeparator()
|
||||
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Go Live'),
|
||||
u':/general/general_live.png',
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Send the selected item to Live.'), self.makeLive,
|
||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
||||
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
|
||||
action_list.add_action(
|
||||
self.serviceManagerList.makeLive, unicode(UiStrings().Service))
|
||||
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarAction(
|
||||
u'makeLive', text=translate('OpenLP.ServiceManager', 'Go Live'),
|
||||
icon=u':/general/general_live.png', tooltip=translate(
|
||||
'OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
||||
category=UiStrings().Service, triggers=self.makeLive)
|
||||
self.layout.addWidget(self.orderToolbar)
|
||||
# Connect up our signals and slots
|
||||
QtCore.QObject.connect(self.themeComboBox,
|
||||
|
@ -305,34 +284,32 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
# build the context menu
|
||||
self.menu = QtGui.QMenu()
|
||||
self.editAction = context_menu_action(
|
||||
self.menu, u':/general/general_edit.png',
|
||||
translate('OpenLP.ServiceManager', '&Edit Item'), self.remoteEdit)
|
||||
self.maintainAction = context_menu_action(
|
||||
self.menu, u':/general/general_edit.png',
|
||||
translate('OpenLP.ServiceManager', '&Reorder Item'),
|
||||
self.onServiceItemEditForm)
|
||||
self.notesAction = context_menu_action(
|
||||
self.menu, u':/services/service_notes.png',
|
||||
translate('OpenLP.ServiceManager', '&Notes'),
|
||||
self.onServiceItemNoteForm)
|
||||
self.timeAction = context_menu_action(
|
||||
self.menu, u':/media/media_time.png',
|
||||
translate('OpenLP.ServiceManager', '&Start Time'),
|
||||
self.onStartTimeForm)
|
||||
self.deleteAction = context_menu_action(
|
||||
self.menu, u':/general/general_delete.png',
|
||||
translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||
self.onDeleteFromService)
|
||||
context_menu_separator(self.menu)
|
||||
self.previewAction = context_menu_action(
|
||||
self.menu, u':/general/general_preview.png',
|
||||
translate('OpenLP.ServiceManager', 'Show &Preview'),
|
||||
self.makePreview)
|
||||
self.liveAction = context_menu_action(
|
||||
self.menu, u':/general/general_live.png',
|
||||
translate('OpenLP.ServiceManager', 'Show &Live'), self.makeLive)
|
||||
context_menu_separator(self.menu)
|
||||
self.editAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', '&Edit Item'),
|
||||
icon=u':/general/general_edit.png', triggers=self.remoteEdit)
|
||||
self.maintainAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', '&Reorder Item'),
|
||||
icon=u':/general/general_edit.png',
|
||||
triggers=self.onServiceItemEditForm)
|
||||
self.notesAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', '&Notes'),
|
||||
icon=u':/services/service_notes.png',
|
||||
triggers=self.onServiceItemNoteForm)
|
||||
self.timeAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', '&Start Time'),
|
||||
icon=u':/media/media_time.png', triggers=self.onStartTimeForm)
|
||||
self.deleteAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
|
||||
icon=u':/general/general_delete.png',
|
||||
triggers=self.onDeleteFromService)
|
||||
self.menu.addSeparator()
|
||||
self.previewAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', 'Show &Preview'),
|
||||
icon=u':/general/general_preview.png', triggers=self.makePreview)
|
||||
self.liveAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', 'Show &Live'),
|
||||
icon=u':/general/general_live.png', triggers=self.makeLive)
|
||||
self.menu.addSeparator()
|
||||
self.themeMenu = QtGui.QMenu(
|
||||
translate('OpenLP.ServiceManager', '&Change Item Theme'))
|
||||
self.menu.addMenu(self.themeMenu)
|
||||
|
@ -484,7 +461,7 @@ class ServiceManager(QtGui.QWidget):
|
|||
log.debug(temp_file_name)
|
||||
path_file_name = unicode(self.fileName())
|
||||
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
|
||||
log.debug(u'ServiceManager.saveFile - %s', path_file_name)
|
||||
SettingsManager.set_last_dir(
|
||||
|
@ -506,8 +483,7 @@ class ServiceManager(QtGui.QWidget):
|
|||
for i, filename in \
|
||||
enumerate(service_item[u'header'][u'background_audio']):
|
||||
new_file = os.path.join(u'audio',
|
||||
item[u'service_item']._uuid,
|
||||
os.path.split(filename)[1])
|
||||
item[u'service_item']._uuid, filename)
|
||||
audio_files.append((filename, new_file))
|
||||
service_item[u'header'][u'background_audio'][i] = new_file
|
||||
# Add the service item to the service.
|
||||
|
@ -596,7 +572,10 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.mainwindow.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except:
|
||||
return self.saveFileAs()
|
||||
self.mainwindow.addRecentFile(path_file_name)
|
||||
self.setModified(False)
|
||||
try:
|
||||
|
@ -610,10 +589,39 @@ class ServiceManager(QtGui.QWidget):
|
|||
Get a file name and then call :func:`ServiceManager.saveFile` to
|
||||
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,
|
||||
UiStrings().SaveService,
|
||||
SettingsManager.get_last_dir(
|
||||
self.mainwindow.servicemanagerSettingsSection),
|
||||
UiStrings().SaveService, path,
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||
if not fileName:
|
||||
return False
|
||||
|
@ -636,14 +644,17 @@ class ServiceManager(QtGui.QWidget):
|
|||
try:
|
||||
zip = zipfile.ZipFile(fileName)
|
||||
for zipinfo in zip.infolist():
|
||||
ucsfile = file_is_unicode(zipinfo.filename)
|
||||
if not ucsfile:
|
||||
try:
|
||||
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(
|
||||
message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n'
|
||||
'The content encoding is not UTF-8.'))
|
||||
continue
|
||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
||||
osfile = ucsfile.replace(u'/', os.path.sep)
|
||||
if not osfile.startswith(u'audio'):
|
||||
osfile = os.path.split(osfile)[1]
|
||||
log.debug(u'Extract file: %s', osfile)
|
||||
|
@ -821,7 +832,7 @@ class ServiceManager(QtGui.QWidget):
|
|||
lookFor = 1
|
||||
serviceIterator += 1
|
||||
|
||||
def previousItem(self):
|
||||
def previousItem(self, message):
|
||||
"""
|
||||
Called by the SlideController to select the previous service item.
|
||||
"""
|
||||
|
@ -829,15 +840,26 @@ class ServiceManager(QtGui.QWidget):
|
|||
return
|
||||
selected = self.serviceManagerList.selectedItems()[0]
|
||||
prevItem = None
|
||||
prevItemLastSlide = None
|
||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
|
||||
while serviceIterator.value():
|
||||
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.makeLive()
|
||||
return
|
||||
if serviceIterator.value().parent() is None:
|
||||
prevItem = serviceIterator.value()
|
||||
if serviceIterator.value().parent() is prevItem:
|
||||
prevItemLastSlide = serviceIterator.value()
|
||||
serviceIterator += 1
|
||||
|
||||
def onSetItem(self, message):
|
||||
|
@ -1092,12 +1114,9 @@ class ServiceManager(QtGui.QWidget):
|
|||
sure the theme combo box is in the correct state.
|
||||
"""
|
||||
log.debug(u'themeChange')
|
||||
if self.mainwindow.renderer.theme_level == ThemeLevel.Global:
|
||||
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
|
||||
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
|
||||
else:
|
||||
self.toolbar.actions[u'ThemeLabel'].setVisible(True)
|
||||
self.toolbar.actions[u'ThemeWidget'].setVisible(True)
|
||||
visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global
|
||||
self.themeLabel.setVisible(visible)
|
||||
self.themeComboBox.setVisible(visible)
|
||||
|
||||
def regenerateServiceItems(self):
|
||||
"""
|
||||
|
@ -1334,15 +1353,15 @@ class ServiceManager(QtGui.QWidget):
|
|||
Handle of the event pint passed
|
||||
"""
|
||||
link = event.mimeData()
|
||||
if event.mimeData().hasUrls():
|
||||
if link.hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
for url in event.mimeData().urls():
|
||||
for url in link.urls():
|
||||
filename = unicode(url.toLocalFile())
|
||||
if filename.endswith(u'.osz'):
|
||||
self.onLoadServiceClicked(filename)
|
||||
elif event.mimeData().hasText():
|
||||
plugin = unicode(event.mimeData().text())
|
||||
elif link.hasText():
|
||||
plugin = unicode(link.text())
|
||||
item = self.serviceManagerList.itemAt(event.pos())
|
||||
# ServiceManager started the drag and drop
|
||||
if plugin == u'ServiceManager':
|
||||
|
@ -1399,19 +1418,16 @@ class ServiceManager(QtGui.QWidget):
|
|||
themeGroup.setObjectName(u'themeGroup')
|
||||
# Create a "Default" theme, which allows the user to reset the item's
|
||||
# theme to the service theme or global theme.
|
||||
defaultTheme = context_menu_action(self.themeMenu, None,
|
||||
UiStrings().Default, self.onThemeChangeAction)
|
||||
defaultTheme.setCheckable(True)
|
||||
defaultTheme = create_widget_action(self.themeMenu,
|
||||
text=UiStrings().Default, checked=False,
|
||||
triggers=self.onThemeChangeAction)
|
||||
self.themeMenu.setDefaultAction(defaultTheme)
|
||||
themeGroup.addAction(defaultTheme)
|
||||
context_menu_separator(self.themeMenu)
|
||||
self.themeMenu.addSeparator()
|
||||
for theme in theme_list:
|
||||
self.themeComboBox.addItem(theme)
|
||||
themeAction = context_menu_action(self.themeMenu, None, theme,
|
||||
self.onThemeChangeAction)
|
||||
themeAction.setObjectName(theme)
|
||||
themeAction.setCheckable(True)
|
||||
themeGroup.addAction(themeAction)
|
||||
themeGroup.addAction(create_widget_action(self.themeMenu, theme,
|
||||
text=theme, checked=False, triggers=self.onThemeChangeAction))
|
||||
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
|
||||
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||
self.regenerateServiceItems()
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -57,7 +57,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||
def exec_(self):
|
||||
# load all the settings
|
||||
self.settingListWidget.clear()
|
||||
for tabIndex in range(0, self.stackedLayout.count() + 1):
|
||||
while self.stackedLayout.count():
|
||||
# take at 0 and the rest shuffle up.
|
||||
self.stackedLayout.takeAt(0)
|
||||
self.insertTab(self.generalTab, 0, PluginStatus.Active)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -344,8 +344,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||
if category.name is None:
|
||||
continue
|
||||
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])
|
||||
self.action_list.update_shortcut_map(action, old_shortcuts)
|
||||
settings.setValue(
|
||||
action.objectName(), QtCore.QVariant(action.shortcuts()))
|
||||
settings.endGroup()
|
||||
|
@ -452,7 +455,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||
those shortcuts which are not saved yet but already assigned (as changes
|
||||
are applied when closing the dialog).
|
||||
"""
|
||||
if self.changedActions.has_key(action):
|
||||
if action in self.changedActions:
|
||||
return self.changedActions[action]
|
||||
return action.shortcuts()
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -33,8 +33,9 @@ from collections import deque
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
|
||||
translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem
|
||||
from openlp.core.lib.ui import UiStrings, shortcut_action
|
||||
translate, build_icon, build_html, PluginManager, ServiceItem
|
||||
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.utils.actions import ActionList, CategoryOrder
|
||||
|
||||
|
@ -45,9 +46,10 @@ class SlideList(QtGui.QTableWidget):
|
|||
Customised version of QTableWidget which can respond to keyboard
|
||||
events.
|
||||
"""
|
||||
def __init__(self, parent=None, name=None):
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QTableWidget.__init__(self, parent.controller)
|
||||
|
||||
|
||||
class Controller(QtGui.QWidget):
|
||||
"""
|
||||
Controller is a general controller widget.
|
||||
|
@ -82,26 +84,29 @@ class SlideController(Controller):
|
|||
"""
|
||||
Controller.__init__(self, parent, isLive)
|
||||
self.screens = ScreenList.get_instance()
|
||||
try:
|
||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||
float(self.screens.current[u'size'].height())
|
||||
except ZeroDivisionError:
|
||||
self.ratio = 1
|
||||
self.imageManager = self.parent().imageManager
|
||||
self.mediaController = self.parent().mediaController
|
||||
self.loopList = [
|
||||
u'Play Slides Menu',
|
||||
u'Loop Separator',
|
||||
u'Image SpinBox'
|
||||
u'playSlidesMenu',
|
||||
u'loopSeparator',
|
||||
u'delaySpinBox'
|
||||
]
|
||||
self.songEditList = [
|
||||
u'Edit Song',
|
||||
]
|
||||
self.nextPreviousList = [
|
||||
u'Previous Slide',
|
||||
u'Next Slide'
|
||||
self.audioList = [
|
||||
u'songMenu',
|
||||
u'audioPauseItem',
|
||||
u'audioTimeLabel'
|
||||
]
|
||||
self.timer_id = 0
|
||||
self.songEdit = False
|
||||
self.selectedRow = 0
|
||||
self.serviceItem = None
|
||||
self.slide_limits = None
|
||||
self.updateSlideLimits()
|
||||
self.panel = QtGui.QWidget(parent.controlSplitter)
|
||||
self.slideList = {}
|
||||
# Layout for holding panel
|
||||
|
@ -116,10 +121,14 @@ class SlideController(Controller):
|
|||
self.typePrefix = u'live'
|
||||
self.keypress_queue = deque()
|
||||
self.keypress_loop = False
|
||||
self.category = UiStrings().LiveToolbar
|
||||
ActionList.get_instance().add_category(
|
||||
unicode(self.category), CategoryOrder.standardToolbar)
|
||||
else:
|
||||
self.typeLabel.setText(UiStrings().Preview)
|
||||
self.split = 0
|
||||
self.typePrefix = u'preview'
|
||||
self.category = None
|
||||
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
||||
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.panelLayout.addWidget(self.typeLabel)
|
||||
|
@ -162,72 +171,71 @@ class SlideController(Controller):
|
|||
sizeToolbarPolicy.setHeightForWidth(
|
||||
self.toolbar.sizePolicy().hasHeightForWidth())
|
||||
self.toolbar.setSizePolicy(sizeToolbarPolicy)
|
||||
self.previousItem = self.toolbar.addToolbarButton(
|
||||
u'Previous Slide',
|
||||
u':/slides/slide_previous.png',
|
||||
translate('OpenLP.SlideController', 'Move to previous.'),
|
||||
self.onSlideSelectedPrevious,
|
||||
self.previousItem = create_action(self,
|
||||
u'previousItem_' + self.typePrefix,
|
||||
text=translate('OpenLP.SlideController', 'Previous Slide'),
|
||||
icon=u':/slides/slide_previous.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
|
||||
shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.nextItem = self.toolbar.addToolbarButton(
|
||||
u'Next Slide',
|
||||
u':/slides/slide_next.png',
|
||||
translate('OpenLP.SlideController', 'Move to next.'),
|
||||
self.onSlideSelectedNext,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.onSlideSelectedPrevious)
|
||||
self.toolbar.addAction(self.previousItem)
|
||||
self.nextItem = create_action(self, u'nextItem_' + self.typePrefix,
|
||||
text=translate('OpenLP.SlideController', 'Next Slide'),
|
||||
icon=u':/slides/slide_next.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
|
||||
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.onSlideSelectedNextAction)
|
||||
self.toolbar.addAction(self.nextItem)
|
||||
self.toolbar.addSeparator()
|
||||
if self.isLive:
|
||||
# Hide Menu
|
||||
self.hideMenu = QtGui.QToolButton(self.toolbar)
|
||||
self.hideMenu.setObjectName(u'hideMenu')
|
||||
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
|
||||
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
||||
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
|
||||
self.hideMenu.setMenu(QtGui.QMenu(
|
||||
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
||||
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
|
||||
[QtCore.Qt.Key_Period], self.onBlankDisplay,
|
||||
u':/slides/slide_blank.png', False,
|
||||
unicode(UiStrings().LiveToolbar))
|
||||
self.blankScreen.setText(
|
||||
translate('OpenLP.SlideController', 'Blank Screen'))
|
||||
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
|
||||
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
|
||||
u':/slides/slide_theme.png', False,
|
||||
unicode(UiStrings().LiveToolbar))
|
||||
self.themeScreen.setText(
|
||||
translate('OpenLP.SlideController', 'Blank to Theme'))
|
||||
self.desktopScreen = shortcut_action(self.hideMenu,
|
||||
u'desktopScreen', [QtGui.QKeySequence(u'D')],
|
||||
self.onHideDisplay, u':/slides/slide_desktop.png', False,
|
||||
unicode(UiStrings().LiveToolbar))
|
||||
self.desktopScreen.setText(
|
||||
translate('OpenLP.SlideController', 'Show Desktop'))
|
||||
self.toolbar.addToolbarWidget(self.hideMenu)
|
||||
self.blankScreen = create_action(self, u'blankScreen',
|
||||
text=translate('OpenLP.SlideController', 'Blank Screen'),
|
||||
icon=u':/slides/slide_blank.png', checked=False,
|
||||
shortcuts=[QtCore.Qt.Key_Period],
|
||||
category=self.category, triggers=self.onBlankDisplay)
|
||||
self.themeScreen = create_action(self, u'themeScreen',
|
||||
text=translate('OpenLP.SlideController', 'Blank to Theme'),
|
||||
icon=u':/slides/slide_theme.png', checked=False,
|
||||
shortcuts=[QtGui.QKeySequence(u'T')],
|
||||
category=self.category, triggers=self.onThemeDisplay)
|
||||
self.desktopScreen = create_action(self, u'desktopScreen',
|
||||
text=translate('OpenLP.SlideController', 'Show Desktop'),
|
||||
icon=u':/slides/slide_desktop.png', checked=False,
|
||||
shortcuts=[QtGui.QKeySequence(u'D')],
|
||||
category=self.category, triggers=self.onHideDisplay)
|
||||
self.hideMenu.setDefaultAction(self.blankScreen)
|
||||
self.hideMenu.menu().addAction(self.blankScreen)
|
||||
self.hideMenu.menu().addAction(self.themeScreen)
|
||||
self.hideMenu.menu().addAction(self.desktopScreen)
|
||||
self.toolbar.addToolbarSeparator(u'Loop Separator')
|
||||
self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
|
||||
# Play Slides Menu
|
||||
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
|
||||
self.playSlidesMenu.setObjectName(u'playSlidesMenu')
|
||||
self.playSlidesMenu.setText(translate('OpenLP.SlideController',
|
||||
'Play Slides'))
|
||||
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
|
||||
self.toolbar.addToolbarWidget(u'Play Slides Menu',
|
||||
self.playSlidesMenu)
|
||||
self.playSlidesMenu.setMenu(QtGui.QMenu(
|
||||
translate('OpenLP.SlideController', 'Play Slides'),
|
||||
self.toolbar))
|
||||
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
|
||||
u'playSlidesLoop', [], self.onPlaySlidesLoop,
|
||||
u':/media/media_time.png', False,
|
||||
unicode(UiStrings().LiveToolbar))
|
||||
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
|
||||
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
|
||||
u'playSlidesOnce', [], self.onPlaySlidesOnce,
|
||||
u':/media/media_time.png', False,
|
||||
unicode(UiStrings().LiveToolbar))
|
||||
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.toolbar.addToolbarWidget(self.playSlidesMenu)
|
||||
self.playSlidesLoop = create_action(self, u'playSlidesLoop',
|
||||
text=UiStrings().PlaySlidesInLoop,
|
||||
icon=u':/media/media_time.png', checked=False, shortcuts=[],
|
||||
category=self.category, triggers=self.onPlaySlidesLoop)
|
||||
self.playSlidesOnce = create_action(self, u'playSlidesOnce',
|
||||
text=UiStrings().PlaySlidesToEnd,
|
||||
icon=u':/media/media_time.png', checked=False, shortcuts=[],
|
||||
category=self.category, triggers=self.onPlaySlidesOnce)
|
||||
if QtCore.QSettings().value(self.parent().generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
|
||||
|
@ -237,47 +245,75 @@ class SlideController(Controller):
|
|||
self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
|
||||
# Loop Delay Spinbox
|
||||
self.delaySpinBox = QtGui.QSpinBox()
|
||||
self.delaySpinBox.setObjectName(u'delaySpinBox')
|
||||
self.delaySpinBox.setRange(1, 180)
|
||||
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
|
||||
self.delaySpinBox.setSuffix(UiStrings().Seconds)
|
||||
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
||||
'Delay between slides in seconds.'))
|
||||
self.toolbar.addToolbarWidget(self.delaySpinBox)
|
||||
else:
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Go Live', u':/general/general_live.png',
|
||||
translate('OpenLP.SlideController', 'Move to live.'),
|
||||
self.onGoLive)
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Add to Service', u':/general/general_add.png',
|
||||
translate('OpenLP.SlideController', 'Add to Service.'),
|
||||
self.onPreviewAddToService)
|
||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Edit Song', u':/general/general_edit.png',
|
||||
translate('OpenLP.SlideController',
|
||||
'Edit and reload song preview.'),
|
||||
self.onEditSong)
|
||||
self.toolbar.addToolbarAction(u'goLive',
|
||||
icon=u':/general/general_live.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
|
||||
triggers=self.onGoLive)
|
||||
self.toolbar.addToolbarAction(u'addToService',
|
||||
icon=u':/general/general_add.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
|
||||
triggers=self.onPreviewAddToService)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addToolbarAction(u'editSong',
|
||||
icon=u':/general/general_edit.png',
|
||||
tooltip=translate('OpenLP.SlideController',
|
||||
'Edit and reload song preview.'), triggers=self.onEditSong)
|
||||
self.controllerLayout.addWidget(self.toolbar)
|
||||
# Build the Media Toolbar
|
||||
self.mediaController.add_controller_items(self, self.controllerLayout)
|
||||
if self.isLive:
|
||||
# Build the Song Toolbar
|
||||
self.songMenu = QtGui.QToolButton(self.toolbar)
|
||||
self.songMenu.setObjectName(u'songMenu')
|
||||
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
|
||||
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
|
||||
self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
|
||||
self.songMenu.setMenu(QtGui.QMenu(
|
||||
translate('OpenLP.SlideController', 'Go To'), self.toolbar))
|
||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||
self.toolbar.addToolbarWidget(self.songMenu)
|
||||
# Stuff for items with background audio.
|
||||
self.audioPauseItem = self.toolbar.addToolbarButton(
|
||||
u'Pause Audio', u':/slides/media_playback_pause.png',
|
||||
translate('OpenLP.SlideController', 'Pause audio.'),
|
||||
self.onAudioPauseClicked, True)
|
||||
self.audioPauseItem.setVisible(False)
|
||||
self.audioPauseItem = self.toolbar.addToolbarAction(
|
||||
u'audioPauseItem', icon=u':/slides/media_playback_pause.png',
|
||||
text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||
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
|
||||
self.previewFrame = QtGui.QFrame(self.splitter)
|
||||
self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
|
||||
|
@ -322,89 +358,31 @@ class SlideController(Controller):
|
|||
self.shortcutTimer = QtCore.QTimer()
|
||||
self.shortcutTimer.setObjectName(u'shortcutTimer')
|
||||
self.shortcutTimer.setSingleShot(True)
|
||||
self.verseShortcut = shortcut_action(self, u'verseShortcut',
|
||||
[QtGui.QKeySequence(u'V')], self.slideShortcutActivated,
|
||||
category=unicode(UiStrings().LiveToolbar),
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.verseShortcut.setText(translate(
|
||||
'OpenLP.SlideController', 'Go to "Verse"'))
|
||||
self.shortcut0 = shortcut_action(self, u'0',
|
||||
[QtGui.QKeySequence(u'0')], self.slideShortcutActivated,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.shortcut1 = shortcut_action(self, u'1',
|
||||
[QtGui.QKeySequence(u'1')], self.slideShortcutActivated,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.shortcut2 = shortcut_action(self, u'2',
|
||||
[QtGui.QKeySequence(u'2')], self.slideShortcutActivated,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.shortcut3 = shortcut_action(self, u'3',
|
||||
[QtGui.QKeySequence(u'3')], self.slideShortcutActivated,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.shortcut4 = shortcut_action(self, u'4',
|
||||
[QtGui.QKeySequence(u'4')], self.slideShortcutActivated,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.shortcut5 = shortcut_action(self, u'5',
|
||||
[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
|
||||
])
|
||||
shortcuts = [{u'key': u'V', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
|
||||
{u'key': u'C', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
|
||||
{u'key': u'B', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
|
||||
{u'key': u'P', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController',
|
||||
'Go to "Pre-Chorus"')},
|
||||
{u'key': u'I', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
|
||||
{u'key': u'E', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
|
||||
{u'key': u'O', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
|
||||
shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
|
||||
self.previewListWidget.addActions([create_action(self,
|
||||
u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
|
||||
shortcuts=[QtGui.QKeySequence(s[u'key'])],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category if s.get(u'configurable') else None,
|
||||
triggers=self._slideShortcutActivated) for s in shortcuts])
|
||||
QtCore.QObject.connect(
|
||||
self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
|
||||
self.slideShortcutActivated)
|
||||
self._slideShortcutActivated)
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.previewListWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
||||
|
@ -412,20 +390,21 @@ class SlideController(Controller):
|
|||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
|
||||
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:
|
||||
QtCore.QObject.connect(self.previewListWidget,
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||
self.onGoLiveClick)
|
||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
||||
self.toolbar.setWidgetVisible([u'editSong'], False)
|
||||
if self.isLive:
|
||||
self.setLiveHotkeys(self)
|
||||
self.__addActionsToWidget(self.previewListWidget)
|
||||
else:
|
||||
self.setPreviewHotkeys()
|
||||
self.previewListWidget.addActions(
|
||||
[self.nextItem,
|
||||
self.previousItem])
|
||||
[self.nextItem, self.previousItem])
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
|
||||
self.onStopLoop)
|
||||
|
@ -447,8 +426,11 @@ class SlideController(Controller):
|
|||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.typePrefix),
|
||||
self.onSlideUnblank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_update_slide_limits'),
|
||||
self.updateSlideLimits)
|
||||
|
||||
def slideShortcutActivated(self):
|
||||
def _slideShortcutActivated(self):
|
||||
"""
|
||||
Called, when a shortcut has been activated to jump to a chorus, verse,
|
||||
etc.
|
||||
|
@ -464,52 +446,38 @@ class SlideController(Controller):
|
|||
SONGS_PLUGIN_AVAILABLE = True
|
||||
except ImportError:
|
||||
SONGS_PLUGIN_AVAILABLE = False
|
||||
verse_type = unicode(self.sender().objectName())
|
||||
if verse_type.startswith(u'verseShortcut'):
|
||||
sender_name = unicode(self.sender().objectName())
|
||||
verse_type = sender_name[15:] \
|
||||
if sender_name[:15] == u'shortcutAction_' else u''
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
if verse_type == u'V':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Verse]
|
||||
else:
|
||||
self.current_shortcut = u'V'
|
||||
elif verse_type.startswith(u'chorusShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'C':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Chorus]
|
||||
else:
|
||||
self.current_shortcut = u'C'
|
||||
elif verse_type.startswith(u'bridgeShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'B':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Bridge]
|
||||
else:
|
||||
self.current_shortcut = u'B'
|
||||
elif verse_type.startswith(u'preChorusShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'P':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.PreChorus]
|
||||
else:
|
||||
self.current_shortcut = u'P'
|
||||
elif verse_type.startswith(u'introShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'I':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Intro]
|
||||
else:
|
||||
self.current_shortcut = u'I'
|
||||
elif verse_type.startswith(u'endingShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'E':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Ending]
|
||||
else:
|
||||
self.current_shortcut = u'E'
|
||||
elif verse_type.startswith(u'otherShortcut'):
|
||||
if SONGS_PLUGIN_AVAILABLE:
|
||||
elif verse_type == u'O':
|
||||
self.current_shortcut = \
|
||||
VerseType.TranslatedTags[VerseType.Other]
|
||||
else:
|
||||
self.current_shortcut = u'O'
|
||||
elif verse_type.isnumeric():
|
||||
self.current_shortcut += verse_type
|
||||
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()
|
||||
matches = [match for match in keys
|
||||
if match.startswith(self.current_shortcut)]
|
||||
|
@ -518,7 +486,7 @@ class SlideController(Controller):
|
|||
self.current_shortcut = u''
|
||||
self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
|
||||
self.slideSelected()
|
||||
elif verse_type != u'shortcutTimer':
|
||||
elif sender_name != u'shortcutTimer':
|
||||
# Start the time as we did not have any match.
|
||||
self.shortcutTimer.start(350)
|
||||
else:
|
||||
|
@ -532,56 +500,54 @@ class SlideController(Controller):
|
|||
# Reset the shortcut.
|
||||
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):
|
||||
self.previousItem.setObjectName(u'previousItemLive')
|
||||
self.nextItem.setObjectName(u'nextItemLive')
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.add_category(
|
||||
unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar)
|
||||
action_list.add_action(self.previousItem)
|
||||
action_list.add_action(self.nextItem)
|
||||
self.previousService = shortcut_action(parent, u'previousService',
|
||||
[QtCore.Qt.Key_Left], self.servicePrevious,
|
||||
category=unicode(UiStrings().LiveToolbar),
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
self.previousService.setText(
|
||||
translate('OpenLP.SlideController', 'Previous Service'))
|
||||
self.nextService = shortcut_action(parent, 'nextService',
|
||||
[QtCore.Qt.Key_Right], self.serviceNext,
|
||||
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'))
|
||||
self.previousService = create_action(parent, u'previousService',
|
||||
text=translate('OpenLP.SlideController', 'Previous Service'),
|
||||
shortcuts=[QtCore.Qt.Key_Left],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.servicePrevious)
|
||||
self.nextService = create_action(parent, 'nextService',
|
||||
text=translate('OpenLP.SlideController', 'Next Service'),
|
||||
shortcuts=[QtCore.Qt.Key_Right],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.serviceNext)
|
||||
self.escapeItem = create_action(parent, 'escapeItem',
|
||||
text=translate('OpenLP.SlideController', 'Escape Item'),
|
||||
shortcuts=[QtCore.Qt.Key_Escape],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.liveEscape)
|
||||
|
||||
def liveEscape(self):
|
||||
self.display.setVisible(False)
|
||||
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):
|
||||
"""
|
||||
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()
|
||||
|
||||
def serviceNext(self):
|
||||
"""
|
||||
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()
|
||||
|
||||
def _process_queue(self):
|
||||
|
@ -592,8 +558,13 @@ class SlideController(Controller):
|
|||
if len(self.keypress_queue):
|
||||
while len(self.keypress_queue) and not self.keypress_loop:
|
||||
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')
|
||||
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
|
||||
# Go to the last slide of the previous item
|
||||
Receiver.send_message('servicemanager_previous_item',
|
||||
u'last slide')
|
||||
else:
|
||||
Receiver.send_message('servicemanager_next_item')
|
||||
self.keypress_loop = False
|
||||
|
@ -611,15 +582,20 @@ class SlideController(Controller):
|
|||
self.display.setup()
|
||||
if self.isLive:
|
||||
self.__addActionsToWidget(self.display)
|
||||
self.display.audioPlayer.connectSlot(
|
||||
QtCore.SIGNAL(u'tick(qint64)'), self.onAudioTimeRemaining)
|
||||
# The SlidePreview's ratio.
|
||||
try:
|
||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||
float(self.screens.current[u'size'].height())
|
||||
except ZeroDivisionError:
|
||||
self.ratio = 1
|
||||
self.mediaController.setup_display(self.display)
|
||||
self.previewSizeChanged()
|
||||
self.previewDisplay.setup()
|
||||
serviceItem = 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))
|
||||
self.mediaController.setup_display(self.previewDisplay)
|
||||
if self.serviceItem:
|
||||
|
@ -682,6 +658,14 @@ class SlideController(Controller):
|
|||
"""
|
||||
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):
|
||||
"""
|
||||
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
|
||||
# See bug #791050
|
||||
self.toolbar.hide()
|
||||
self.mediabar.setVisible(False)
|
||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
||||
self.mediabar.hide()
|
||||
self.songMenu.hide()
|
||||
self.toolbar.setWidgetVisible(self.loopList, False)
|
||||
# Reset the button
|
||||
self.playSlidesOnce.setChecked(False)
|
||||
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
|
||||
|
@ -711,17 +695,16 @@ class SlideController(Controller):
|
|||
if QtCore.QSettings().value(
|
||||
self.parent().songsSettingsSection + u'/display songbar',
|
||||
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 \
|
||||
len(item.get_frames()) > 1:
|
||||
self.toolbar.makeWidgetsVisible(self.loopList)
|
||||
self.toolbar.setWidgetVisible(self.loopList)
|
||||
if item.is_media():
|
||||
self.mediabar.setVisible(True)
|
||||
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
|
||||
else:
|
||||
self.mediabar.show()
|
||||
self.previousItem.setVisible(not item.is_media())
|
||||
self.nextItem.setVisible(not item.is_media())
|
||||
# Work-around for OS X, hide and then show the toolbar
|
||||
# See bug #791050
|
||||
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
|
||||
self.toolbar.show()
|
||||
|
||||
def enablePreviewToolBar(self, item):
|
||||
|
@ -731,17 +714,16 @@ class SlideController(Controller):
|
|||
# Work-around for OS X, hide and then show the toolbar
|
||||
# See bug #791050
|
||||
self.toolbar.hide()
|
||||
self.mediabar.setVisible(False)
|
||||
self.toolbar.makeWidgetsInvisible(self.songEditList)
|
||||
self.mediabar.hide()
|
||||
self.toolbar.setWidgetVisible([u'editSong'], False)
|
||||
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
|
||||
self.toolbar.makeWidgetsVisible(self.songEditList)
|
||||
self.toolbar.setWidgetVisible([u'editSong'])
|
||||
elif item.is_media():
|
||||
self.mediabar.setVisible(True)
|
||||
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
|
||||
if not item.is_media():
|
||||
self.mediabar.show()
|
||||
self.previousItem.setVisible(not item.is_media())
|
||||
self.nextItem.setVisible(not item.is_media())
|
||||
# Work-around for OS X, hide and then show the toolbar
|
||||
# See bug #791050
|
||||
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
|
||||
self.toolbar.show()
|
||||
|
||||
def refreshServiceItem(self):
|
||||
|
@ -818,10 +800,23 @@ class SlideController(Controller):
|
|||
self.display.audioPlayer.reset()
|
||||
self.setAudioItemsVisibility(False)
|
||||
self.audioPauseItem.setChecked(False)
|
||||
# If the current item has background audio
|
||||
if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
log.debug(u'Starting to play...')
|
||||
self.display.audioPlayer.addToPlaylist(
|
||||
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(
|
||||
self.parent().generalSettingsSection + \
|
||||
u'/audio start paused',
|
||||
|
@ -873,7 +868,7 @@ class SlideController(Controller):
|
|||
self.slideList[unicode(row)] = row - 1
|
||||
text.append(unicode(row))
|
||||
self.previewListWidget.setItem(framenumber, 0, item)
|
||||
if slideHeight != 0:
|
||||
if slideHeight:
|
||||
self.previewListWidget.setRowHeight(framenumber, slideHeight)
|
||||
self.previewListWidget.setVerticalHeaderLabels(text)
|
||||
if self.serviceItem.is_text():
|
||||
|
@ -938,7 +933,8 @@ class SlideController(Controller):
|
|||
display_type = QtCore.QSettings().value(
|
||||
self.parent().generalSettingsSection + u'/screen blank',
|
||||
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
|
||||
if display_type == u'themed':
|
||||
self.onThemeDisplay(True)
|
||||
|
@ -949,7 +945,7 @@ class SlideController(Controller):
|
|||
else:
|
||||
Receiver.send_message(u'live_display_show')
|
||||
else:
|
||||
Receiver.send_message(u'live_display_hide', HideMode.Screen)
|
||||
self.liveEscape()
|
||||
|
||||
def onSlideBlank(self):
|
||||
"""
|
||||
|
@ -1074,7 +1070,7 @@ class SlideController(Controller):
|
|||
else:
|
||||
Receiver.send_message(u'live_display_show')
|
||||
|
||||
def onSlideSelected(self, start=False):
|
||||
def onSlideSelected(self):
|
||||
"""
|
||||
Slide selected in controller
|
||||
"""
|
||||
|
@ -1087,7 +1083,7 @@ class SlideController(Controller):
|
|||
"""
|
||||
row = self.previewListWidget.currentRow()
|
||||
self.selectedRow = 0
|
||||
if row > -1 and row < self.previewListWidget.rowCount():
|
||||
if -1 < row < self.previewListWidget.rowCount():
|
||||
if self.serviceItem.is_command():
|
||||
if self.isLive and not start:
|
||||
Receiver.send_message(
|
||||
|
@ -1144,6 +1140,13 @@ class SlideController(Controller):
|
|||
rect.y(), rect.width(), rect.height())
|
||||
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):
|
||||
"""
|
||||
Go to the next slide.
|
||||
|
@ -1158,10 +1161,14 @@ class SlideController(Controller):
|
|||
row = self.previewListWidget.currentRow() + 1
|
||||
if row == self.previewListWidget.rowCount():
|
||||
if wrap is None:
|
||||
wrap = QtCore.QSettings().value(
|
||||
self.parent().generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool()
|
||||
if wrap:
|
||||
if self.slide_limits == SlideLimits.Wrap:
|
||||
row = 0
|
||||
elif self.isLive and self.slide_limits == SlideLimits.Next:
|
||||
self.serviceNext()
|
||||
return
|
||||
else:
|
||||
row = self.previewListWidget.rowCount() - 1
|
||||
elif wrap:
|
||||
row = 0
|
||||
else:
|
||||
row = self.previewListWidget.rowCount() - 1
|
||||
|
@ -1181,9 +1188,13 @@ class SlideController(Controller):
|
|||
else:
|
||||
row = self.previewListWidget.currentRow() - 1
|
||||
if row == -1:
|
||||
if QtCore.QSettings().value(self.parent().generalSettingsSection
|
||||
+ u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
if self.slide_limits == SlideLimits.Wrap:
|
||||
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:
|
||||
row = 0
|
||||
self.__checkUpdateSelectedSlide(row)
|
||||
|
@ -1216,7 +1227,7 @@ class SlideController(Controller):
|
|||
"""
|
||||
Stop the timer loop running
|
||||
"""
|
||||
if self.timer_id != 0:
|
||||
if self.timer_id:
|
||||
self.killTimer(self.timer_id)
|
||||
self.timer_id = 0
|
||||
|
||||
|
@ -1263,7 +1274,7 @@ class SlideController(Controller):
|
|||
self.onToggleLoop()
|
||||
|
||||
def setAudioItemsVisibility(self, visible):
|
||||
self.audioPauseItem.setVisible(visible)
|
||||
self.toolbar.setWidgetVisible(self.audioList, visible)
|
||||
|
||||
def onAudioPauseClicked(self, checked):
|
||||
if not self.audioPauseItem.isVisible():
|
||||
|
@ -1317,7 +1328,7 @@ class SlideController(Controller):
|
|||
If preview copy slide item to live
|
||||
"""
|
||||
row = self.previewListWidget.currentRow()
|
||||
if row > -1 and row < self.previewListWidget.rowCount():
|
||||
if -1 < row < self.previewListWidget.rowCount():
|
||||
if self.serviceItem.from_service:
|
||||
Receiver.send_message('servicemanager_preview_live',
|
||||
u'%s:%s' % (self.serviceItem._uuid, row))
|
||||
|
@ -1374,3 +1385,17 @@ class SlideController(Controller):
|
|||
return HideMode.Screen
|
||||
else:
|
||||
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 #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -359,11 +359,15 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||
self.gradientEndButton.setStyleSheet(u'background-color: %s' %
|
||||
self.theme.background_end_color)
|
||||
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.theme.background_border_color)
|
||||
self.imageFileEdit.setText(self.theme.background_filename)
|
||||
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 == \
|
||||
BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
|
||||
self.setField(u'gradient', QtCore.QVariant(0))
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -30,6 +30,7 @@ import zipfile
|
|||
import shutil
|
||||
import logging
|
||||
import locale
|
||||
import re
|
||||
|
||||
from xml.etree.ElementTree import ElementTree, XML
|
||||
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, \
|
||||
BackgroundGradientType
|
||||
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.ui import FileRenameForm, ThemeForm
|
||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||
get_filesystem_encoding
|
||||
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -64,32 +64,32 @@ class ThemeManager(QtGui.QWidget):
|
|||
self.layout.setMargin(0)
|
||||
self.layout.setObjectName(u'layout')
|
||||
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.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.themeWidget = QtGui.QWidgetAction(self.toolbar)
|
||||
self.themeWidget.setObjectName(u'themeWidget')
|
||||
|
@ -105,29 +105,26 @@ class ThemeManager(QtGui.QWidget):
|
|||
self.contextMenu)
|
||||
# build the context menu
|
||||
self.menu = QtGui.QMenu()
|
||||
self.editAction = context_menu_action(
|
||||
self.menu, u':/themes/theme_edit.png',
|
||||
translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme)
|
||||
self.copyAction = context_menu_action(
|
||||
self.menu, u':/themes/theme_edit.png',
|
||||
translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme)
|
||||
self.renameAction = context_menu_action(
|
||||
self.menu, u':/themes/theme_edit.png',
|
||||
translate('OpenLP.ThemeManager', '&Rename Theme'),
|
||||
self.onRenameTheme)
|
||||
self.deleteAction = context_menu_action(
|
||||
self.menu, u':/general/general_delete.png',
|
||||
translate('OpenLP.ThemeManager', '&Delete Theme'),
|
||||
self.onDeleteTheme)
|
||||
context_menu_separator(self.menu)
|
||||
self.globalAction = context_menu_action(
|
||||
self.menu, u':/general/general_export.png',
|
||||
translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
||||
self.changeGlobalFromScreen)
|
||||
self.exportAction = context_menu_action(
|
||||
self.menu, u':/general/general_export.png',
|
||||
translate('OpenLP.ThemeManager', '&Export Theme'),
|
||||
self.onExportTheme)
|
||||
self.editAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
|
||||
self.copyAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
|
||||
self.renameAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
|
||||
self.deleteAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
|
||||
icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
|
||||
self.menu.addSeparator()
|
||||
self.globalAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
||||
icon=u':/general/general_export.png',
|
||||
triggers=self.changeGlobalFromScreen)
|
||||
self.exportAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Export Theme'),
|
||||
icon=u':/general/general_export.png', triggers=self.onExportTheme)
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.themeListWidget,
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||
|
@ -140,13 +137,14 @@ class ThemeManager(QtGui.QWidget):
|
|||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
|
||||
# Variables
|
||||
self.themelist = []
|
||||
self.theme_list = []
|
||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||
check_directory_exists(self.path)
|
||||
self.thumbPath = os.path.join(self.path, u'thumbnails')
|
||||
check_directory_exists(self.thumbPath)
|
||||
self.thumb_path = os.path.join(self.path, u'thumbnails')
|
||||
check_directory_exists(self.thumb_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
|
||||
self.configUpdated()
|
||||
|
||||
|
@ -155,10 +153,9 @@ class ThemeManager(QtGui.QWidget):
|
|||
Import new themes downloaded by the first time wizard
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
encoding = get_filesystem_encoding()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
||||
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)
|
||||
delete_file(file)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
@ -177,10 +174,10 @@ class ThemeManager(QtGui.QWidget):
|
|||
"""
|
||||
if item is None:
|
||||
return
|
||||
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
themeName = unicode(item.text())
|
||||
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
theme_name = unicode(item.text())
|
||||
# If default theme restrict actions
|
||||
if realThemeName == themeName:
|
||||
if real_theme_name == theme_name:
|
||||
self.deleteToolbarAction.setVisible(True)
|
||||
else:
|
||||
self.deleteToolbarAction.setVisible(False)
|
||||
|
@ -193,35 +190,35 @@ class ThemeManager(QtGui.QWidget):
|
|||
item = self.themeListWidget.itemAt(point)
|
||||
if item is None:
|
||||
return
|
||||
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
themeName = unicode(item.text())
|
||||
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
theme_name = unicode(item.text())
|
||||
self.deleteAction.setVisible(False)
|
||||
self.renameAction.setVisible(False)
|
||||
self.globalAction.setVisible(False)
|
||||
# If default theme restrict actions
|
||||
if realThemeName == themeName:
|
||||
if real_theme_name == theme_name:
|
||||
self.deleteAction.setVisible(True)
|
||||
self.renameAction.setVisible(True)
|
||||
self.globalAction.setVisible(True)
|
||||
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
|
||||
tab
|
||||
"""
|
||||
log.debug(u'changeGlobalFromTab %s', themeName)
|
||||
log.debug(u'changeGlobalFromTab %s', theme_name)
|
||||
for count in range (0, self.themeListWidget.count()):
|
||||
# reset the old name
|
||||
item = self.themeListWidget.item(count)
|
||||
oldName = item.text()
|
||||
newName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
if oldName != newName:
|
||||
self.themeListWidget.item(count).setText(newName)
|
||||
old_name = item.text()
|
||||
new_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
if old_name != new_name:
|
||||
self.themeListWidget.item(count).setText(new_name)
|
||||
# Set the new name
|
||||
if themeName == newName:
|
||||
if theme_name == new_name:
|
||||
name = unicode(translate('OpenLP.ThemeManager',
|
||||
'%s (default)')) % newName
|
||||
'%s (default)')) % new_name
|
||||
self.themeListWidget.item(count).setText(name)
|
||||
|
||||
def changeGlobalFromScreen(self, index=-1):
|
||||
|
@ -233,9 +230,9 @@ class ThemeManager(QtGui.QWidget):
|
|||
selected_row = self.themeListWidget.currentRow()
|
||||
for count in range (0, self.themeListWidget.count()):
|
||||
item = self.themeListWidget.item(count)
|
||||
oldName = item.text()
|
||||
old_name = item.text()
|
||||
# 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(
|
||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||
# Set the new name
|
||||
|
@ -271,19 +268,19 @@ class ThemeManager(QtGui.QWidget):
|
|||
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
|
||||
False, False):
|
||||
item = self.themeListWidget.currentItem()
|
||||
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
|
||||
old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
self.fileRenameForm.fileNameEdit.setText(old_theme_name)
|
||||
if self.fileRenameForm.exec_():
|
||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||
if oldThemeName == newThemeName:
|
||||
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||
if old_theme_name == new_theme_name:
|
||||
return
|
||||
if self.checkIfThemeExists(newThemeName):
|
||||
oldThemeData = self.getThemeData(oldThemeName)
|
||||
self.cloneThemeData(oldThemeData, newThemeName)
|
||||
self.deleteTheme(oldThemeName)
|
||||
if self.checkIfThemeExists(new_theme_name):
|
||||
old_theme_data = self.getThemeData(old_theme_name)
|
||||
self.cloneThemeData(old_theme_data, new_theme_name)
|
||||
self.deleteTheme(old_theme_name)
|
||||
for plugin in self.mainwindow.pluginManager.plugins:
|
||||
if plugin.usesTheme(oldThemeName):
|
||||
plugin.renameTheme(oldThemeName, newThemeName)
|
||||
if plugin.usesTheme(old_theme_name):
|
||||
plugin.renameTheme(old_theme_name, new_theme_name)
|
||||
self.loadThemes()
|
||||
|
||||
def onCopyTheme(self):
|
||||
|
@ -291,30 +288,30 @@ class ThemeManager(QtGui.QWidget):
|
|||
Copies an existing theme to a new name
|
||||
"""
|
||||
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(
|
||||
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):
|
||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||
if self.checkIfThemeExists(newThemeName):
|
||||
themeData = self.getThemeData(oldThemeName)
|
||||
self.cloneThemeData(themeData, newThemeName)
|
||||
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||
if self.checkIfThemeExists(new_theme_name):
|
||||
theme_data = self.getThemeData(old_theme_name)
|
||||
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.
|
||||
"""
|
||||
log.debug(u'cloneThemeData')
|
||||
saveTo = None
|
||||
saveFrom = None
|
||||
if themeData.background_type == u'image':
|
||||
saveTo = os.path.join(self.path, newThemeName,
|
||||
os.path.split(unicode(themeData.background_filename))[1])
|
||||
saveFrom = themeData.background_filename
|
||||
themeData.theme_name = newThemeName
|
||||
themeData.extend_image_filename(self.path)
|
||||
self.saveTheme(themeData, saveFrom, saveTo)
|
||||
save_to = None
|
||||
save_from = None
|
||||
if theme_data.background_type == u'image':
|
||||
save_to = os.path.join(self.path, new_theme_name,
|
||||
os.path.split(unicode(theme_data.background_filename))[1])
|
||||
save_from = theme_data.background_filename
|
||||
theme_data.theme_name = new_theme_name
|
||||
theme_data.extend_image_filename(self.path)
|
||||
self.saveTheme(theme_data, save_from, save_to)
|
||||
|
||||
def onEditTheme(self):
|
||||
"""
|
||||
|
@ -328,10 +325,10 @@ class ThemeManager(QtGui.QWidget):
|
|||
theme = self.getThemeData(
|
||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||
if theme.background_type == u'image':
|
||||
self.oldBackgroundImage = theme.background_filename
|
||||
self.old_background_image = theme.background_filename
|
||||
self.themeForm.theme = theme
|
||||
self.themeForm.exec_(True)
|
||||
self.oldBackgroundImage = None
|
||||
self.old_background_image = None
|
||||
|
||||
def onDeleteTheme(self):
|
||||
"""
|
||||
|
@ -357,10 +354,10 @@ class ThemeManager(QtGui.QWidget):
|
|||
``theme``
|
||||
The theme to delete.
|
||||
"""
|
||||
self.themelist.remove(theme)
|
||||
self.theme_list.remove(theme)
|
||||
thumb = u'%s.png' % theme
|
||||
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:
|
||||
encoding = get_filesystem_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')
|
||||
if path:
|
||||
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
|
||||
try:
|
||||
zip = zipfile.ZipFile(themePath, u'w')
|
||||
zip = zipfile.ZipFile(theme_path, u'w')
|
||||
source = os.path.join(self.path, theme)
|
||||
for files in os.walk(source):
|
||||
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.
|
||||
"""
|
||||
log.debug(u'Load themes from dir')
|
||||
self.themelist = []
|
||||
self.theme_list = []
|
||||
self.themeListWidget.clear()
|
||||
dirList = os.listdir(self.path)
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
if firstTime:
|
||||
self.firstTime()
|
||||
|
@ -457,29 +453,29 @@ class ThemeManager(QtGui.QWidget):
|
|||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
# Sort the themes by its name considering language specific characters.
|
||||
# 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)
|
||||
# now process the file list of png files
|
||||
for name in files:
|
||||
# check to see file is in theme root directory
|
||||
theme = os.path.join(self.path, name)
|
||||
if os.path.exists(theme):
|
||||
textName = os.path.splitext(name)[0]
|
||||
if textName == self.global_theme:
|
||||
text_name = os.path.splitext(name)[0]
|
||||
if text_name == self.global_theme:
|
||||
name = unicode(translate('OpenLP.ThemeManager',
|
||||
'%s (default)')) % textName
|
||||
'%s (default)')) % text_name
|
||||
else:
|
||||
name = textName
|
||||
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
|
||||
name = text_name
|
||||
thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
|
||||
item_name = QtGui.QListWidgetItem(name)
|
||||
if validate_thumb(theme, thumb):
|
||||
icon = build_icon(thumb)
|
||||
else:
|
||||
icon = create_thumb(theme, thumb)
|
||||
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.themelist.append(textName)
|
||||
self.theme_list.append(text_name)
|
||||
self._pushThemes()
|
||||
|
||||
def _pushThemes(self):
|
||||
|
@ -492,86 +488,111 @@ class ThemeManager(QtGui.QWidget):
|
|||
"""
|
||||
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
|
||||
|
||||
``themeName``
|
||||
``theme_name``
|
||||
Name of the theme to load from file
|
||||
"""
|
||||
log.debug(u'getthemedata for theme %s', themeName)
|
||||
xmlFile = os.path.join(self.path, unicode(themeName),
|
||||
unicode(themeName) + u'.xml')
|
||||
xml = get_text_file_string(xmlFile)
|
||||
log.debug(u'getthemedata for theme %s', theme_name)
|
||||
xml_file = os.path.join(self.path, unicode(theme_name),
|
||||
unicode(theme_name) + u'.xml')
|
||||
xml = get_text_file_string(xml_file)
|
||||
if not xml:
|
||||
log.debug("No theme data - using default theme")
|
||||
return ThemeXML()
|
||||
else:
|
||||
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
|
||||
Generate a new preview file. Check the XML theme version and upgrade if
|
||||
necessary.
|
||||
"""
|
||||
log.debug(u'Unzipping theme %s', filename)
|
||||
filename = unicode(filename)
|
||||
log.debug(u'Unzipping theme %s', file_name)
|
||||
file_name = unicode(file_name)
|
||||
zip = None
|
||||
outfile = None
|
||||
filexml = None
|
||||
out_file = None
|
||||
file_xml = None
|
||||
try:
|
||||
zip = zipfile.ZipFile(filename)
|
||||
themename = None
|
||||
for file in zip.namelist():
|
||||
# Handle UTF-8 files
|
||||
ucsfile = file_is_unicode(file)
|
||||
if not ucsfile:
|
||||
# Handle native Unicode files from Windows
|
||||
ucsfile = file
|
||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
||||
theme_dir = None
|
||||
if osfile.endswith(os.path.sep):
|
||||
theme_dir = os.path.join(dir, osfile)
|
||||
check_directory_exists(theme_dir)
|
||||
zip = zipfile.ZipFile(file_name)
|
||||
xml_file = filter(lambda name:
|
||||
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
|
||||
if len(xml_file) != 1:
|
||||
log.exception(u'Theme contains "%s" XML files' % len(xml_file))
|
||||
raise Exception(u'validation')
|
||||
xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
|
||||
v1_background = xml_tree.find(u'BackgroundType')
|
||||
if v1_background is not None:
|
||||
theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
|
||||
xml_file[0], xml_tree, v1_background, out_file)
|
||||
else:
|
||||
fullpath = os.path.join(dir, osfile)
|
||||
names = osfile.split(os.path.sep)
|
||||
if len(names) > 1:
|
||||
# not preview file
|
||||
if themename is None:
|
||||
themename = names[0]
|
||||
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'))
|
||||
theme_name = xml_tree.find(u'name').text.strip()
|
||||
theme_folder = os.path.join(dir, theme_name)
|
||||
theme_exists = os.path.exists(theme_folder)
|
||||
if theme_exists and not self.overWriteMessageBox(theme_name):
|
||||
abort_import = True
|
||||
return
|
||||
else:
|
||||
outfile = open(fullpath, u'wb')
|
||||
outfile.write(zip.read(file))
|
||||
except (IOError, NameError, zipfile.BadZipfile):
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
||||
log.exception(u'Importing theme from zip failed %s' % filename)
|
||||
abort_import = False
|
||||
for name in zip.namelist():
|
||||
try:
|
||||
uname = unicode(name, u'utf-8')
|
||||
except UnicodeDecodeError:
|
||||
log.exception(u'Theme file contains non utf-8 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:
|
||||
# Close the files, to be able to continue creating the theme.
|
||||
if zip:
|
||||
zip.close()
|
||||
if outfile:
|
||||
outfile.close()
|
||||
if out_file:
|
||||
out_file.close()
|
||||
if not abort_import:
|
||||
# As all files are closed, we can create the Theme.
|
||||
if filexml:
|
||||
theme = self._createThemeFromXml(filexml, self.path)
|
||||
self.generateAndSaveImage(dir, themename, theme)
|
||||
if file_xml:
|
||||
theme = self._createThemeFromXml(file_xml, self.path)
|
||||
self.generateAndSaveImage(dir, theme_name, theme)
|
||||
# Only show the error message, when IOError was not raised (in this
|
||||
# case the error message has already been shown).
|
||||
elif zip is not None:
|
||||
|
@ -580,16 +601,50 @@ class ThemeManager(QtGui.QWidget):
|
|||
translate('OpenLP.ThemeManager',
|
||||
'File is not a valid theme.'))
|
||||
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
|
||||
|
||||
``themeName``
|
||||
``theme_name``
|
||||
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):
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
|
@ -598,12 +653,12 @@ class ThemeManager(QtGui.QWidget):
|
|||
return False
|
||||
return True
|
||||
|
||||
def saveTheme(self, theme, imageFrom, imageTo):
|
||||
def saveTheme(self, theme, image_from, image_to):
|
||||
"""
|
||||
Called by thememaintenance Dialog to save the theme
|
||||
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 == \
|
||||
BackgroundType.to_string(BackgroundType.Image):
|
||||
self.mainwindow.imageManager.update_image(theme.theme_name,
|
||||
|
@ -611,7 +666,7 @@ class ThemeManager(QtGui.QWidget):
|
|||
self.mainwindow.imageManager.process_updates()
|
||||
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
|
||||
necessary
|
||||
|
@ -622,24 +677,24 @@ class ThemeManager(QtGui.QWidget):
|
|||
theme_dir = os.path.join(self.path, name)
|
||||
check_directory_exists(theme_dir)
|
||||
theme_file = os.path.join(theme_dir, name + u'.xml')
|
||||
if self.oldBackgroundImage and \
|
||||
imageTo != self.oldBackgroundImage:
|
||||
delete_file(self.oldBackgroundImage)
|
||||
outfile = None
|
||||
if self.old_background_image and \
|
||||
image_to != self.old_background_image:
|
||||
delete_file(self.old_background_image)
|
||||
out_file = None
|
||||
try:
|
||||
outfile = open(theme_file, u'w')
|
||||
outfile.write(theme_pretty_xml)
|
||||
out_file = open(theme_file, u'w')
|
||||
out_file.write(theme_pretty_xml)
|
||||
except IOError:
|
||||
log.exception(u'Saving theme to file failed')
|
||||
finally:
|
||||
if outfile:
|
||||
outfile.close()
|
||||
if imageFrom and imageFrom != imageTo:
|
||||
if out_file:
|
||||
out_file.close()
|
||||
if image_from and image_from != image_to:
|
||||
try:
|
||||
encoding = get_filesystem_encoding()
|
||||
shutil.copyfile(
|
||||
unicode(imageFrom).encode(encoding),
|
||||
unicode(imageTo).encode(encoding))
|
||||
unicode(image_from).encode(encoding),
|
||||
unicode(image_to).encode(encoding))
|
||||
except IOError:
|
||||
log.exception(u'Failed to save theme image')
|
||||
self.generateAndSaveImage(self.path, name, theme)
|
||||
|
@ -647,39 +702,39 @@ class ThemeManager(QtGui.QWidget):
|
|||
def generateAndSaveImage(self, dir, name, theme):
|
||||
log.debug(u'generateAndSaveImage %s %s', dir, name)
|
||||
frame = self.generateImage(theme)
|
||||
samplepathname = os.path.join(self.path, name + u'.png')
|
||||
if os.path.exists(samplepathname):
|
||||
os.unlink(samplepathname)
|
||||
frame.save(samplepathname, u'png')
|
||||
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
|
||||
create_thumb(samplepathname, thumb, False)
|
||||
log.debug(u'Theme image written to %s', samplepathname)
|
||||
sample_path_name = os.path.join(self.path, name + u'.png')
|
||||
if os.path.exists(sample_path_name):
|
||||
os.unlink(sample_path_name)
|
||||
frame.save(sample_path_name, u'png')
|
||||
thumb = os.path.join(self.thumb_path, u'%s.png' % name)
|
||||
create_thumb(sample_path_name, thumb, False)
|
||||
log.debug(u'Theme image written to %s', sample_path_name)
|
||||
|
||||
def updatePreviewImages(self):
|
||||
"""
|
||||
Called to update the themes' preview images.
|
||||
"""
|
||||
self.mainwindow.displayProgressBar(len(self.themelist))
|
||||
for theme in self.themelist:
|
||||
self.mainwindow.displayProgressBar(len(self.theme_list))
|
||||
for theme in self.theme_list:
|
||||
self.mainwindow.incrementProgressBar()
|
||||
self.generateAndSaveImage(
|
||||
self.path, theme, self.getThemeData(theme))
|
||||
self.mainwindow.finishedProgressBar()
|
||||
self.loadThemes()
|
||||
|
||||
def generateImage(self, themeData, forcePage=False):
|
||||
def generateImage(self, theme_data, forcePage=False):
|
||||
"""
|
||||
Call the renderer to build a Sample Image
|
||||
|
||||
``themeData``
|
||||
``theme_data``
|
||||
The theme to generated a preview for.
|
||||
|
||||
``forcePage``
|
||||
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(
|
||||
themeData, forcePage)
|
||||
theme_data, forcePage)
|
||||
|
||||
def getPreviewImage(self, theme):
|
||||
"""
|
||||
|
@ -692,31 +747,15 @@ class ThemeManager(QtGui.QWidget):
|
|||
image = os.path.join(self.path, theme + u'.png')
|
||||
return image
|
||||
|
||||
def _checkVersionAndConvert(self, xml_data):
|
||||
"""
|
||||
Check if a theme is from OpenLP version 1
|
||||
|
||||
``xml_data``
|
||||
Theme XML to check the version of
|
||||
"""
|
||||
log.debug(u'checkVersion1 ')
|
||||
theme = xml_data.encode(u'ascii', u'xmlcharrefreplace')
|
||||
tree = ElementTree(element=XML(theme)).getroot()
|
||||
# look for old version 1 tags
|
||||
if tree.find(u'BackgroundType') is None:
|
||||
return xml_data
|
||||
else:
|
||||
return self._migrateVersion122(xml_data)
|
||||
|
||||
def _createThemeFromXml(self, themeXml, path):
|
||||
def _createThemeFromXml(self, theme_xml, path):
|
||||
"""
|
||||
Return a theme object using information parsed from XML
|
||||
|
||||
``themeXml``
|
||||
``theme_xml``
|
||||
The XML data to load into the theme
|
||||
"""
|
||||
theme = ThemeXML()
|
||||
theme.parse(themeXml)
|
||||
theme.parse(theme_xml)
|
||||
theme.extend_image_filename(path)
|
||||
return theme
|
||||
|
||||
|
@ -771,50 +810,53 @@ class ThemeManager(QtGui.QWidget):
|
|||
Version 1 theme to convert
|
||||
"""
|
||||
theme = Theme(xml_data)
|
||||
newtheme = ThemeXML()
|
||||
newtheme.theme_name = theme.Name
|
||||
new_theme = ThemeXML()
|
||||
new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
|
||||
if theme.BackgroundType == 0:
|
||||
newtheme.background_type = \
|
||||
new_theme.background_type = \
|
||||
BackgroundType.to_string(BackgroundType.Solid)
|
||||
newtheme.background_color = \
|
||||
new_theme.background_color = \
|
||||
unicode(theme.BackgroundParameter1.name())
|
||||
elif theme.BackgroundType == 1:
|
||||
newtheme.background_type = \
|
||||
new_theme.background_type = \
|
||||
BackgroundType.to_string(BackgroundType.Gradient)
|
||||
newtheme.background_direction = \
|
||||
new_theme.background_direction = \
|
||||
BackgroundGradientType. \
|
||||
to_string(BackgroundGradientType.Horizontal)
|
||||
if theme.BackgroundParameter3.name() == 1:
|
||||
newtheme.background_direction = \
|
||||
new_theme.background_direction = \
|
||||
BackgroundGradientType. \
|
||||
to_string(BackgroundGradientType.Horizontal)
|
||||
newtheme.background_start_color = \
|
||||
new_theme.background_start_color = \
|
||||
unicode(theme.BackgroundParameter1.name())
|
||||
newtheme.background_end_color = \
|
||||
new_theme.background_end_color = \
|
||||
unicode(theme.BackgroundParameter2.name())
|
||||
else:
|
||||
newtheme.background_type = \
|
||||
elif theme.BackgroundType == 2:
|
||||
new_theme.background_type = \
|
||||
BackgroundType.to_string(BackgroundType.Image)
|
||||
newtheme.background_filename = unicode(theme.BackgroundParameter1)
|
||||
newtheme.font_main_name = theme.FontName
|
||||
newtheme.font_main_color = unicode(theme.FontColor.name())
|
||||
newtheme.font_main_size = theme.FontProportion * 3
|
||||
newtheme.font_footer_name = theme.FontName
|
||||
newtheme.font_footer_color = unicode(theme.FontColor.name())
|
||||
newtheme.font_main_shadow = False
|
||||
new_theme.background_filename = unicode(theme.BackgroundParameter1)
|
||||
elif theme.BackgroundType == 3:
|
||||
new_theme.background_type = \
|
||||
BackgroundType.to_string(BackgroundType.Transparent)
|
||||
new_theme.font_main_name = theme.FontName
|
||||
new_theme.font_main_color = unicode(theme.FontColor.name())
|
||||
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:
|
||||
newtheme.font_main_shadow = True
|
||||
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
|
||||
new_theme.font_main_shadow = True
|
||||
new_theme.font_main_shadow_color = unicode(theme.ShadowColor.name())
|
||||
if theme.Outline == 1:
|
||||
newtheme.font_main_outline = True
|
||||
newtheme.font_main_outline_color = \
|
||||
new_theme.font_main_outline = True
|
||||
new_theme.font_main_outline_color = \
|
||||
unicode(theme.OutlineColor.name())
|
||||
vAlignCorrection = VerticalType.Top
|
||||
if theme.VerticalAlign == 2:
|
||||
vAlignCorrection = VerticalType.Middle
|
||||
elif theme.VerticalAlign == 1:
|
||||
vAlignCorrection = VerticalType.Bottom
|
||||
newtheme.display_horizontal_align = theme.HorizontalAlign
|
||||
newtheme.display_vertical_align = vAlignCorrection
|
||||
return newtheme.extract_xml()
|
||||
new_theme.display_horizontal_align = theme.HorizontalAlign
|
||||
new_theme.display_vertical_align = vAlignCorrection
|
||||
return new_theme.extract_xml()
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -54,7 +54,7 @@ class Ui_ThemeWizard(object):
|
|||
self.backgroundLabel = QtGui.QLabel(self.backgroundPage)
|
||||
self.backgroundLabel.setObjectName(u'BackgroundLabel')
|
||||
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.backgroundTypeLayout.addRow(self.backgroundLabel,
|
||||
self.backgroundComboBox)
|
||||
|
@ -126,6 +126,12 @@ class Ui_ThemeWizard(object):
|
|||
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
|
||||
self.imageLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
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)
|
||||
themeWizard.addPage(self.backgroundPage)
|
||||
# Main Area Page
|
||||
|
@ -432,6 +438,8 @@ class Ui_ThemeWizard(object):
|
|||
translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||
self.backgroundComboBox.setItemText(
|
||||
BackgroundType.Image, UiStrings().Image)
|
||||
self.backgroundComboBox.setItemText(BackgroundType.Transparent,
|
||||
translate('OpenLP.ThemeWizard', 'Transparent'))
|
||||
self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||
self.gradientStartLabel.setText(
|
||||
translate(u'OpenLP.ThemeWizard', 'Starting color:'))
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -47,7 +47,7 @@ class WizardStrings(object):
|
|||
CCLI = u'CCLI/SongSelect'
|
||||
CSV = u'CSV'
|
||||
EW = u'EasyWorship'
|
||||
ES = u'EasiSlides'
|
||||
ES = u'EasySlides'
|
||||
FP = u'Foilpresenter'
|
||||
OL = u'OpenLyrics'
|
||||
OS = u'OpenSong'
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -53,6 +53,8 @@ APPLICATION_VERSION = {}
|
|||
IMAGES_FILTER = None
|
||||
UNO_CONNECTION_TYPE = u'pipe'
|
||||
#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]+))?')
|
||||
|
||||
class VersionThread(QtCore.QThread):
|
||||
|
@ -400,7 +402,7 @@ def clean_filename(filename):
|
|||
"""
|
||||
if not isinstance(filename, unicode):
|
||||
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):
|
||||
"""
|
||||
|
@ -455,26 +457,6 @@ def get_web_page(url, header=None, update_openlp=False):
|
|||
log.debug(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():
|
||||
"""
|
||||
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',
|
||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
||||
u'get_uno_instance', u'delete_file', u'clean_filename']
|
||||
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||
u'delete_file', u'clean_filename']
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -188,6 +188,7 @@ class ActionList(object):
|
|||
actions or categories.
|
||||
"""
|
||||
instance = None
|
||||
shortcut_map = {}
|
||||
|
||||
def __init__(self):
|
||||
self.categories = CategoryList()
|
||||
|
@ -224,17 +225,45 @@ class ActionList(object):
|
|||
self.categories[category].actions.append(action)
|
||||
else:
|
||||
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.
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(u'shortcuts')
|
||||
shortcuts = settings.value(action.objectName(),
|
||||
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(
|
||||
[QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
||||
settings.endGroup()
|
||||
|
||||
def remove_action(self, action, category=None):
|
||||
"""
|
||||
|
@ -242,7 +271,7 @@ class ActionList(object):
|
|||
automatically removed.
|
||||
|
||||
``action``
|
||||
The QAction object to be removed.
|
||||
The ``QAction`` object to be removed.
|
||||
|
||||
``category``
|
||||
The name (unicode string) of the category, which contains the
|
||||
|
@ -252,8 +281,17 @@ class ActionList(object):
|
|||
return
|
||||
self.categories[category].actions.remove(action)
|
||||
# Remove empty categories.
|
||||
if len(self.categories[category].actions) == 0:
|
||||
if not self.categories[category].actions:
|
||||
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):
|
||||
"""
|
||||
|
@ -275,6 +313,73 @@ class ActionList(object):
|
|||
return
|
||||
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):
|
||||
"""
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -31,7 +31,7 @@ from PyQt4 import QtCore
|
|||
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||
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.utils.actions import ActionList
|
||||
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
|
||||
|
@ -133,16 +133,12 @@ class AlertsPlugin(Plugin):
|
|||
use it as their parent.
|
||||
"""
|
||||
log.info(u'add tools menu')
|
||||
self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem',
|
||||
u':/plugins/plugin_alerts.png')
|
||||
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
|
||||
self.toolsAlertItem.setStatusTip(
|
||||
translate('AlertsPlugin', 'Show an alert message.'))
|
||||
self.toolsAlertItem.setShortcut(u'F7')
|
||||
self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
|
||||
text=translate('AlertsPlugin', '&Alert'),
|
||||
icon=u':/plugins/plugin_alerts.png',
|
||||
statustip=translate('AlertsPlugin', 'Show an alert message.'),
|
||||
visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
|
||||
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):
|
||||
log.info(u'Alerts Initialising')
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -27,10 +27,10 @@
|
|||
|
||||
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.ui import base_action, UiStrings
|
||||
from openlp.core.lib.ui import create_action, UiStrings
|
||||
from openlp.core.utils.actions import ActionList
|
||||
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
||||
from openlp.plugins.bibles.forms import BibleUpgradeForm
|
||||
|
@ -93,19 +93,16 @@ class BiblePlugin(Plugin):
|
|||
self.onToolsUpgradeItemTriggered()
|
||||
|
||||
def addImportMenuItem(self, import_menu):
|
||||
self.importBibleItem = base_action(import_menu, u'importBibleItem')
|
||||
self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
|
||||
self.importBibleItem = create_action(import_menu, u'importBibleItem',
|
||||
text=translate('BiblesPlugin', '&Bible'), visible=False,
|
||||
triggers=self.onBibleImportClick)
|
||||
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):
|
||||
self.exportBibleItem = base_action(export_menu, u'exportBibleItem')
|
||||
self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
|
||||
self.exportBibleItem = create_action(export_menu, u'exportBibleItem',
|
||||
text=translate('BiblesPlugin', '&Bible'),
|
||||
visible=False)
|
||||
export_menu.addAction(self.exportBibleItem)
|
||||
self.exportBibleItem.setVisible(False)
|
||||
|
||||
def addToolsMenuItem(self, tools_menu):
|
||||
"""
|
||||
|
@ -117,17 +114,12 @@ class BiblePlugin(Plugin):
|
|||
use it as their parent.
|
||||
"""
|
||||
log.debug(u'add tools menu')
|
||||
self.toolsUpgradeItem = QtGui.QAction(tools_menu)
|
||||
self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
|
||||
self.toolsUpgradeItem.setText(
|
||||
translate('BiblesPlugin', '&Upgrade older Bibles'))
|
||||
self.toolsUpgradeItem.setStatusTip(
|
||||
translate('BiblesPlugin', 'Upgrade the Bible databases to the '
|
||||
'latest format.'))
|
||||
self.toolsUpgradeItem = create_action(tools_menu, u'toolsUpgradeItem',
|
||||
text=translate('BiblesPlugin', '&Upgrade older Bibles'),
|
||||
statustip=translate('BiblesPlugin',
|
||||
'Upgrade the Bible databases to the latest format.'),
|
||||
visible=False, triggers=self.onToolsUpgradeItemTriggered)
|
||||
tools_menu.addAction(self.toolsUpgradeItem)
|
||||
QtCore.QObject.connect(self.toolsUpgradeItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
|
||||
self.toolsUpgradeItem.setVisible(False)
|
||||
|
||||
def onToolsUpgradeItemTriggered(self):
|
||||
"""
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, Frode Woldsund #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, Frode Woldsund #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, Frode Woldsund #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, Frode Woldsund #
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -31,8 +31,16 @@ plugin.
|
|||
import logging
|
||||
import re
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
REFERENCE_MATCHES = {}
|
||||
REFERENCE_SEPARATORS = {}
|
||||
|
||||
class LayoutStyle(object):
|
||||
"""
|
||||
An enumeration for bible screen layout styles.
|
||||
|
@ -52,41 +60,198 @@ class DisplayStyle(object):
|
|||
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):
|
||||
"""
|
||||
Provides the regexes and matches to use while parsing strings for bible
|
||||
references.
|
||||
Provides matches for parsing scripture references strings.
|
||||
|
||||
``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'
|
||||
).split(u';;') # English
|
||||
# local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde'
|
||||
# ).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]}
|
||||
if len(REFERENCE_MATCHES) == 0:
|
||||
update_reference_separators()
|
||||
return REFERENCE_MATCHES[match_type]
|
||||
|
||||
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
|
||||
range_string = str(r'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?(?P<from_verse>'
|
||||
r'[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?'
|
||||
r'(?P<to_verse>[0-9]+)|%(sep_e)s)?)?') % separators
|
||||
if match_type == u'range':
|
||||
return re.compile(r'^\s*' + range_string + r'\s*$', re.UNICODE)
|
||||
elif match_type == u'range_separator':
|
||||
return re.compile(separators[u'sep_l'])
|
||||
elif match_type == u'full':
|
||||
# full reference match: <book>(<range>(,|(?=$)))+
|
||||
return re.compile(str(r'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
|
||||
r'(?P<ranges>(?:' + range_string + r'(?:%(sep_l)s|(?=\s*$)))+)\s*$')
|
||||
% separators, re.UNICODE)
|
||||
else:
|
||||
return separators[match_type]
|
||||
|
||||
def parse_reference(reference):
|
||||
def parse_reference(reference, bible, language_selection, book_ref_id=False):
|
||||
"""
|
||||
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
|
||||
|
@ -95,6 +260,16 @@ def parse_reference(reference):
|
|||
``reference``
|
||||
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.
|
||||
|
||||
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
|
||||
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:
|
||||
|
||||
``(?:(?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
|
||||
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
|
||||
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)
|
||||
|
@ -179,6 +354,51 @@ def parse_reference(reference):
|
|||
if match:
|
||||
log.debug(u'Matched reference %s' % reference)
|
||||
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')
|
||||
range_list = get_reference_match(u'range_separator').split(ranges)
|
||||
ref_list = []
|
||||
|
@ -224,16 +444,18 @@ def parse_reference(reference):
|
|||
if not to_verse:
|
||||
to_verse = -1
|
||||
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):
|
||||
ref_list.append((book, i, 1, -1))
|
||||
ref_list.append((book, to_chapter, 1, to_verse))
|
||||
ref_list.append((book_ref_id, i, 1, -1))
|
||||
ref_list.append((book_ref_id, to_chapter, 1, to_verse))
|
||||
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:
|
||||
ref_list.append((book, from_chapter, from_verse, from_verse))
|
||||
ref_list.append((book_ref_id, from_chapter,
|
||||
from_verse, from_verse))
|
||||
else:
|
||||
ref_list.append((book, from_chapter, 1, -1))
|
||||
ref_list.append((book_ref_id, from_chapter, 1, -1))
|
||||
return ref_list
|
||||
else:
|
||||
log.debug(u'Invalid reference: %s' % reference)
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 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, #
|
||||
|
@ -30,8 +30,9 @@ import logging
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
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.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
|
||||
update_reference_separators, get_reference_separator, LanguageSelection
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -90,9 +91,74 @@ class BiblesTab(SettingsTab):
|
|||
self.changeNoteLabel.setObjectName(u'changeNoteLabel')
|
||||
self.verseDisplayLayout.addRow(self.changeNoteLabel)
|
||||
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(
|
||||
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()
|
||||
# Signals and slots
|
||||
QtCore.QObject.connect(
|
||||
|
@ -110,8 +176,47 @@ class BiblesTab(SettingsTab):
|
|||
QtCore.QObject.connect(
|
||||
self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
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.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||
QtCore.QObject.connect(
|
||||
self.languageSelectionComboBox, QtCore.SIGNAL(u'activated(int)'),
|
||||
self.onLanguageSelectionComboBoxChanged)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.verseDisplayGroupBox.setTitle(
|
||||
|
@ -141,6 +246,53 @@ class BiblesTab(SettingsTab):
|
|||
'Note:\nChanges do not affect verses already in the service.'))
|
||||
self.bibleSecondCheckBox.setText(
|
||||
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):
|
||||
self.bible_theme = self.bibleThemeComboBox.currentText()
|
||||
|
@ -151,6 +303,9 @@ class BiblesTab(SettingsTab):
|
|||
def onLayoutStyleComboBoxChanged(self):
|
||||
self.layout_style = self.layoutStyleComboBox.currentIndex()
|
||||
|
||||
def onLanguageSelectionComboBoxChanged(self):
|
||||
self.language_selection = self.languageSelectionComboBox.currentIndex()
|
||||
|
||||
def onNewChaptersCheckBoxChanged(self, check_state):
|
||||
self.show_new_chapters = False
|
||||
# We have a set value convert to True/False.
|
||||
|
@ -163,6 +318,106 @@ class BiblesTab(SettingsTab):
|
|||
if check_state == QtCore.Qt.Checked:
|
||||
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):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
|
@ -180,6 +435,61 @@ class BiblesTab(SettingsTab):
|
|||
self.displayStyleComboBox.setCurrentIndex(self.display_style)
|
||||
self.layoutStyleComboBox.setCurrentIndex(self.layout_style)
|
||||
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()
|
||||
|
||||
def save(self):
|
||||
|
@ -191,8 +501,32 @@ class BiblesTab(SettingsTab):
|
|||
QtCore.QVariant(self.display_style))
|
||||
settings.setValue(u'verse 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'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()
|
||||
|
||||
def updateThemeList(self, theme_list):
|
||||
|
@ -209,3 +543,15 @@ class BiblesTab(SettingsTab):
|
|||
for theme in theme_list:
|
||||
self.bibleThemeComboBox.addItem(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