forked from openlp/openlp
- Merged trunk on 21.5.16
This commit is contained in:
commit
dcfcd3e576
@ -114,7 +114,7 @@ class CategoryActionList(object):
|
||||
if item[1] == action:
|
||||
self.actions.remove(item)
|
||||
return
|
||||
raise ValueError('Action "%s" does not exist.' % action)
|
||||
raise ValueError('Action "{action}" does not exist.'.format(action=action))
|
||||
|
||||
|
||||
class CategoryList(object):
|
||||
@ -138,7 +138,7 @@ class CategoryList(object):
|
||||
for category in self.categories:
|
||||
if category.name == key:
|
||||
return category
|
||||
raise KeyError('Category "%s" does not exist.' % key)
|
||||
raise KeyError('Category "{keY}" does not exist.'.format(key=key))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
@ -203,7 +203,7 @@ class CategoryList(object):
|
||||
if category.name == name:
|
||||
self.categories.remove(category)
|
||||
return
|
||||
raise ValueError('Category "%s" does not exist.' % name)
|
||||
raise ValueError('Category "{name}" does not exist.'.format(name=name))
|
||||
|
||||
|
||||
class ActionList(object):
|
||||
@ -272,8 +272,9 @@ class ActionList(object):
|
||||
actions.append(action)
|
||||
ActionList.shortcut_map[shortcuts[1]] = actions
|
||||
else:
|
||||
log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' %
|
||||
(shortcuts[1], action.objectName()))
|
||||
log.warning('Shortcut "{shortcut}" is removed from "{action}" because another '
|
||||
'action already uses this shortcut.'.format(shortcut=shortcuts[1],
|
||||
action=action.objectName()))
|
||||
shortcuts.remove(shortcuts[1])
|
||||
# Check the primary shortcut.
|
||||
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
||||
@ -283,8 +284,9 @@ class ActionList(object):
|
||||
actions.append(action)
|
||||
ActionList.shortcut_map[shortcuts[0]] = actions
|
||||
else:
|
||||
log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' %
|
||||
(shortcuts[0], action.objectName()))
|
||||
log.warning('Shortcut "{shortcut}" is removed from "{action}" '
|
||||
'because another action already uses this shortcut.'.format(shortcut=shortcuts[0],
|
||||
action=action.objectName()))
|
||||
shortcuts.remove(shortcuts[0])
|
||||
action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
||||
|
||||
|
@ -68,7 +68,7 @@ class LanguageManager(object):
|
||||
"""
|
||||
Find all available language files in this OpenLP install
|
||||
"""
|
||||
log.debug('Translation files: %s', AppLocation.get_directory(AppLocation.LanguageDir))
|
||||
log.debug('Translation files: {files}'.format(files=AppLocation.get_directory(AppLocation.LanguageDir)))
|
||||
trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
|
||||
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name)
|
||||
# Remove qm files from the list which start with "qt_".
|
||||
@ -93,7 +93,7 @@ class LanguageManager(object):
|
||||
"""
|
||||
language = Settings().value('core/language')
|
||||
language = str(language)
|
||||
log.info('Language file: \'%s\' Loaded from conf file' % language)
|
||||
log.info("Language file: '{language}' Loaded from conf file".format(language=language))
|
||||
if re.match(r'[[].*[]]', language):
|
||||
LanguageManager.auto_language = True
|
||||
language = re.sub(r'[\[\]]', '', language)
|
||||
@ -117,9 +117,9 @@ class LanguageManager(object):
|
||||
qm_list = LanguageManager.get_qm_list()
|
||||
language = str(qm_list[action_name])
|
||||
if LanguageManager.auto_language:
|
||||
language = '[%s]' % language
|
||||
language = '[{language}]'.format(language=language)
|
||||
Settings().setValue('core/language', language)
|
||||
log.info('Language file: \'%s\' written to conf file' % language)
|
||||
log.info("Language file: '{language}' written to conf file".format(language=language))
|
||||
if message:
|
||||
QtWidgets.QMessageBox.information(None,
|
||||
translate('OpenLP.LanguageManager', 'Language'),
|
||||
@ -136,7 +136,8 @@ class LanguageManager(object):
|
||||
for counter, qmf in enumerate(qm_files):
|
||||
reg_ex = QtCore.QRegExp("^.*i18n/(.*).qm")
|
||||
if reg_ex.exactMatch(qmf):
|
||||
name = '%s' % reg_ex.cap(1)
|
||||
name = '{regex}'.format(regex=reg_ex.cap(1))
|
||||
# TODO: Test before converting to python3 string format
|
||||
LanguageManager.__qm_list__['%#2i %s' % (counter + 1, LanguageManager.language_name(qmf))] = name
|
||||
|
||||
@staticmethod
|
||||
|
@ -49,12 +49,13 @@ class OpenLPMixin(object):
|
||||
Code to added debug wrapper to work on called functions within a decorated class.
|
||||
"""
|
||||
def wrapped(*args, **kwargs):
|
||||
parent.logger.debug("Entering %s" % func.__name__)
|
||||
parent.logger.debug("Entering {function}".format(function=func.__name__))
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
if parent.logger.getEffectiveLevel() <= logging.ERROR:
|
||||
parent.logger.error('Exception in %s : %s' % (func.__name__, e))
|
||||
parent.logger.error('Exception in {function} : {error}'.format(function=func.__name__,
|
||||
error=e))
|
||||
raise e
|
||||
return wrapped
|
||||
|
||||
|
@ -71,8 +71,8 @@ class Registry(object):
|
||||
else:
|
||||
if not self.initialising:
|
||||
trace_error_handler(log)
|
||||
log.error('Service %s not found in list' % key)
|
||||
raise KeyError('Service %s not found in list' % key)
|
||||
log.error('Service {key} not found in list'.format(key=key))
|
||||
raise KeyError('Service {key} not found in list'.format(key=key))
|
||||
|
||||
def register(self, key, reference):
|
||||
"""
|
||||
@ -83,8 +83,8 @@ class Registry(object):
|
||||
"""
|
||||
if key in self.service_list:
|
||||
trace_error_handler(log)
|
||||
log.error('Duplicate service exception %s' % key)
|
||||
raise KeyError('Duplicate service exception %s' % key)
|
||||
log.error('Duplicate service exception {key}'.format(key=key))
|
||||
raise KeyError('Duplicate service exception {key}'.format(key=key))
|
||||
else:
|
||||
self.service_list[key] = reference
|
||||
|
||||
@ -140,8 +140,8 @@ class Registry(object):
|
||||
except TypeError:
|
||||
# Who has called me can help in debugging
|
||||
trace_error_handler(log)
|
||||
log.exception('Exception for function %s', function)
|
||||
log.exception('Exception for function {function}'.format(function=function))
|
||||
else:
|
||||
trace_error_handler(log)
|
||||
log.error("Event %s called but not registered" % event)
|
||||
log.error("Event {event} called but not registered".format(event=event))
|
||||
return results
|
||||
|
@ -487,16 +487,16 @@ class Settings(QtCore.QSettings):
|
||||
# Do NOT do this anywhere else!
|
||||
settings = QtCore.QSettings(self.fileName(), Settings.IniFormat)
|
||||
settings.beginGroup(plugin.settings_section)
|
||||
if settings.contains('%s count' % plugin.name):
|
||||
if settings.contains('{name} count'.format(name=plugin.name)):
|
||||
# Get the count.
|
||||
list_count = int(settings.value('%s count' % plugin.name, 0))
|
||||
list_count = int(settings.value('{name} count'.format(name=plugin.name), 0))
|
||||
if list_count:
|
||||
for counter in range(list_count):
|
||||
# The keys were named e. g.: "image 0"
|
||||
item = settings.value('%s %d' % (plugin.name, counter), '')
|
||||
item = settings.value('{name} {counter:d}'.format(name=plugin.name, counter=counter), '')
|
||||
if item:
|
||||
files_list.append(item)
|
||||
settings.remove('%s %d' % (plugin.name, counter))
|
||||
settings.remove('%s count' % plugin.name)
|
||||
settings.remove('{name} {counter:d}'.format(name=plugin.name, counter=counter))
|
||||
settings.remove('{name} count'.format(name=plugin.name))
|
||||
settings.endGroup()
|
||||
return files_list
|
||||
|
@ -81,6 +81,7 @@ class UiStrings(object):
|
||||
self.Export = translate('OpenLP.Ui', 'Export')
|
||||
self.File = translate('OpenLP.Ui', 'File')
|
||||
self.FileNotFound = translate('OpenLP.Ui', 'File Not Found')
|
||||
# TODO: Check before converting to python3 string
|
||||
self.FileNotFoundMessage = translate('OpenLP.Ui', 'File %s not found.\nPlease try selecting it individually.')
|
||||
self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit')
|
||||
self.Help = translate('OpenLP.Ui', 'Help')
|
||||
@ -111,8 +112,8 @@ class UiStrings(object):
|
||||
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
||||
self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
||||
self.OLP = translate('OpenLP.Ui', 'OpenLP')
|
||||
self.OLPV2 = "%s %s" % (self.OLP, "2")
|
||||
self.OLPV2x = "%s %s" % (self.OLP, "2.4")
|
||||
self.OLPV2 = "{name} {version}".format(name=self.OLP, version="2")
|
||||
self.OLPV2x = "{name} {version}".format(name=self.OLP, version="2.4")
|
||||
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
|
||||
self.OpenService = translate('OpenLP.Ui', 'Open service.')
|
||||
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
|
||||
@ -140,6 +141,7 @@ class UiStrings(object):
|
||||
self.Split = translate('OpenLP.Ui', 'Optional &Split')
|
||||
self.SplitToolTip = translate('OpenLP.Ui',
|
||||
'Split a slide into two only if it does not fit on the screen as one slide.')
|
||||
# TODO: Check before converting to python3 string
|
||||
self.StartTimeCode = translate('OpenLP.Ui', 'Start %s')
|
||||
self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop')
|
||||
self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End')
|
||||
|
@ -44,9 +44,10 @@ class VersionThread(QtCore.QThread):
|
||||
log.debug('Version thread - run')
|
||||
app_version = get_application_version()
|
||||
version = check_latest_version(app_version)
|
||||
log.debug("Versions %s and %s " % (LooseVersion(str(version)), LooseVersion(str(app_version['full']))))
|
||||
log.debug("Versions {version1} and {version2} ".format(version1=LooseVersion(str(version)),
|
||||
version2=LooseVersion(str(app_version['full']))))
|
||||
if LooseVersion(str(version)) > LooseVersion(str(app_version['full'])):
|
||||
self.main_window.openlp_version_check.emit('%s' % version)
|
||||
self.main_window.openlp_version_check.emit('{version}'.format(version=version))
|
||||
|
||||
|
||||
def get_application_version():
|
||||
@ -91,7 +92,7 @@ def get_application_version():
|
||||
if tree_revision == tag_revision:
|
||||
full_version = tag_version.strip()
|
||||
else:
|
||||
full_version = '%s-bzr%s' % (tag_version.strip(), tree_revision.strip())
|
||||
full_version = '{tag}-bzr{tree}'.format(tag=tag_version.strip(), tree=tree_revision.strip())
|
||||
else:
|
||||
# We're not running the development version, let's use the file.
|
||||
file_path = AppLocation.get_directory(AppLocation.VersionDir)
|
||||
@ -113,9 +114,10 @@ def get_application_version():
|
||||
'build': bits[1] if len(bits) > 1 else None
|
||||
}
|
||||
if APPLICATION_VERSION['build']:
|
||||
log.info('Openlp version %s build %s', APPLICATION_VERSION['version'], APPLICATION_VERSION['build'])
|
||||
log.info('Openlp version {version} build {build}'.format(version=APPLICATION_VERSION['version'],
|
||||
build=APPLICATION_VERSION['build']))
|
||||
else:
|
||||
log.info('Openlp version %s' % APPLICATION_VERSION['version'])
|
||||
log.info('Openlp version {version}'.format(version=APPLICATION_VERSION['version']))
|
||||
return APPLICATION_VERSION
|
||||
|
||||
|
||||
@ -149,8 +151,9 @@ def check_latest_version(current_version):
|
||||
req = urllib.request.Request('http://www.openlp.org/files/dev_version.txt')
|
||||
else:
|
||||
req = urllib.request.Request('http://www.openlp.org/files/version.txt')
|
||||
req.add_header('User-Agent', 'OpenLP/%s %s/%s; ' % (current_version['full'], platform.system(),
|
||||
platform.release()))
|
||||
req.add_header('User-Agent', 'OpenLP/{version} {system}/{release}; '.format(version=current_version['full'],
|
||||
system=platform.system(),
|
||||
release=platform.release()))
|
||||
remote_version = None
|
||||
retries = 0
|
||||
while True:
|
||||
|
@ -55,9 +55,13 @@ class ImageSource(object):
|
||||
|
||||
``Theme``
|
||||
This says, that the image is used by a theme.
|
||||
|
||||
``CommandPlugins``
|
||||
This states that an image is being used by a command plugin.
|
||||
"""
|
||||
ImagePlugin = 1
|
||||
Theme = 2
|
||||
CommandPlugins = 3
|
||||
|
||||
|
||||
class MediaType(object):
|
||||
@ -174,10 +178,30 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
|
||||
ext = os.path.splitext(thumb_path)[1].lower()
|
||||
reader = QtGui.QImageReader(image_path)
|
||||
if size is None:
|
||||
ratio = reader.size().width() / reader.size().height()
|
||||
# No size given; use default height of 88
|
||||
if reader.size().isEmpty():
|
||||
ratio = 1
|
||||
else:
|
||||
ratio = reader.size().width() / reader.size().height()
|
||||
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
|
||||
else:
|
||||
elif size.isValid():
|
||||
# Complete size given
|
||||
reader.setScaledSize(size)
|
||||
else:
|
||||
# Invalid size given
|
||||
if reader.size().isEmpty():
|
||||
ratio = 1
|
||||
else:
|
||||
ratio = reader.size().width() / reader.size().height()
|
||||
if size.width() >= 0:
|
||||
# Valid width; scale height
|
||||
reader.setScaledSize(QtCore.QSize(size.width(), int(size.width() / ratio)))
|
||||
elif size.height() >= 0:
|
||||
# Valid height; scale width
|
||||
reader.setScaledSize(QtCore.QSize(int(ratio * size.height()), size.height()))
|
||||
else:
|
||||
# Invalid; use default height of 88
|
||||
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
|
||||
thumb = reader.read()
|
||||
thumb.save(thumb_path, ext[1:])
|
||||
if not return_icon:
|
||||
|
@ -68,9 +68,11 @@ def get_db_path(plugin_name, db_file_name=None):
|
||||
:return: The path to the database as type str
|
||||
"""
|
||||
if db_file_name is None:
|
||||
return 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name)
|
||||
return 'sqlite:///{path}/{plugin}.sqlite'.format(path=AppLocation.get_section_data_path(plugin_name),
|
||||
plugin=plugin_name)
|
||||
else:
|
||||
return 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name)
|
||||
return 'sqlite:///{path}/{name}'.format(path=AppLocation.get_section_data_path(plugin_name),
|
||||
name=db_file_name)
|
||||
|
||||
|
||||
def handle_db_error(plugin_name, db_file_name):
|
||||
@ -82,10 +84,10 @@ def handle_db_error(plugin_name, db_file_name):
|
||||
:return: None
|
||||
"""
|
||||
db_path = get_db_path(plugin_name, db_file_name)
|
||||
log.exception('Error loading database: %s', db_path)
|
||||
log.exception('Error loading database: {db}'.format(db=db_path))
|
||||
critical_error_message_box(translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s')
|
||||
% db_path)
|
||||
translate('OpenLP.Manager',
|
||||
'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path))
|
||||
|
||||
|
||||
def init_url(plugin_name, db_file_name=None):
|
||||
@ -101,10 +103,11 @@ def init_url(plugin_name, db_file_name=None):
|
||||
if db_type == 'sqlite':
|
||||
db_url = get_db_path(plugin_name, db_file_name)
|
||||
else:
|
||||
db_url = '%s://%s:%s@%s/%s' % (db_type, urlquote(settings.value('db username')),
|
||||
urlquote(settings.value('db password')),
|
||||
urlquote(settings.value('db hostname')),
|
||||
urlquote(settings.value('db database')))
|
||||
db_url = '{type}://{user}:{password}@{host}/{db}'.format(type=db_type,
|
||||
user=urlquote(settings.value('db username')),
|
||||
password=urlquote(settings.value('db password')),
|
||||
host=urlquote(settings.value('db hostname')),
|
||||
db=urlquote(settings.value('db database')))
|
||||
settings.endGroup()
|
||||
return db_url
|
||||
|
||||
@ -157,10 +160,10 @@ def upgrade_db(url, upgrade):
|
||||
return version, upgrade.__version__
|
||||
version += 1
|
||||
try:
|
||||
while hasattr(upgrade, 'upgrade_%d' % version):
|
||||
log.debug('Running upgrade_%d', version)
|
||||
while hasattr(upgrade, 'upgrade_{version:d}'.format(version=version)):
|
||||
log.debug('Running upgrade_{version:d}'.format(version=version))
|
||||
try:
|
||||
upgrade_func = getattr(upgrade, 'upgrade_%d' % version)
|
||||
upgrade_func = getattr(upgrade, 'upgrade_{version:d}'.format(version=version))
|
||||
upgrade_func(session, metadata)
|
||||
session.commit()
|
||||
# Update the version number AFTER a commit so that we are sure the previous transaction happened
|
||||
@ -168,8 +171,8 @@ def upgrade_db(url, upgrade):
|
||||
session.commit()
|
||||
version += 1
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
log.exception('Could not run database upgrade script "upgrade_%s", upgrade process has been halted.',
|
||||
version)
|
||||
log.exception('Could not run database upgrade script '
|
||||
'"upgrade_{version:d}", upgrade process has been halted.'.format(version=version))
|
||||
break
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
version_meta = Metadata.populate(key='version', value=int(upgrade.__version__))
|
||||
@ -242,9 +245,10 @@ class Manager(object):
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'The database being loaded was created in a more recent version of '
|
||||
'OpenLP. The database is version %d, while OpenLP expects version %d. The database will '
|
||||
'not be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url)
|
||||
)
|
||||
'OpenLP. The database is version {db_ver}, while OpenLP expects version {db_up}. '
|
||||
'The database will not be loaded.\n\nDatabase: {db_name}').format(db_ver=db_ver,
|
||||
db_up=up_ver,
|
||||
db_name=self.db_url))
|
||||
return
|
||||
if not session:
|
||||
try:
|
||||
@ -460,7 +464,7 @@ class Manager(object):
|
||||
raise
|
||||
except InvalidRequestError:
|
||||
self.session.rollback()
|
||||
log.exception('Failed to delete %s records', object_class.__name__)
|
||||
log.exception('Failed to delete {name} records'.format(name=object_class.__name__))
|
||||
return False
|
||||
except:
|
||||
self.session.rollback()
|
||||
|
@ -50,7 +50,8 @@ class FileDialog(QtWidgets.QFileDialog):
|
||||
log.info('File not found. Attempting to unquote.')
|
||||
file = parse.unquote(file)
|
||||
if not os.path.exists(file):
|
||||
log.error('File %s not found.' % file)
|
||||
log.error('File {text} not found.'.format(text=file))
|
||||
# TODO: Test with UiStrings() before converting to python3 strings
|
||||
QtWidgets.QMessageBox.information(parent, UiStrings().FileNotFound,
|
||||
UiStrings().FileNotFoundMessage % file)
|
||||
continue
|
||||
|
@ -396,6 +396,7 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# TODO: Verify where this is used before converting to python3
|
||||
HTMLSRC = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -564,13 +565,13 @@ def build_html(item, screen, is_live, background, image=None, plugins=None):
|
||||
theme_data = item.theme_data
|
||||
# Image generated and poked in
|
||||
if background:
|
||||
bgimage_src = 'src="data:image/png;base64,%s"' % background
|
||||
bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=background)
|
||||
elif item.bg_image_bytes:
|
||||
bgimage_src = 'src="data:image/png;base64,%s"' % item.bg_image_bytes
|
||||
bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=item.bg_image_bytes)
|
||||
else:
|
||||
bgimage_src = 'style="display:none;"'
|
||||
if image:
|
||||
image_src = 'src="data:image/png;base64,%s"' % image
|
||||
image_src = 'src="data:image/png;base64,{image}"'.format(image=image)
|
||||
else:
|
||||
image_src = 'style="display:none;"'
|
||||
css_additions = ''
|
||||
@ -601,7 +602,7 @@ def webkit_version():
|
||||
"""
|
||||
try:
|
||||
webkit_ver = float(QtWebKit.qWebKitVersion())
|
||||
log.debug('Webkit version = %s' % webkit_ver)
|
||||
log.debug('Webkit version = {version}'.format(version=webkit_ver))
|
||||
except AttributeError:
|
||||
webkit_ver = 0
|
||||
return webkit_ver
|
||||
@ -621,23 +622,25 @@ def build_background_css(item, width):
|
||||
if theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
|
||||
background = ''
|
||||
elif theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
|
||||
background = 'background-color: %s' % theme.background_color
|
||||
background = 'background-color: {theme}'.format(theme=theme.background_color)
|
||||
else:
|
||||
if theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
|
||||
background = 'background: -webkit-gradient(linear, left top, left bottom, from(%s), to(%s)) fixed' \
|
||||
% (theme.background_start_color, theme.background_end_color)
|
||||
background = 'background: -webkit-gradient(linear, left top, left bottom, from({start}), to({end})) ' \
|
||||
'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
|
||||
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftTop):
|
||||
background = 'background: -webkit-gradient(linear, left top, right bottom, from(%s), to(%s)) fixed' \
|
||||
% (theme.background_start_color, theme.background_end_color)
|
||||
background = 'background: -webkit-gradient(linear, left top, right bottom, from({start}), to({end})) ' \
|
||||
'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
|
||||
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftBottom):
|
||||
background = 'background: -webkit-gradient(linear, left bottom, right top, from(%s), to(%s)) fixed' \
|
||||
% (theme.background_start_color, theme.background_end_color)
|
||||
background = 'background: -webkit-gradient(linear, left bottom, right top, from({start}), to({end})) ' \
|
||||
'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
|
||||
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Vertical):
|
||||
background = 'background: -webkit-gradient(linear, left top, right top, from(%s), to(%s)) fixed' % \
|
||||
(theme.background_start_color, theme.background_end_color)
|
||||
background = 'background: -webkit-gradient(linear, left top, right top, from({start}), to({end})) ' \
|
||||
'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
|
||||
else:
|
||||
background = 'background: -webkit-gradient(radial, %s 50%%, 100, %s 50%%, %s, from(%s), to(%s)) fixed'\
|
||||
% (width, width, width, theme.background_start_color, theme.background_end_color)
|
||||
background = 'background: -webkit-gradient(radial, {width} 50%, 100, {width} 50%, {width}, ' \
|
||||
'from({start}), to({end})) fixed'.format(width=width,
|
||||
start=theme.background_start_color,
|
||||
end=theme.background_end_color)
|
||||
return background
|
||||
|
||||
|
||||
@ -647,6 +650,7 @@ def build_lyrics_css(item):
|
||||
|
||||
:param item: Service Item containing theme and location information
|
||||
"""
|
||||
# TODO: Verify this before converting to python3
|
||||
style = """
|
||||
.lyricstable {
|
||||
z-index: 5;
|
||||
@ -669,12 +673,13 @@ def build_lyrics_css(item):
|
||||
lyrics = ''
|
||||
lyricsmain = ''
|
||||
if theme_data and item.main:
|
||||
lyricstable = 'left: %spx; top: %spx;' % (item.main.x(), item.main.y())
|
||||
lyricstable = 'left: {left}px; top: {top}px;'.format(left=item.main.x(), top=item.main.y())
|
||||
lyrics = build_lyrics_format_css(theme_data, item.main.width(), item.main.height())
|
||||
lyricsmain += build_lyrics_outline_css(theme_data)
|
||||
if theme_data.font_main_shadow:
|
||||
lyricsmain += ' text-shadow: %s %spx %spx;' % \
|
||||
(theme_data.font_main_shadow_color, theme_data.font_main_shadow_size, theme_data.font_main_shadow_size)
|
||||
lyricsmain += ' text-shadow: {theme} {shadow}px ' \
|
||||
'{shadow}px;'.format(theme=theme_data.font_main_shadow_color,
|
||||
shadow=theme_data.font_main_shadow_size)
|
||||
lyrics_css = style % (lyricstable, lyrics, lyricsmain)
|
||||
return lyrics_css
|
||||
|
||||
@ -689,7 +694,9 @@ def build_lyrics_outline_css(theme_data):
|
||||
size = float(theme_data.font_main_outline_size) / 16
|
||||
fill_color = theme_data.font_main_color
|
||||
outline_color = theme_data.font_main_outline_color
|
||||
return ' -webkit-text-stroke: %sem %s; -webkit-text-fill-color: %s; ' % (size, outline_color, fill_color)
|
||||
return ' -webkit-text-stroke: {size}em {color}; -webkit-text-fill-color: {fill}; '.format(size=size,
|
||||
color=outline_color,
|
||||
fill=fill_color)
|
||||
return ''
|
||||
|
||||
|
||||
@ -715,13 +722,21 @@ def build_lyrics_format_css(theme_data, width, height):
|
||||
padding_bottom = '0.5em'
|
||||
else:
|
||||
padding_bottom = '0'
|
||||
lyrics = '%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-bottom: %s; padding-left: %spx; width: %spx; height: %spx; ' % \
|
||||
(justify, align, valign, theme_data.font_main_name, theme_data.font_main_size,
|
||||
theme_data.font_main_color, 100 + int(theme_data.font_main_line_adjustment), padding_bottom,
|
||||
left_margin, width, height)
|
||||
lyrics = '{justify} word-wrap: break-word; ' \
|
||||
'text-align: {align}; vertical-align: {valign}; font-family: {font}; ' \
|
||||
'font-size: {size}pt; color: {color}; line-height: {line:d}%; margin: 0;' \
|
||||
'padding: 0; padding-bottom: {bottom}; padding-left: {left}px; width: {width}px; ' \
|
||||
'height: {height}px; '.format(justify=justify,
|
||||
align=align,
|
||||
valign=valign,
|
||||
font=theme_data.font_main_name,
|
||||
size=theme_data.font_main_size,
|
||||
color=theme_data.font_main_color,
|
||||
line=100 + int(theme_data.font_main_line_adjustment),
|
||||
bottom=padding_bottom,
|
||||
left=left_margin,
|
||||
width=width,
|
||||
height=height)
|
||||
if theme_data.font_main_italics:
|
||||
lyrics += 'font-style:italic; '
|
||||
if theme_data.font_main_bold:
|
||||
@ -737,20 +752,21 @@ def build_footer_css(item, height):
|
||||
:param height:
|
||||
"""
|
||||
style = """
|
||||
left: %spx;
|
||||
bottom: %spx;
|
||||
width: %spx;
|
||||
font-family: %s;
|
||||
font-size: %spt;
|
||||
color: %s;
|
||||
left: {left}px;
|
||||
bottom: {bottom}px;
|
||||
width: {width}px;
|
||||
font-family: {family};
|
||||
font-size: {size}pt;
|
||||
color: {color};
|
||||
text-align: left;
|
||||
white-space: %s;
|
||||
white-space: {space};
|
||||
"""
|
||||
theme = item.theme_data
|
||||
if not theme or not item.footer:
|
||||
return ''
|
||||
bottom = height - int(item.footer.y()) - int(item.footer.height())
|
||||
whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap'
|
||||
lyrics_html = style % (item.footer.x(), bottom, item.footer.width(),
|
||||
theme.font_footer_name, theme.font_footer_size, theme.font_footer_color, whitespace)
|
||||
lyrics_html = style.format(left=item.footer.x(), bottom=bottom, width=item.footer.width(),
|
||||
family=theme.font_footer_name, size=theme.font_footer_size,
|
||||
color=theme.font_footer_color, space=whitespace)
|
||||
return lyrics_html
|
||||
|
@ -236,7 +236,7 @@ class ImageManager(QtCore.QObject):
|
||||
"""
|
||||
Return the ``QImage`` from the cache. If not present wait for the background thread to process it.
|
||||
"""
|
||||
log.debug('getImage %s' % path)
|
||||
log.debug('getImage {path}'.format(path=path))
|
||||
image = self._cache[(path, source, width, height)]
|
||||
if image.image is None:
|
||||
self._conversion_queue.modify_priority(image, Priority.High)
|
||||
@ -256,7 +256,7 @@ class ImageManager(QtCore.QObject):
|
||||
"""
|
||||
Returns the byte string for an image. If not present wait for the background thread to process it.
|
||||
"""
|
||||
log.debug('get_image_bytes %s' % path)
|
||||
log.debug('get_image_bytes {path}'.format(path=path))
|
||||
image = self._cache[(path, source, width, height)]
|
||||
if image.image_bytes is None:
|
||||
self._conversion_queue.modify_priority(image, Priority.Urgent)
|
||||
@ -271,7 +271,7 @@ class ImageManager(QtCore.QObject):
|
||||
"""
|
||||
Add image to cache if it is not already there.
|
||||
"""
|
||||
log.debug('add_image %s' % path)
|
||||
log.debug('add_image {path}'.format(path=path))
|
||||
if not (path, source, width, height) in self._cache:
|
||||
image = Image(path, source, background, width, height)
|
||||
self._cache[(path, source, width, height)] = image
|
||||
|
@ -186,7 +186,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
for action in toolbar_actions:
|
||||
if action[0] == StringContent.Preview:
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.add_toolbar_action('%s%sAction' % (self.plugin.name, action[0]),
|
||||
self.toolbar.add_toolbar_action('{name}{action}Action'.format(name=self.plugin.name, action=action[0]),
|
||||
text=self.plugin.get_string(action[1])['title'], icon=action[2],
|
||||
tooltip=self.plugin.get_string(action[1])['tooltip'],
|
||||
triggers=action[3])
|
||||
@ -200,7 +200,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
self.list_view.setSpacing(1)
|
||||
self.list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.list_view.setAlternatingRowColors(True)
|
||||
self.list_view.setObjectName('%sListView' % self.plugin.name)
|
||||
self.list_view.setObjectName('{name}ListView'.format(name=self.plugin.name))
|
||||
# Add to page_layout
|
||||
self.page_layout.addWidget(self.list_view)
|
||||
# define and add the context menu
|
||||
@ -212,19 +212,22 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
triggers=self.on_edit_click)
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
|
||||
'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(),
|
||||
preview=StringContent.Preview.title()),
|
||||
text=self.plugin.get_string(StringContent.Preview)['title'],
|
||||
icon=':/general/general_preview.png',
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_preview_click)
|
||||
create_widget_action(self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()),
|
||||
'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(),
|
||||
live=StringContent.Live.title()),
|
||||
text=self.plugin.get_string(StringContent.Live)['title'],
|
||||
icon=':/general/general_live.png',
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_live_click)
|
||||
create_widget_action(self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Service.title()),
|
||||
'listView{plugin}{service}Item'.format(plugin=self.plugin.name.title(),
|
||||
service=StringContent.Service.title()),
|
||||
can_shortcuts=True,
|
||||
text=self.plugin.get_string(StringContent.Service)['title'],
|
||||
icon=':/general/general_add.png',
|
||||
@ -232,7 +235,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
if self.has_delete_icon:
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
|
||||
'listView{plugin}{delete}Item'.format(plugin=self.plugin.name.title(),
|
||||
delete=StringContent.Delete.title()),
|
||||
text=self.plugin.get_string(StringContent.Delete)['title'],
|
||||
icon=':/general/general_delete.png',
|
||||
can_shortcuts=True, triggers=self.on_delete_click)
|
||||
@ -313,7 +317,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
files = FileDialog.getOpenFileNames(self, self.on_new_prompt,
|
||||
Settings().value(self.settings_section + '/last directory'),
|
||||
self.on_new_file_masks)
|
||||
log.info('New files(s) %s' % files)
|
||||
log.info('New files(s) {files}'.format(files=files))
|
||||
if files:
|
||||
self.application.set_busy_cursor()
|
||||
self.validate_and_load(files)
|
||||
@ -333,7 +337,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
if not error_shown:
|
||||
critical_error_message_box(translate('OpenLP.MediaManagerItem', 'Invalid File Type'),
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'Invalid File %s.\nSuffix not supported') % file_name)
|
||||
'Invalid File {name}.\n'
|
||||
'Suffix not supported').format(name=file_name))
|
||||
error_shown = True
|
||||
else:
|
||||
new_files.append(file_name)
|
||||
@ -375,7 +380,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
self.load_list(full_list, target_group)
|
||||
last_dir = os.path.split(files[0])[0]
|
||||
Settings().setValue(self.settings_section + '/last directory', last_dir)
|
||||
Settings().setValue('%s/%s files' % (self.settings_section, self.settings_section), self.get_file_list())
|
||||
Settings().setValue('{section}/{section} files'.format(section=self.settings_section),
|
||||
self.get_file_list())
|
||||
if duplicates_found:
|
||||
critical_error_message_box(UiStrings().Duplicate,
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
@ -550,7 +556,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
# Is it possible to process multiple list items to generate
|
||||
# multiple service items?
|
||||
if self.single_service_item:
|
||||
log.debug('%s Add requested', self.plugin.name)
|
||||
log.debug('{plugin} Add requested'.format(plugin=self.plugin.name))
|
||||
self.add_to_service(replace=self.remote_triggered)
|
||||
else:
|
||||
items = self.list_view.selectedIndexes()
|
||||
@ -591,7 +597,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select one or more items.'))
|
||||
else:
|
||||
log.debug('%s Add requested', self.plugin.name)
|
||||
log.debug('{plugin} Add requested'.format(plugin=self.plugin.name))
|
||||
service_item = self.service_manager.get_service_item()
|
||||
if not service_item:
|
||||
QtWidgets.QMessageBox.information(self, UiStrings().NISs,
|
||||
@ -604,7 +610,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
# Turn off the remote edit update message indicator
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'Invalid Service Item'),
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select a %s service item.') % self.title)
|
||||
'You must select a {title} '
|
||||
'service item.').format(title=self.title))
|
||||
|
||||
def build_service_item(self, item=None, xml_version=False, remote=False, context=ServiceItemContext.Live):
|
||||
"""
|
||||
|
@ -130,7 +130,7 @@ class Plugin(QtCore.QObject, RegistryProperties):
|
||||
:param settings_tab_class: The class name of the plugin's settings tab.
|
||||
:param version: Defaults to *None*, which means that the same version number is used as OpenLP's version number.
|
||||
"""
|
||||
log.debug('Plugin %s initialised' % name)
|
||||
log.debug('Plugin {plugin} initialised'.format(plugin=name))
|
||||
super(Plugin, self).__init__()
|
||||
self.name = name
|
||||
self.text_strings = {}
|
||||
@ -154,11 +154,11 @@ class Plugin(QtCore.QObject, RegistryProperties):
|
||||
# Append a setting for files in the mediamanager (note not all plugins
|
||||
# which have a mediamanager need this).
|
||||
if media_item_class is not None:
|
||||
default_settings['%s/%s files' % (name, name)] = []
|
||||
default_settings['{name}/{name} files'.format(name=name)] = []
|
||||
# Add settings to the dict of all settings.
|
||||
Settings.extend_default_settings(default_settings)
|
||||
Registry().register_function('%s_add_service_item' % self.name, self.process_add_service_event)
|
||||
Registry().register_function('%s_config_updated' % self.name, self.config_update)
|
||||
Registry().register_function('{name}_add_service_item'.format(name=self.name), self.process_add_service_event)
|
||||
Registry().register_function('{name}_config_updated'.format(name=self.name), self.config_update)
|
||||
|
||||
def check_pre_conditions(self):
|
||||
"""
|
||||
@ -256,7 +256,7 @@ class Plugin(QtCore.QObject, RegistryProperties):
|
||||
"""
|
||||
Generic Drag and drop handler triggered from service_manager.
|
||||
"""
|
||||
log.debug('process_add_service_event event called for plugin %s' % self.name)
|
||||
log.debug('process_add_service_event event called for plugin {name}'.format(name=self.name))
|
||||
if replace:
|
||||
self.media_item.on_add_edit_click()
|
||||
else:
|
||||
|
@ -43,7 +43,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
super(PluginManager, self).__init__(parent)
|
||||
self.log_info('Plugin manager Initialising')
|
||||
self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
|
||||
self.log_debug('Base path %s ' % self.base_path)
|
||||
self.log_debug('Base path {path}'.format(path=self.base_path))
|
||||
self.plugins = []
|
||||
self.log_info('Plugin manager Initialised')
|
||||
|
||||
@ -73,7 +73,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
"""
|
||||
start_depth = len(os.path.abspath(self.base_path).split(os.sep))
|
||||
present_plugin_dir = os.path.join(self.base_path, 'presentations')
|
||||
self.log_debug('finding plugins in %s at depth %d' % (self.base_path, start_depth))
|
||||
self.log_debug('finding plugins in {path} at depth {depth:d}'.format(path=self.base_path, depth=start_depth))
|
||||
for root, dirs, files in os.walk(self.base_path):
|
||||
for name in files:
|
||||
if name.endswith('.py') and not name.startswith('__'):
|
||||
@ -84,7 +84,9 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
break
|
||||
module_name = name[:-3]
|
||||
# import the modules
|
||||
self.log_debug('Importing %s from %s. Depth %d' % (module_name, root, this_depth))
|
||||
self.log_debug('Importing {name} from {root}. Depth {depth:d}'.format(name=module_name,
|
||||
root=root,
|
||||
depth=this_depth))
|
||||
try:
|
||||
# Use the "imp" library to try to get around a problem with the PyUNO library which
|
||||
# monkey-patches the __import__ function to do some magic. This causes issues with our tests.
|
||||
@ -93,21 +95,21 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
# Then load the module (do the actual import) using the details from find_module()
|
||||
imp.load_module(module_name, fp, path_name, description)
|
||||
except ImportError as e:
|
||||
self.log_exception('Failed to import module %s on path %s: %s'
|
||||
% (module_name, path, e.args[0]))
|
||||
self.log_exception('Failed to import module {name} on path {path}: '
|
||||
'{args}'.format(name=module_name, path=path, args=e.args[0]))
|
||||
plugin_classes = Plugin.__subclasses__()
|
||||
plugin_objects = []
|
||||
for p in plugin_classes:
|
||||
try:
|
||||
plugin = p()
|
||||
self.log_debug('Loaded plugin %s' % str(p))
|
||||
self.log_debug('Loaded plugin {plugin}'.format(plugin=str(p)))
|
||||
plugin_objects.append(plugin)
|
||||
except TypeError:
|
||||
self.log_exception('Failed to load plugin %s' % str(p))
|
||||
self.log_exception('Failed to load plugin {plugin}'.format(plugin=str(p)))
|
||||
plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight)
|
||||
for plugin in plugins_list:
|
||||
if plugin.check_pre_conditions():
|
||||
self.log_debug('Plugin %s active' % str(plugin.name))
|
||||
self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name)))
|
||||
plugin.set_status()
|
||||
else:
|
||||
plugin.status = PluginStatus.Disabled
|
||||
@ -175,10 +177,11 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
Loop through all the plugins and give them an opportunity to initialise themselves.
|
||||
"""
|
||||
for plugin in self.plugins:
|
||||
self.log_info('initialising plugins %s in a %s state' % (plugin.name, plugin.is_active()))
|
||||
self.log_info('initialising plugins {plugin} in a {state} state'.format(plugin=plugin.name,
|
||||
state=plugin.is_active()))
|
||||
if plugin.is_active():
|
||||
plugin.initialise()
|
||||
self.log_info('Initialisation Complete for %s ' % plugin.name)
|
||||
self.log_info('Initialisation Complete for {plugin}'.format(plugin=plugin.name))
|
||||
|
||||
def finalise_plugins(self):
|
||||
"""
|
||||
@ -187,7 +190,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
for plugin in self.plugins:
|
||||
if plugin.is_active():
|
||||
plugin.finalise()
|
||||
self.log_info('Finalisation Complete for %s ' % plugin.name)
|
||||
self.log_info('Finalisation Complete for {plugin}'.format(plugin=plugin.name))
|
||||
|
||||
def get_plugin_by_name(self, name):
|
||||
"""
|
||||
|
@ -131,7 +131,7 @@ class Source(CommonBase, Base):
|
||||
"""
|
||||
Return basic representation of Source table entry.
|
||||
"""
|
||||
return '<Source(pjlink_name="{name}", pjlink_code="{code}", text="{Text}")>'.format(name=self.pjlink_name,
|
||||
return '<Source(pjlink_name="{name}", pjlink_code="{code}", text="{text}")>'.format(name=self.pjlink_name,
|
||||
code=self.pjlink_code,
|
||||
text=self.text)
|
||||
model_id = Column(Integer, ForeignKey('model.id'))
|
||||
|
@ -107,7 +107,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
|
||||
:param theme_name: The theme name
|
||||
"""
|
||||
self.log_debug("_set_theme with theme %s" % theme_name)
|
||||
self.log_debug("_set_theme with theme {theme}".format(theme=theme_name))
|
||||
if theme_name not in self._theme_dimensions:
|
||||
theme_data = self.theme_manager.get_theme_data(theme_name)
|
||||
main_rect = self.get_main_rectangle(theme_data)
|
||||
@ -183,7 +183,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
|
||||
:param item_theme_name: The item theme's name.
|
||||
"""
|
||||
self.log_debug("set_item_theme with theme %s" % item_theme_name)
|
||||
self.log_debug("set_item_theme with theme {theme}".format(theme=item_theme_name))
|
||||
self._set_theme(item_theme_name)
|
||||
self.item_theme_name = item_theme_name
|
||||
|
||||
@ -317,7 +317,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
self.width = screen_size.width()
|
||||
self.height = screen_size.height()
|
||||
self.screen_ratio = self.height / self.width
|
||||
self.log_debug('_calculate default %s, %f' % (screen_size, self.screen_ratio))
|
||||
self.log_debug('_calculate default {size}, {ratio:f}'.format(size=screen_size, ratio=self.screen_ratio))
|
||||
# 90% is start of footer
|
||||
self.footer_start = int(self.height * 0.90)
|
||||
|
||||
@ -354,7 +354,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
:param rect_main: The main text block.
|
||||
:param rect_footer: The footer text block.
|
||||
"""
|
||||
self.log_debug('_set_text_rectangle %s , %s' % (rect_main, rect_footer))
|
||||
self.log_debug('_set_text_rectangle {main} , {footer}'.format(main=rect_main, footer=rect_footer))
|
||||
self._rect = rect_main
|
||||
self._rect_footer = rect_footer
|
||||
self.page_width = self._rect.width()
|
||||
@ -370,6 +370,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
self.web.resize(self.page_width, self.page_height)
|
||||
self.web_frame = self.web.page().mainFrame()
|
||||
# Adjust width and height to account for shadow. outline done in css.
|
||||
# TODO: Verify before converting to python3 strings
|
||||
html = """<!DOCTYPE html><html><head><script>
|
||||
function show_text(newtext) {
|
||||
var main = document.getElementById('main');
|
||||
@ -518,7 +519,8 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
|
||||
:param text: The text to check. It may contain HTML tags.
|
||||
"""
|
||||
self.web_frame.evaluateJavaScript('show_text("%s")' % text.replace('\\', '\\\\').replace('\"', '\\\"'))
|
||||
self.web_frame.evaluateJavaScript('show_text'
|
||||
'("{text}")'.format(text=text.replace('\\', '\\\\').replace('\"', '\\\"')))
|
||||
return self.web_frame.contentsSize().height() <= self.empty_height
|
||||
|
||||
|
||||
|
@ -78,7 +78,7 @@ class ScreenList(object):
|
||||
``number``
|
||||
The number of the screen, which size has changed.
|
||||
"""
|
||||
log.info('screen_resolution_changed %d' % number)
|
||||
log.info('screen_resolution_changed {number:d}'.format(number=number))
|
||||
for screen in self.screen_list:
|
||||
if number == screen['number']:
|
||||
new_screen = {
|
||||
@ -105,7 +105,7 @@ class ScreenList(object):
|
||||
"""
|
||||
# Do not log at start up.
|
||||
if changed_screen != -1:
|
||||
log.info('screen_count_changed %d' % self.desktop.screenCount())
|
||||
log.info('screen_count_changed {count:d}'.format(count=self.desktop.screenCount()))
|
||||
# Remove unplugged screens.
|
||||
for screen in copy.deepcopy(self.screen_list):
|
||||
if screen['number'] == self.desktop.screenCount():
|
||||
@ -132,9 +132,11 @@ class ScreenList(object):
|
||||
"""
|
||||
screen_list = []
|
||||
for screen in self.screen_list:
|
||||
screen_name = '%s %d' % (translate('OpenLP.ScreenList', 'Screen'), screen['number'] + 1)
|
||||
screen_name = '{name} {number:d}'.format(name=translate('OpenLP.ScreenList', 'Screen'),
|
||||
number=screen['number'] + 1)
|
||||
if screen['primary']:
|
||||
screen_name = '%s (%s)' % (screen_name, translate('OpenLP.ScreenList', 'primary'))
|
||||
screen_name = '{name} ({primary})'.format(name=screen_name,
|
||||
primary=translate('OpenLP.ScreenList', 'primary'))
|
||||
screen_list.append(screen_name)
|
||||
return screen_list
|
||||
|
||||
@ -152,7 +154,7 @@ class ScreenList(object):
|
||||
'size': PyQt5.QtCore.QRect(0, 0, 1024, 768)
|
||||
}
|
||||
"""
|
||||
log.info('Screen %d found with resolution %s' % (screen['number'], screen['size']))
|
||||
log.info('Screen {number:d} found with resolution {size}'.format(number=screen['number'], size=screen['size']))
|
||||
if screen['primary']:
|
||||
self.current = screen
|
||||
self.override = copy.deepcopy(self.current)
|
||||
@ -165,7 +167,7 @@ class ScreenList(object):
|
||||
|
||||
:param number: The screen number (int).
|
||||
"""
|
||||
log.info('remove_screen %d' % number)
|
||||
log.info('remove_screen {number:d}'.forma(number=number))
|
||||
for screen in self.screen_list:
|
||||
if screen['number'] == number:
|
||||
self.screen_list.remove(screen)
|
||||
@ -189,7 +191,7 @@ class ScreenList(object):
|
||||
|
||||
:param number: The screen number (int).
|
||||
"""
|
||||
log.debug('set_current_display %s' % number)
|
||||
log.debug('set_current_display {number}'.format(number=number))
|
||||
if number + 1 > self.display_count:
|
||||
self.current = self.screen_list[0]
|
||||
else:
|
||||
|
@ -62,9 +62,10 @@ class SearchEdit(QtWidgets.QLineEdit):
|
||||
right_padding = self.clear_button.width() + frame_width
|
||||
if hasattr(self, 'menu_button'):
|
||||
left_padding = self.menu_button.width()
|
||||
stylesheet = 'QLineEdit { padding-left: %spx; padding-right: %spx; } ' % (left_padding, right_padding)
|
||||
stylesheet = 'QLineEdit {{ padding-left:{left}px; padding-right: {right}px; }} '.format(left=left_padding,
|
||||
right=right_padding)
|
||||
else:
|
||||
stylesheet = 'QLineEdit { padding-right: %spx; } ' % right_padding
|
||||
stylesheet = 'QLineEdit {{ padding-right: {right}px; }} '.format(right=right_padding)
|
||||
self.setStyleSheet(stylesheet)
|
||||
msz = self.minimumSizeHint()
|
||||
self.setMinimumSize(max(msz.width(), self.clear_button.width() + (frame_width * 2) + 2),
|
||||
|
@ -247,7 +247,7 @@ class ServiceItem(RegistryProperties):
|
||||
self.renderer.set_item_theme(self.theme)
|
||||
self.theme_data, self.main, self.footer = self.renderer.pre_render()
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
log.debug('Formatting slides: %s' % self.title)
|
||||
log.debug('Formatting slides: {title}'.format(title=self.title))
|
||||
# Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
|
||||
# the dict instead of rendering them again.
|
||||
previous_pages = {}
|
||||
@ -270,7 +270,7 @@ class ServiceItem(RegistryProperties):
|
||||
elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
|
||||
pass
|
||||
else:
|
||||
log.error('Invalid value renderer: %s' % self.service_item_type)
|
||||
log.error('Invalid value renderer: {item}'.format(item=self.service_item_type))
|
||||
self.title = clean_tags(self.title)
|
||||
# The footer should never be None, but to be compatible with a few
|
||||
# nightly builds between 1.9.4 and 1.9.5, we have to correct this to
|
||||
@ -325,7 +325,8 @@ class ServiceItem(RegistryProperties):
|
||||
self.service_item_type = ServiceItemType.Command
|
||||
# If the item should have a display title but this frame doesn't have one, we make one up
|
||||
if self.is_capable(ItemCapabilities.HasDisplayTitle) and not display_title:
|
||||
display_title = translate('OpenLP.ServiceItem', '[slide %d]') % (len(self._raw_frames) + 1)
|
||||
display_title = translate('OpenLP.ServiceItem',
|
||||
'[slide {frame:d}]').format(frame=len(self._raw_frames) + 1)
|
||||
# Update image path to match servicemanager location if file was loaded from service
|
||||
if image and not self.has_original_files and self.name == 'presentations':
|
||||
file_location = os.path.join(path, file_name)
|
||||
@ -334,6 +335,8 @@ class ServiceItem(RegistryProperties):
|
||||
file_location_hash, ntpath.basename(image))
|
||||
self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
|
||||
'display_title': display_title, 'notes': notes})
|
||||
if self.is_capable(ItemCapabilities.HasThumbnails):
|
||||
self.image_manager.add_image(image, ImageSource.CommandPlugins, '#000000')
|
||||
self._new_item()
|
||||
|
||||
def get_service_repr(self, lite_save):
|
||||
@ -390,7 +393,7 @@ class ServiceItem(RegistryProperties):
|
||||
:param path: Defaults to *None*. This is the service manager path for things which have their files saved
|
||||
with them or None when the saved service is lite and the original file paths need to be preserved.
|
||||
"""
|
||||
log.debug('set_from_service called with path %s' % path)
|
||||
log.debug('set_from_service called with path {path}'.format(path=path))
|
||||
header = service_item['serviceitem']['header']
|
||||
self.title = header['title']
|
||||
self.name = header['name']
|
||||
@ -606,11 +609,13 @@ class ServiceItem(RegistryProperties):
|
||||
start = None
|
||||
end = None
|
||||
if self.start_time != 0:
|
||||
start = translate('OpenLP.ServiceItem', '<strong>Start</strong>: %s') % \
|
||||
str(datetime.timedelta(seconds=self.start_time))
|
||||
time = str(datetime.timedelta(seconds=self.start_time))
|
||||
start = translate('OpenLP.ServiceItem',
|
||||
'<strong>Start</strong>: {start}').format(start=time)
|
||||
if self.media_length != 0:
|
||||
end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: %s') % \
|
||||
str(datetime.timedelta(seconds=self.media_length // 1000))
|
||||
length = str(datetime.timedelta(seconds=self.media_length // 1000))
|
||||
end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: {length}').format(length=length)
|
||||
|
||||
if not start and not end:
|
||||
return ''
|
||||
elif start and not end:
|
||||
@ -618,7 +623,7 @@ class ServiceItem(RegistryProperties):
|
||||
elif not start and end:
|
||||
return end
|
||||
else:
|
||||
return '%s <br>%s' % (start, end)
|
||||
return '{start} <br>{end}'.format(start=start, end=end)
|
||||
|
||||
def update_theme(self, theme):
|
||||
"""
|
||||
|
@ -135,4 +135,4 @@ class SettingsTab(QtWidgets.QWidget, RegistryProperties):
|
||||
"""
|
||||
Tab has just been made visible to the user
|
||||
"""
|
||||
self.tab_visited = True
|
||||
pass
|
||||
|
@ -427,7 +427,7 @@ class ThemeXML(object):
|
||||
try:
|
||||
theme_xml = objectify.fromstring(xml)
|
||||
except etree.XMLSyntaxError:
|
||||
log.exception('Invalid xml %s', xml)
|
||||
log.exception('Invalid xml {text}'.format(text=xml))
|
||||
return
|
||||
xml_iter = theme_xml.getiterator()
|
||||
for element in xml_iter:
|
||||
@ -513,6 +513,7 @@ class ThemeXML(object):
|
||||
theme_strings = []
|
||||
for key in dir(self):
|
||||
if key[0:1] != '_':
|
||||
# TODO: Verify spacing format before converting to python3 string
|
||||
theme_strings.append('%30s: %s' % (key, getattr(self, key)))
|
||||
return '\n'.join(theme_strings)
|
||||
|
||||
|
@ -165,7 +165,7 @@ def create_button(parent, name, **kwargs):
|
||||
kwargs.setdefault('icon', ':/services/service_down.png')
|
||||
kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
|
||||
else:
|
||||
log.warning('The role "%s" is not defined in create_push_button().', role)
|
||||
log.warning('The role "{role}" is not defined in create_push_button().'.format(role=role))
|
||||
if kwargs.pop('btn_class', '') == 'toolbutton':
|
||||
button = QtWidgets.QToolButton(parent)
|
||||
else:
|
||||
@ -183,7 +183,7 @@ def create_button(parent, name, **kwargs):
|
||||
button.clicked.connect(kwargs.pop('click'))
|
||||
for key in list(kwargs.keys()):
|
||||
if key not in ['text', 'icon', 'tooltip', 'click']:
|
||||
log.warning('Parameter %s was not consumed in create_button().', key)
|
||||
log.warning('Parameter {key} was not consumed in create_button().'.format(key=key))
|
||||
return button
|
||||
|
||||
|
||||
@ -270,7 +270,7 @@ def create_action(parent, name, **kwargs):
|
||||
action.triggered.connect(kwargs.pop('triggers'))
|
||||
for key in list(kwargs.keys()):
|
||||
if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']:
|
||||
log.warning('Parameter %s was not consumed in create_action().' % key)
|
||||
log.warning('Parameter {key} was not consumed in create_action().'.format(key=key))
|
||||
return action
|
||||
|
||||
|
||||
|
@ -133,37 +133,37 @@ def get_web_page(url, header=None, update_openlp=False):
|
||||
time.sleep(0.1)
|
||||
try:
|
||||
page = urllib.request.urlopen(req, timeout=CONNECTION_TIMEOUT)
|
||||
log.debug('Downloaded page {}'.format(page.geturl()))
|
||||
log.debug('Downloaded page {text}'.format(text=page.geturl()))
|
||||
break
|
||||
except urllib.error.URLError as err:
|
||||
log.exception('URLError on {}'.format(url))
|
||||
log.exception('URLError: {}'.format(err.reason))
|
||||
log.exception('URLError on {text}'.format(text=url))
|
||||
log.exception('URLError: {text}'.format(text=err.reason))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
except socket.timeout:
|
||||
log.exception('Socket timeout: {}'.format(url))
|
||||
log.exception('Socket timeout: {text}'.format(text=url))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
except socket.gaierror:
|
||||
log.exception('Socket gaierror: {}'.format(url))
|
||||
log.exception('Socket gaierror: {text}'.format(text=url))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
except ConnectionRefusedError:
|
||||
log.exception('ConnectionRefused: {}'.format(url))
|
||||
log.exception('ConnectionRefused: {text}'.format(text=url))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
break
|
||||
except ConnectionError:
|
||||
log.exception('Connection error: {}'.format(url))
|
||||
log.exception('Connection error: {text}'.format(text=url))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
except HTTPException:
|
||||
log.exception('HTTPException error: {}'.format(url))
|
||||
log.exception('HTTPException error: {text}'.format(text=url))
|
||||
page = None
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
@ -173,7 +173,7 @@ def get_web_page(url, header=None, update_openlp=False):
|
||||
if update_openlp:
|
||||
Registry().get('application').process_events()
|
||||
if not page:
|
||||
log.exception('{} could not be downloaded'.format(url))
|
||||
log.exception('{text} could not be downloaded'.format(text=url))
|
||||
return None
|
||||
log.debug(page)
|
||||
return page
|
||||
|
@ -88,7 +88,7 @@ class UiAboutDialog(object):
|
||||
|
||||
:param about_dialog: The QDialog object to translate
|
||||
"""
|
||||
about_dialog.setWindowTitle('%s OpenLP' % UiStrings().About)
|
||||
about_dialog.setWindowTitle('{about} OpenLP'.format(about=UiStrings().About))
|
||||
self.about_text_edit.setPlainText(
|
||||
translate('OpenLP.AboutForm',
|
||||
'OpenLP <version><revision> - Open Source Lyrics Projection\n'
|
||||
@ -200,115 +200,115 @@ class UiAboutDialog(object):
|
||||
' bring this software to you for free because\n'
|
||||
' He has set us free.')
|
||||
self.credits_text_edit.setPlainText(
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleLead}\n'
|
||||
' {nameLead}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleDevs}\n'
|
||||
' {nameDevs}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleContrib}\n'
|
||||
' {nameContrib}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleTesters}\n'
|
||||
' {nameTesters}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titlePackagers}\n'
|
||||
' {namePackagers}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
'{titleTranslators}\n'
|
||||
' {titleAF}\n'
|
||||
' {nameAF}\n'
|
||||
' {titleCS}\n'
|
||||
' {nameCS}\n'
|
||||
' {titleDA}\n'
|
||||
' {nameDA}\n'
|
||||
' {titleDE}\n'
|
||||
' {nameDE}\n'
|
||||
' {titleEL}\n'
|
||||
' {nameEL}\n'
|
||||
' {titleGB}\n'
|
||||
' {nameGB}\n'
|
||||
' {titleENZA}\n'
|
||||
' {nameENZA}\n'
|
||||
' {titleES}\n'
|
||||
' {nameES}\n'
|
||||
' {titleET}\n'
|
||||
' {nameET}\n'
|
||||
' {titleFI}\n'
|
||||
' {nameFI}\n'
|
||||
' {titleFR}\n'
|
||||
' {nameFR}\n'
|
||||
' {titleHU}\n'
|
||||
' {nameHU}\n'
|
||||
' {titleIND}\n'
|
||||
' {nameIND}\n'
|
||||
' {titleJA}\n'
|
||||
' {nameJA}\n'
|
||||
' {titleNB}\n'
|
||||
' {nameNB}\n'
|
||||
' {titleNL}\n'
|
||||
' {nameNL}\n'
|
||||
' {titlePL}\n'
|
||||
' {namePL}\n'
|
||||
' {titlePTBR}\n'
|
||||
' {namePTBR}\n'
|
||||
' {titleRU}\n'
|
||||
' {nameRU}\n'
|
||||
' {titleSV}\n'
|
||||
' {nameSV}\n'
|
||||
' {titleTALK}\n'
|
||||
' {nameTALK}\n'
|
||||
' {titleZHCN}\n'
|
||||
' {nameZHCN}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleDOCS}\n'
|
||||
' {nameDOCS}\n'
|
||||
'\n'
|
||||
'%s\n%s' %
|
||||
(project_lead, lead,
|
||||
devs, '\n '.join(developers),
|
||||
cons, '\n '.join(contributors),
|
||||
tests, '\n '.join(testers),
|
||||
packs, '\n '.join(packagers),
|
||||
laters,
|
||||
af, '\n '.join(translators['af']),
|
||||
cs, '\n '.join(translators['cs']),
|
||||
da, '\n '.join(translators['da']),
|
||||
de, '\n '.join(translators['de']),
|
||||
el, '\n '.join(translators['el']),
|
||||
gb, '\n '.join(translators['en_GB']),
|
||||
enza, '\n '.join(translators['en_ZA']),
|
||||
es, '\n '.join(translators['es']),
|
||||
et, '\n '.join(translators['et']),
|
||||
fi, '\n '.join(translators['fi']),
|
||||
fr, '\n '.join(translators['fr']),
|
||||
hu, '\n '.join(translators['hu']),
|
||||
ind, '\n '.join(translators['id']),
|
||||
ja, '\n '.join(translators['ja']),
|
||||
nb, '\n '.join(translators['nb']),
|
||||
nl, '\n '.join(translators['nl']),
|
||||
pl, '\n '.join(translators['pl']),
|
||||
ptbr, '\n '.join(translators['pt_BR']),
|
||||
ru, '\n '.join(translators['ru']),
|
||||
sv, '\n '.join(translators['sv']),
|
||||
talk, '\n '.join(translators['ta_LK']),
|
||||
zhcn, '\n '.join(translators['zh_CN']),
|
||||
documentation, '\n '.join(documentors),
|
||||
built_with, final_credit))
|
||||
'{build}\n{final}'.format(titleLead=project_lead, nameLead=lead,
|
||||
titleDevs=devs, nameDevs='\n '.join(developers),
|
||||
titleContrib=cons, nameContrib='\n '.join(contributors),
|
||||
titleTesters=tests, nameTesters='\n '.join(testers),
|
||||
titlePackagers=packs, namePackagers='\n '.join(packagers),
|
||||
titleTranslators=laters,
|
||||
titleAF=af, nameAF='\n '.join(translators['af']),
|
||||
titleCS=cs, nameCS='\n '.join(translators['cs']),
|
||||
titleDA=da, nameDA='\n '.join(translators['da']),
|
||||
titleDE=de, nameDE='\n '.join(translators['de']),
|
||||
titleEL=el, nameEL='\n '.join(translators['el']),
|
||||
titleGB=gb, nameGB='\n '.join(translators['en_GB']),
|
||||
titleENZA=enza, nameENZA='\n '.join(translators['en_ZA']),
|
||||
titleES=es, nameES='\n '.join(translators['es']),
|
||||
titleET=et, nameET='\n '.join(translators['et']),
|
||||
titleFI=fi, nameFI='\n '.join(translators['fi']),
|
||||
titleFR=fr, nameFR='\n '.join(translators['fr']),
|
||||
titleHU=hu, nameHU='\n '.join(translators['hu']),
|
||||
titleIND=ind, nameIND='\n '.join(translators['id']),
|
||||
titleJA=ja, nameJA='\n '.join(translators['ja']),
|
||||
titleNB=nb, nameNB='\n '.join(translators['nb']),
|
||||
titleNL=nl, nameNL='\n '.join(translators['nl']),
|
||||
titlePL=pl, namePL='\n '.join(translators['pl']),
|
||||
titlePTBR=ptbr, namePTBR='\n '.join(translators['pt_BR']),
|
||||
titleRU=ru, nameRU='\n '.join(translators['ru']),
|
||||
titleSV=sv, nameSV='\n '.join(translators['sv']),
|
||||
titleTALK=talk, nameTALK='\n '.join(translators['ta_LK']),
|
||||
titleZHCN=zhcn, nameZHCN='\n '.join(translators['zh_CN']),
|
||||
titleDOCS=documentation, nameDOCS='\n '.join(documentors),
|
||||
build=built_with,
|
||||
final=final_credit))
|
||||
self.about_notebook.setTabText(self.about_notebook.indexOf(self.credits_tab),
|
||||
translate('OpenLP.AboutForm', 'Credits'))
|
||||
cr_others = ('Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
'Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, '
|
||||
'Armin K\xf6hler, Erik Lundin, Edwin Lunando, Joshua Miller, '
|
||||
'Brian T. Meyer, Stevan Pettit, Andreas Preikschat, '
|
||||
'Mattias P\xf5ldaru, Christian Richter, Philip Ridout, '
|
||||
'Ken Roberts, Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, '
|
||||
'Martin Thompson, Jon Tibble, Dave Warnock, Frode Woldsund, '
|
||||
'Martin Zibricky, Patrick Zimmermann')
|
||||
copyright_note = translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2016 %s\n'
|
||||
'Portions copyright \xa9 2004-2016 %s') % \
|
||||
('Raoul Snyman',
|
||||
'Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
'Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, '
|
||||
'Armin K\xf6hler, Erik Lundin, Edwin Lunando, Joshua Miller, '
|
||||
'Brian T. Meyer, Stevan Pettit, Andreas Preikschat, '
|
||||
'Mattias P\xf5ldaru, Christian Richter, '
|
||||
'Philip Ridout, Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, '
|
||||
'Martin Thompson, Jon Tibble, Dave Warnock, Frode Woldsund, '
|
||||
'Martin Zibricky, Patrick Zimmermann')
|
||||
'Copyright \xa9 2004-2016 {cr}\n\n'
|
||||
'Portions copyright \xa9 2004-2016 {others}').format(cr='Raoul Snyman',
|
||||
others=cr_others)
|
||||
licence = translate('OpenLP.AboutForm',
|
||||
'This program is free software; you can redistribute it and/or '
|
||||
'modify it under the terms of the GNU General Public License as '
|
||||
@ -690,7 +690,11 @@ class UiAboutDialog(object):
|
||||
'linking proprietary applications with the library. If this is '
|
||||
'what you want to do, use the GNU Lesser General Public License '
|
||||
'instead of this License.')
|
||||
self.license_text_edit.setPlainText('%s\n\n%s\n\n%s\n\n\n%s' % (copyright_note, licence, disclaimer, gpl_text))
|
||||
self.license_text_edit.setPlainText('{crnote}\n\n{license}\n\n{disclaimer}'
|
||||
'\n\n\n{gpl}'.format(crnote=copyright_note,
|
||||
license=licence,
|
||||
disclaimer=disclaimer,
|
||||
gpl=gpl_text))
|
||||
self.about_notebook.setTabText(self.about_notebook.indexOf(self.license_tab),
|
||||
translate('OpenLP.AboutForm', 'License'))
|
||||
self.volunteer_button.setText(translate('OpenLP.AboutForm', 'Volunteer'))
|
||||
|
@ -52,7 +52,7 @@ class AboutForm(QtWidgets.QDialog, UiAboutDialog):
|
||||
about_text = self.about_text_edit.toPlainText()
|
||||
about_text = about_text.replace('<version>', application_version['version'])
|
||||
if application_version['build']:
|
||||
build_text = translate('OpenLP.AboutForm', ' build %s') % application_version['build']
|
||||
build_text = translate('OpenLP.AboutForm', ' build {version}').format(version=application_version['build'])
|
||||
else:
|
||||
build_text = ''
|
||||
about_text = about_text.replace('<revision>', build_text)
|
||||
|
@ -308,8 +308,8 @@ class AdvancedTab(SettingsTab):
|
||||
self.service_name_label.setText(translate('OpenLP.AdvancedTab', 'Name:'))
|
||||
self.service_name_edit.setToolTip(translate('OpenLP.AdvancedTab', 'Consult the OpenLP manual for usage.'))
|
||||
self.service_name_revert_button.setToolTip(
|
||||
translate('OpenLP.AdvancedTab', 'Revert to the default service name "%s".') %
|
||||
UiStrings().DefaultServiceName)
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'Revert to the default service name "{name}".').format(name=UiStrings().DefaultServiceName))
|
||||
self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))
|
||||
self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))
|
||||
self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))
|
||||
@ -391,16 +391,16 @@ class AdvancedTab(SettingsTab):
|
||||
# Since data location can be changed, make sure the path is present.
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
if not os.path.exists(self.current_data_path):
|
||||
log.error('Data path not found %s' % self.current_data_path)
|
||||
log.error('Data path not found {path}'.format(path=self.current_data_path))
|
||||
answer = QtWidgets.QMessageBox.critical(
|
||||
self, translate('OpenLP.AdvancedTab', 'Data Directory Error'),
|
||||
translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n%s\n\n'
|
||||
translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n{path}\n\n'
|
||||
'This data directory was previously changed from the OpenLP '
|
||||
'default location. If the new location was on removable '
|
||||
'media, that media needs to be made available.\n\n'
|
||||
'Click "No" to stop loading OpenLP. allowing you to fix the the problem.\n\n'
|
||||
'Click "Yes" to reset the data directory to the default '
|
||||
'location.').replace('%s', self.current_data_path),
|
||||
'location.').format(path=self.current_data_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if answer == QtWidgets.QMessageBox.No:
|
||||
@ -410,7 +410,7 @@ class AdvancedTab(SettingsTab):
|
||||
# Set data location to default.
|
||||
settings.remove('advanced/data path')
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
log.warning('User requested data path set to default %s' % self.current_data_path)
|
||||
log.warning('User requested data path set to default {path}'.format(path=self.current_data_path))
|
||||
self.data_directory_label.setText(os.path.abspath(self.current_data_path))
|
||||
# Don't allow data directory move if running portable.
|
||||
if settings.value('advanced/is portable'):
|
||||
@ -542,9 +542,9 @@ class AdvancedTab(SettingsTab):
|
||||
# Make sure they want to change the data.
|
||||
answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'),
|
||||
translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '
|
||||
'location of the OpenLP data directory to:\n\n%s\n\nThe data '
|
||||
'directory will be changed when OpenLP is closed.').
|
||||
replace('%s', new_data_path),
|
||||
'location of the OpenLP data directory to:\n\n{path}'
|
||||
'\n\nThe data directory will be changed when OpenLP is '
|
||||
'closed.').format(path=new_data_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
@ -608,10 +608,10 @@ class AdvancedTab(SettingsTab):
|
||||
answer = QtWidgets.QMessageBox.warning(self,
|
||||
translate('OpenLP.AdvancedTab', 'Overwrite Existing Data'),
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'WARNING: \n\nThe location you have selected \n\n%s\n\n'
|
||||
'appears to contain OpenLP data files. Do you wish to '
|
||||
'replace these files with the current data files?').
|
||||
replace('%s', os.path.abspath(data_path,)),
|
||||
'WARNING: \n\nThe location you have selected \n\n{path}'
|
||||
'\n\nappears to contain OpenLP data files. Do you wish to '
|
||||
'replace these files with the current data '
|
||||
'files?').format(path=os.path.abspath(data_path,)),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
|
@ -91,6 +91,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
||||
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
|
||||
self.setupUi(self)
|
||||
self.settings_section = 'crashreport'
|
||||
# TODO: Need to see how to format strings when string with tags is actually a variable
|
||||
self.report_text = '**OpenLP Bug Report**\n' \
|
||||
'Version: %s\n\n' \
|
||||
'--- Details of the Exception. ---\n\n%s\n\n ' \
|
||||
@ -114,21 +115,17 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
||||
openlp_version = get_application_version()
|
||||
description = self.description_text_edit.toPlainText()
|
||||
traceback = self.exception_text_edit.toPlainText()
|
||||
system = translate('OpenLP.ExceptionForm', 'Platform: %s\n') % platform.platform()
|
||||
libraries = 'Python: %s\n' % platform.python_version() + \
|
||||
'Qt5: %s\n' % Qt.qVersion() + \
|
||||
'PyQt5: %s\n' % Qt.PYQT_VERSION_STR + \
|
||||
'QtWebkit: %s\n' % WEBKIT_VERSION + \
|
||||
'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \
|
||||
'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \
|
||||
'BeautifulSoup: %s\n' % bs4.__version__ + \
|
||||
'lxml: %s\n' % etree.__version__ + \
|
||||
'Chardet: %s\n' % CHARDET_VERSION + \
|
||||
'PyEnchant: %s\n' % ENCHANT_VERSION + \
|
||||
'Mako: %s\n' % MAKO_VERSION + \
|
||||
'pyICU: %s\n' % ICU_VERSION + \
|
||||
'pyUNO bridge: %s\n' % self._pyuno_import() + \
|
||||
'VLC: %s\n' % VLC_VERSION
|
||||
system = translate('OpenLP.ExceptionForm', 'Platform: {platform}\n').format(platform=platform.platform())
|
||||
libraries = ('Python: {python}\nQt5: {qt5}\nPyQt5: {pyqt5}\nQtWebkit: {qtwebkit}\nSQLAlchemy: {sqalchemy}\n'
|
||||
'SQLAlchemy Migrate: {migrate}\nBeautifulSoup: {soup}\nlxml: {etree}\nChardet: {chardet}\n'
|
||||
'PyEnchant: {enchant}\nMako: {mako}\npyICU: {icu}\npyUNO bridge: {uno}\n'
|
||||
'VLC: {vlc}\n').format(python=platform.python_version(), qt5=Qt.qVersion(),
|
||||
pyqt5=Qt.PYQT_VERSION_STR, qtwebkit=WEBKIT_VERSION,
|
||||
sqalchemy=sqlalchemy.__version__, migrate=MIGRATE_VERSION,
|
||||
soup=bs4.__version__, etree=etree.__version__, chardet=CHARDET_VERSION,
|
||||
enchant=ENCHANT_VERSION, mako=MAKO_VERSION, icu=ICU_VERSION,
|
||||
uno=self._pyuno_import(), vlc=VLC_VERSION)
|
||||
|
||||
if is_linux():
|
||||
if os.environ.get('KDE_FULL_SESSION') == 'true':
|
||||
system += 'Desktop: KDE SC\n'
|
||||
@ -178,9 +175,10 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
||||
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
|
||||
if ':' in line:
|
||||
exception = line.split('\n')[-1].split(':')[0]
|
||||
subject = 'Bug report: %s in %s' % (exception, source)
|
||||
subject = 'Bug report: {error} in {source}'.format(error=exception, source=source)
|
||||
mail_urlquery = QtCore.QUrlQuery()
|
||||
mail_urlquery.addQueryItem('subject', subject)
|
||||
# TODO: Find out how to format() text that is in a variable
|
||||
mail_urlquery.addQueryItem('body', self.report_text % content)
|
||||
if self.file_attachment:
|
||||
mail_urlquery.addQueryItem('attach', self.file_attachment)
|
||||
@ -199,7 +197,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
||||
else:
|
||||
self.__button_state(False)
|
||||
self.description_word_count.setText(
|
||||
translate('OpenLP.ExceptionDialog', 'Description characters to enter : %s') % count)
|
||||
translate('OpenLP.ExceptionDialog', 'Description characters to enter : {count}').format(count=count))
|
||||
|
||||
def on_attach_file_button_clicked(self):
|
||||
"""
|
||||
@ -210,7 +208,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
||||
'Select Attachment'),
|
||||
Settings().value(self.settings_section +
|
||||
'/last directory'),
|
||||
'%s (*)' % UiStrings().AllFiles)
|
||||
'{text} (*)'.format(text=UiStrings().AllFiles))
|
||||
log.info('New files(s) %s', str(files))
|
||||
if files:
|
||||
self.file_attachment = str(files)
|
||||
|
@ -72,7 +72,7 @@ class ThemeScreenshotWorker(QtCore.QObject):
|
||||
if self.was_download_cancelled:
|
||||
return
|
||||
try:
|
||||
urllib.request.urlretrieve('%s%s' % (self.themes_url, self.screenshot),
|
||||
urllib.request.urlretrieve('{host}{name}'.format(host=self.themes_url, name=self.screenshot),
|
||||
os.path.join(gettempdir(), 'openlp', self.screenshot))
|
||||
# Signal that the screenshot has been downloaded
|
||||
self.screenshot_downloaded.emit(self.title, self.filename, self.sha256)
|
||||
@ -180,11 +180,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
||||
self.application.process_events()
|
||||
try:
|
||||
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
||||
web_config = get_web_page('{host}{name}'.format(host=self.web, name='download.cfg'),
|
||||
header=('User-Agent', user_agent))
|
||||
except (urllib.error.URLError, ConnectionError) as err:
|
||||
msg = QtWidgets.QMessageBox()
|
||||
title = translate('OpenLP.FirstTimeWizard', 'Network Error')
|
||||
msg.setText('{} {}'.format(title, err.code if hasattr(err, 'code') else ''))
|
||||
msg.setText('{title} {error}'.format(title=title,
|
||||
error=err.code if hasattr(err, 'code') else ''))
|
||||
msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
|
||||
'There was a network error attempting to '
|
||||
'connect to retrieve initial configuration information'))
|
||||
@ -205,6 +207,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
trace_error_handler(log)
|
||||
self.update_screen_list_combo()
|
||||
self.application.process_events()
|
||||
# TODO: Figure out how to use a variable with format()
|
||||
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
||||
if self.has_run_wizard:
|
||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
||||
@ -223,9 +226,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
songs = songs.split(',')
|
||||
for song in songs:
|
||||
self.application.process_events()
|
||||
title = self.config.get('songs_%s' % song, 'title')
|
||||
filename = self.config.get('songs_%s' % song, 'filename')
|
||||
sha256 = self.config.get('songs_%s' % song, 'sha256', fallback='')
|
||||
title = self.config.get('songs_{song}'.format(song=song), 'title')
|
||||
filename = self.config.get('songs_{song}'.format(song=song), 'filename')
|
||||
sha256 = self.config.get('songs_{song}'.format(song=song), 'sha256', fallback='')
|
||||
item = QtWidgets.QListWidgetItem(title, self.songs_list_widget)
|
||||
item.setData(QtCore.Qt.UserRole, (filename, sha256))
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
@ -234,15 +237,15 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
bible_languages = bible_languages.split(',')
|
||||
for lang in bible_languages:
|
||||
self.application.process_events()
|
||||
language = self.config.get('bibles_%s' % lang, 'title')
|
||||
language = self.config.get('bibles_{lang}'.format(lang=lang), 'title')
|
||||
lang_item = QtWidgets.QTreeWidgetItem(self.bibles_tree_widget, [language])
|
||||
bibles = self.config.get('bibles_%s' % lang, 'translations')
|
||||
bibles = self.config.get('bibles_{lang}'.format(lang=lang), 'translations')
|
||||
bibles = bibles.split(',')
|
||||
for bible in bibles:
|
||||
self.application.process_events()
|
||||
title = self.config.get('bible_%s' % bible, 'title')
|
||||
filename = self.config.get('bible_%s' % bible, 'filename')
|
||||
sha256 = self.config.get('bible_%s' % bible, 'sha256', fallback='')
|
||||
title = self.config.get('bible_{bible}'.format(bible=bible), 'title')
|
||||
filename = self.config.get('bible_{bible}'.format(bible=bible), 'filename')
|
||||
sha256 = self.config.get('bible_{bible}'.format(bible=bible), 'sha256', fallback='')
|
||||
item = QtWidgets.QTreeWidgetItem(lang_item, [title])
|
||||
item.setData(0, QtCore.Qt.UserRole, (filename, sha256))
|
||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
@ -252,10 +255,10 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
# Download the theme screenshots
|
||||
themes = self.config.get('themes', 'files').split(',')
|
||||
for theme in themes:
|
||||
title = self.config.get('theme_%s' % theme, 'title')
|
||||
filename = self.config.get('theme_%s' % theme, 'filename')
|
||||
sha256 = self.config.get('theme_%s' % theme, 'sha256', fallback='')
|
||||
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||
title = self.config.get('theme_{theme}'.format(theme=theme), 'title')
|
||||
filename = self.config.get('theme_{theme}'.format(theme=theme), 'filename')
|
||||
sha256 = self.config.get('theme_{theme}'.format(theme=theme), 'sha256', fallback='')
|
||||
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
|
||||
worker = ThemeScreenshotWorker(self.themes_url, title, filename, sha256, screenshot)
|
||||
self.theme_screenshot_workers.append(worker)
|
||||
worker.screenshot_downloaded.connect(self.on_screenshot_downloaded)
|
||||
@ -421,7 +424,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self._download_progress(block_count, block_size)
|
||||
filename.close()
|
||||
if sha256 and hasher.hexdigest() != sha256:
|
||||
log.error('sha256 sums did not match for file: {}'.format(f_path))
|
||||
log.error('sha256 sums did not match for file: {file}'.format(file=f_path))
|
||||
os.remove(f_path)
|
||||
return False
|
||||
except (urllib.error.URLError, socket.timeout) as err:
|
||||
@ -447,7 +450,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
themes = self.config.get('themes', 'files')
|
||||
themes = themes.split(',')
|
||||
for index, theme in enumerate(themes):
|
||||
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
|
||||
item = self.themes_list_widget.item(index)
|
||||
if item:
|
||||
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
|
||||
@ -507,7 +510,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.songs_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.songs_url, name=filename))
|
||||
self.max_progress += size
|
||||
# Loop through the Bibles list and increase for each selected item
|
||||
iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
@ -516,7 +519,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
item = iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(0, QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.bibles_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.bibles_url, name=filename))
|
||||
self.max_progress += size
|
||||
iterator += 1
|
||||
# Loop through the themes list and increase for each selected item
|
||||
@ -525,7 +528,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.themes_url, name=filename))
|
||||
self.max_progress += size
|
||||
except urllib.error.URLError:
|
||||
trace_error_handler(log)
|
||||
@ -560,22 +563,26 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
if self.max_progress:
|
||||
self.progress_bar.setValue(self.progress_bar.maximum())
|
||||
if self.has_run_wizard:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the %s button to return to OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to return to OpenLP.'
|
||||
).format(text=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the %s button to start OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText()
|
||||
else:
|
||||
if self.has_run_wizard:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the %s button to return to OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to return to OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the %s button to start OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText()
|
||||
self.finish_button.setVisible(True)
|
||||
self.finish_button.setEnabled(True)
|
||||
self.cancel_button.setVisible(False)
|
||||
@ -628,8 +635,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self._increment_progress_bar(self.downloading % filename, 0)
|
||||
self.previous_size = 0
|
||||
destination = os.path.join(songs_destination, str(filename))
|
||||
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
|
||||
missed_files.append('Song: {}'.format(filename))
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.songs_url, name=filename),
|
||||
destination, sha256):
|
||||
missed_files.append('Song: {name}'.format(name=filename))
|
||||
# Download Bibles
|
||||
bibles_iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
while bibles_iterator.value():
|
||||
@ -638,31 +646,34 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
bible, sha256 = item.data(0, QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % bible, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible),
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.bibles_url, name=bible),
|
||||
os.path.join(bibles_destination, bible),
|
||||
sha256):
|
||||
missed_files.append('Bible: {}'.format(bible))
|
||||
missed_files.append('Bible: {name}'.format(name=bible))
|
||||
bibles_iterator += 1
|
||||
# Download themes
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
theme, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
# TODO: Verify how to use format() with strings in a variable
|
||||
self._increment_progress_bar(self.downloading % theme, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme),
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.themes_url, name=theme),
|
||||
os.path.join(themes_destination, theme),
|
||||
sha256):
|
||||
missed_files.append('Theme: {}'.format(theme))
|
||||
missed_files.append('Theme: {name}'.format(name=theme))
|
||||
if missed_files:
|
||||
file_list = ''
|
||||
for entry in missed_files:
|
||||
file_list += '{}<br \>'.format(entry)
|
||||
file_list += '{text}<br \>'.format(text=entry)
|
||||
msg = QtWidgets.QMessageBox()
|
||||
msg.setIcon(QtWidgets.QMessageBox.Warning)
|
||||
msg.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'Network Error'))
|
||||
msg.setText(translate('OpenLP.FirstTimeWizard', 'Unable to download some files'))
|
||||
msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
|
||||
'The following files were not able to be '
|
||||
'downloaded:<br \>{}'.format(file_list)))
|
||||
'downloaded:<br \>{text}'.format(text=file_list)))
|
||||
msg.setStandardButtons(msg.Ok)
|
||||
ans = msg.exec()
|
||||
return True
|
||||
|
@ -228,12 +228,13 @@ class UiFirstTimeWizard(object):
|
||||
:param first_time_wizard: The wizard form
|
||||
"""
|
||||
first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard'))
|
||||
first_time_wizard.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard'))
|
||||
text = translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')
|
||||
first_time_wizard.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}'
|
||||
'</span>'.format(text=text))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.NextButton))
|
||||
first_time_wizard.information_label.setText(
|
||||
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
|
||||
'Click the %s button below to start.') %
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.NextButton)))
|
||||
'Click the {button} button below to start.').format(button=button))
|
||||
self.download_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Downloading Resource Index'))
|
||||
self.download_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Please wait while the resource index is '
|
||||
'downloaded.'))
|
||||
@ -264,18 +265,19 @@ class UiFirstTimeWizard(object):
|
||||
self.no_internet_page.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection'))
|
||||
self.no_internet_page.setSubTitle(
|
||||
translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.'))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
self.no_internet_text = translate('OpenLP.FirstTimeWizard',
|
||||
'No Internet connection was found. The First Time Wizard needs an Internet '
|
||||
'connection in order to be able to download sample songs, Bibles and themes.'
|
||||
' Click the %s button now to start OpenLP with initial settings and '
|
||||
' Click the {button} button now to start OpenLP with initial settings and '
|
||||
'no sample data.\n\nTo re-run the First Time Wizard and import this sample '
|
||||
'data at a later time, check your Internet connection and re-run this '
|
||||
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.') % \
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.'
|
||||
).format(button=button)
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton))
|
||||
self.cancel_wizard_text = translate('OpenLP.FirstTimeWizard',
|
||||
'\n\nTo cancel the First Time Wizard completely (and not start OpenLP), '
|
||||
'click the %s button now.') % \
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton))
|
||||
'click the {button} button now.').format(button=button)
|
||||
self.songs_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs'))
|
||||
self.songs_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.'))
|
||||
self.bibles_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles'))
|
||||
|
@ -72,19 +72,19 @@ class FormattingTagController(object):
|
||||
"""
|
||||
for line_number, html1 in enumerate(self.protected_tags):
|
||||
if self._strip(html1['start tag']) == tag:
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag {tag} already defined.').format(tag=tag)
|
||||
if self._strip(html1['desc']) == desc:
|
||||
return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Description {tag} already defined.').format(tag=tag)
|
||||
for line_number, html1 in enumerate(self.custom_tags):
|
||||
if self._strip(html1['start tag']) == tag:
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag {tag} already defined.').format(tag=tag)
|
||||
if self._strip(html1['desc']) == desc:
|
||||
return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Description {tag} already defined.').format(tag=tag)
|
||||
tag = {
|
||||
'desc': desc,
|
||||
'start tag': '{%s}' % tag,
|
||||
'start tag': '{{{tag}}}'.format(tag=tag),
|
||||
'start html': start_html,
|
||||
'end tag': '{/%s}' % tag,
|
||||
'end tag': '{/{tag}}}'.format(tag=tag),
|
||||
'end html': end_html,
|
||||
'protected': False,
|
||||
'temporary': False
|
||||
@ -130,6 +130,7 @@ class FormattingTagController(object):
|
||||
elif not match.group('empty'):
|
||||
end_tags.append(tag)
|
||||
match = self.html_tag_regex.search(start_html, match.end())
|
||||
# TODO: Verify format() works with lambda
|
||||
return ''.join(map(lambda tag: '</%s>' % tag, reversed(end_tags)))
|
||||
|
||||
def start_tag_changed(self, start_html, end_html):
|
||||
@ -146,7 +147,8 @@ class FormattingTagController(object):
|
||||
end = self.start_html_to_end_html(start_html)
|
||||
if not end_html:
|
||||
if not end:
|
||||
return translate('OpenLP.FormattingTagForm', 'Start tag %s is not valid HTML') % start_html, None
|
||||
return translate('OpenLP.FormattingTagForm',
|
||||
'Start tag {tag} is not valid HTML').format(tag=start_html), None
|
||||
return None, end
|
||||
return None, None
|
||||
|
||||
@ -165,7 +167,8 @@ class FormattingTagController(object):
|
||||
if not end_html:
|
||||
return None, end
|
||||
if end and end != end_html:
|
||||
return translate('OpenLP.FormattingTagForm',
|
||||
'End tag %(end)s does not match end tag for start tag %(start)s') % \
|
||||
{'end': end, 'start': start_html}, None
|
||||
return (translate('OpenLP.FormattingTagForm',
|
||||
'End tag {end} does not match end tag for start tag {start}').format(end=end,
|
||||
start=start_html),
|
||||
None)
|
||||
return None, None
|
||||
|
@ -90,9 +90,10 @@ class FormattingTagForm(QtWidgets.QDialog, Ui_FormattingTagDialog, FormattingTag
|
||||
"""
|
||||
new_row = self.tag_table_widget.rowCount()
|
||||
self.tag_table_widget.insertRow(new_row)
|
||||
self.tag_table_widget.setItem(new_row, 0, QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm',
|
||||
'New Tag %d' % new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 1, QtWidgets.QTableWidgetItem('n%d' % new_row))
|
||||
self.tag_table_widget.setItem(new_row, 0,
|
||||
QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm',
|
||||
'New Tag {row:d}').format(row=new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 1, QtWidgets.QTableWidgetItem('n{row:d}'.format(row=new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 2,
|
||||
QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm', '<HTML here>')))
|
||||
self.tag_table_widget.setItem(new_row, 3, QtWidgets.QTableWidgetItem(''))
|
||||
|
@ -400,7 +400,7 @@ class GeneralTab(SettingsTab):
|
||||
"""
|
||||
Select the logo file
|
||||
"""
|
||||
file_filters = '%s;;%s (*.*)' % (get_images_filter(), UiStrings().AllFiles)
|
||||
file_filters = '{text};;{names} (*.*)'.format(text=get_images_filter(), names=UiStrings().AllFiles)
|
||||
filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(self,
|
||||
translate('OpenLP.AdvancedTab', 'Open File'), '',
|
||||
file_filters)
|
||||
|
@ -27,7 +27,7 @@ It is based on a QTableWidget but represents its contents in list form.
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import RegistryProperties, Settings
|
||||
from openlp.core.lib import ImageSource, ServiceItem
|
||||
from openlp.core.lib import ImageSource, ItemCapabilities, ServiceItem
|
||||
|
||||
|
||||
class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
||||
@ -152,14 +152,16 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
||||
else:
|
||||
label.setScaledContents(True)
|
||||
if self.service_item.is_command():
|
||||
pixmap = QtGui.QPixmap(frame['image'])
|
||||
pixmap.setDevicePixelRatio(label.devicePixelRatio())
|
||||
label.setPixmap(pixmap)
|
||||
if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
|
||||
image = self.image_manager.get_image(frame['image'], ImageSource.CommandPlugins)
|
||||
pixmap = QtGui.QPixmap.fromImage(image)
|
||||
else:
|
||||
pixmap = QtGui.QPixmap(frame['image'])
|
||||
else:
|
||||
image = self.image_manager.get_image(frame['path'], ImageSource.ImagePlugin)
|
||||
pixmap = QtGui.QPixmap.fromImage(image)
|
||||
pixmap.setDevicePixelRatio(label.devicePixelRatio())
|
||||
label.setPixmap(pixmap)
|
||||
pixmap.setDevicePixelRatio(label.devicePixelRatio())
|
||||
label.setPixmap(pixmap)
|
||||
slide_height = width // self.screen_ratio
|
||||
# Setup and validate row height cap if in use.
|
||||
max_img_row_height = Settings().value('advanced/slide max height')
|
||||
|
@ -471,7 +471,8 @@ class Ui_MainWindow(object):
|
||||
self.web_site_item.setText(translate('OpenLP.MainWindow', '&Web Site'))
|
||||
for item in self.language_group.actions():
|
||||
item.setText(item.objectName())
|
||||
item.setStatusTip(translate('OpenLP.MainWindow', 'Set the interface language to %s') % item.objectName())
|
||||
item.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Set the interface language to {name}').format(name=item.objectName()))
|
||||
self.auto_language_item.setText(translate('OpenLP.MainWindow', '&Autodetect'))
|
||||
self.auto_language_item.setStatusTip(translate('OpenLP.MainWindow', 'Use the system language, if available.'))
|
||||
self.tools_add_tool_item.setText(translate('OpenLP.MainWindow', 'Add &Tool...'))
|
||||
@ -1334,8 +1335,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
||||
for file_id, filename in enumerate(recent_files_to_display):
|
||||
log.debug('Recent file name: {name}'.format(name=filename))
|
||||
# TODO: Verify ''.format() before committing
|
||||
action = create_action(self, '', text='&%d %s' % (file_id + 1,
|
||||
os.path.splitext(os.path.basename(str(filename)))[0]), data=filename,
|
||||
action = create_action(self, '',
|
||||
text='&{n} {name}'.format(n=file_id + 1,
|
||||
name=os.path.splitext(os.path.basename(str(filename)))[0]),
|
||||
data=filename,
|
||||
triggers=self.service_manager_contents.on_recent_service_clicked)
|
||||
self.recent_files_menu.addAction(action)
|
||||
clear_recent_files_action = create_action(self, '',
|
||||
|
@ -53,15 +53,9 @@ class Ui_PluginViewDialog(object):
|
||||
self.plugin_info_layout.setObjectName('plugin_info_layout')
|
||||
self.status_label = QtWidgets.QLabel(self.plugin_info_group_box)
|
||||
self.status_label.setObjectName('status_label')
|
||||
self.status_combo_box = QtWidgets.QComboBox(self.plugin_info_group_box)
|
||||
self.status_combo_box.addItems(('', ''))
|
||||
self.status_combo_box.setObjectName('status_combo_box')
|
||||
self.plugin_info_layout.addRow(self.status_label, self.status_combo_box)
|
||||
self.version_label = QtWidgets.QLabel(self.plugin_info_group_box)
|
||||
self.version_label.setObjectName('version_label')
|
||||
self.version_number_label = QtWidgets.QLabel(self.plugin_info_group_box)
|
||||
self.version_number_label.setObjectName('version_number_label')
|
||||
self.plugin_info_layout.addRow(self.version_label, self.version_number_label)
|
||||
self.status_checkbox = QtWidgets.QCheckBox(self.plugin_info_group_box)
|
||||
self.status_checkbox.setObjectName('status_checkbox')
|
||||
self.plugin_info_layout.addRow(self.status_label, self.status_checkbox)
|
||||
self.about_label = QtWidgets.QLabel(self.plugin_info_group_box)
|
||||
self.about_label.setObjectName('about_label')
|
||||
self.about_text_browser = QtWidgets.QTextBrowser(self.plugin_info_group_box)
|
||||
@ -80,8 +74,6 @@ class Ui_PluginViewDialog(object):
|
||||
"""
|
||||
plugin_view_dialog.setWindowTitle(translate('OpenLP.PluginForm', 'Manage Plugins'))
|
||||
self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
|
||||
self.version_label.setText('%s:' % UiStrings().Version)
|
||||
self.about_label.setText('%s:' % UiStrings().About)
|
||||
self.about_label.setText('{about}:'.format(about=UiStrings().About))
|
||||
self.status_label.setText(translate('OpenLP.PluginForm', 'Status:'))
|
||||
self.status_combo_box.setItemText(0, translate('OpenLP.PluginForm', 'Active'))
|
||||
self.status_combo_box.setItemText(1, translate('OpenLP.PluginForm', 'Inactive'))
|
||||
self.status_checkbox.setText(translate('OpenLP.PluginForm', 'Active'))
|
||||
|
@ -49,7 +49,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
||||
self._clear_details()
|
||||
# Right, now let's put some signals and slots together!
|
||||
self.plugin_list_widget.itemSelectionChanged.connect(self.on_plugin_list_widget_selection_changed)
|
||||
self.status_combo_box.currentIndexChanged.connect(self.on_status_combo_box_changed)
|
||||
self.status_checkbox.stateChanged.connect(self.on_status_checkbox_changed)
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
@ -60,6 +60,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
||||
self._clear_details()
|
||||
self.programatic_change = True
|
||||
plugin_list_width = 0
|
||||
# TODO: See how to use format() with variables
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
item = QtWidgets.QListWidgetItem(self.plugin_list_widget)
|
||||
# We do this just to make 100% sure the status is an integer as
|
||||
@ -86,24 +87,23 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
||||
"""
|
||||
Clear the plugin details widgets
|
||||
"""
|
||||
self.status_combo_box.setCurrentIndex(-1)
|
||||
self.version_number_label.setText('')
|
||||
self.status_checkbox.setChecked(False)
|
||||
self.about_text_browser.setHtml('')
|
||||
self.status_combo_box.setEnabled(False)
|
||||
self.status_checkbox.setEnabled(False)
|
||||
|
||||
def _set_details(self):
|
||||
"""
|
||||
Set the details of the currently selected plugin
|
||||
"""
|
||||
log.debug('PluginStatus: %s', str(self.active_plugin.status))
|
||||
self.version_number_label.setText(self.active_plugin.version)
|
||||
log.debug('PluginStatus: {status}'.format(status=str(self.active_plugin.status)))
|
||||
self.about_text_browser.setHtml(self.active_plugin.about())
|
||||
self.programatic_change = True
|
||||
status = PluginStatus.Active
|
||||
if self.active_plugin.status == PluginStatus.Active:
|
||||
status = PluginStatus.Inactive
|
||||
self.status_combo_box.setCurrentIndex(status)
|
||||
self.status_combo_box.setEnabled(True)
|
||||
if self.active_plugin.status != PluginStatus.Disabled:
|
||||
self.status_checkbox.setChecked(self.active_plugin.status == PluginStatus.Active)
|
||||
self.status_checkbox.setEnabled(True)
|
||||
else:
|
||||
self.status_checkbox.setChecked(False)
|
||||
self.status_checkbox.setEnabled(False)
|
||||
self.programatic_change = False
|
||||
|
||||
def on_plugin_list_widget_selection_changed(self):
|
||||
@ -116,28 +116,28 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
||||
plugin_name_singular = self.plugin_list_widget.currentItem().text().split('(')[0][:-1]
|
||||
self.active_plugin = None
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.status != PluginStatus.Disabled:
|
||||
if plugin.name_strings['singular'] == plugin_name_singular:
|
||||
self.active_plugin = plugin
|
||||
break
|
||||
if plugin.name_strings['singular'] == plugin_name_singular:
|
||||
self.active_plugin = plugin
|
||||
break
|
||||
if self.active_plugin:
|
||||
self._set_details()
|
||||
else:
|
||||
self._clear_details()
|
||||
|
||||
def on_status_combo_box_changed(self, status):
|
||||
def on_status_checkbox_changed(self, status):
|
||||
"""
|
||||
If the status of a plugin is altered, apply the change
|
||||
"""
|
||||
if self.programatic_change or status == PluginStatus.Disabled:
|
||||
if self.programatic_change or self.active_plugin is None:
|
||||
return
|
||||
if status == PluginStatus.Inactive:
|
||||
if status:
|
||||
self.application.set_busy_cursor()
|
||||
self.active_plugin.toggle_status(PluginStatus.Active)
|
||||
self.application.set_normal_cursor()
|
||||
self.active_plugin.app_startup()
|
||||
else:
|
||||
self.active_plugin.toggle_status(PluginStatus.Inactive)
|
||||
# TODO: Verify using format() with a variable
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Inactive)')
|
||||
if self.active_plugin.status == PluginStatus.Active:
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Active)')
|
||||
|
@ -118,7 +118,7 @@ class Ui_ServiceManager(object):
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||
triggers=self.decide_save_method)
|
||||
self.toolbar.addSeparator()
|
||||
self.theme_label = QtWidgets.QLabel('%s:' % UiStrings().Theme, widget)
|
||||
self.theme_label = QtWidgets.QLabel('{theme}:'.format(theme=UiStrings().Theme), widget)
|
||||
self.theme_label.setContentsMargins(3, 3, 3, 3)
|
||||
self.theme_label.setObjectName('theme_label')
|
||||
self.toolbar.add_toolbar_widget(self.theme_label)
|
||||
@ -503,8 +503,8 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
self.log_debug('ServiceManager.save_file - %s' % path_file_name)
|
||||
service_file_name = '{name}.osj'.format(name=base_name)
|
||||
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = self.create_basic_service()
|
||||
write_list = []
|
||||
@ -530,8 +530,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
self.application.set_normal_cursor()
|
||||
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
||||
message = translate('OpenLP.ServiceManager',
|
||||
'The following file(s) in the service are missing: %s\n\n'
|
||||
'These files will be removed if you continue to save.') % "\n\t".join(missing_list)
|
||||
'The following file(s) in the service are missing: {name}\n\n'
|
||||
'These files will be removed if you continue to save.'
|
||||
).format(name="\n\t".join(missing_list))
|
||||
answer = QtWidgets.QMessageBox.critical(self, title, message,
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok |
|
||||
QtWidgets.QMessageBox.Cancel))
|
||||
@ -561,7 +562,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
service_content = json.dumps(service)
|
||||
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX.
|
||||
allow_zip_64 = (total_size > 2147483648 + len(service_content))
|
||||
self.log_debug('ServiceManager.save_file - allowZip64 is %s' % allow_zip_64)
|
||||
self.log_debug('ServiceManager.save_file - allowZip64 is {text}'.format(text=allow_zip_64))
|
||||
zip_file = None
|
||||
success = True
|
||||
self.main_window.increment_progress_bar()
|
||||
@ -584,7 +585,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
shutil.copy(audio_from, save_file)
|
||||
zip_file.write(audio_from, audio_to)
|
||||
except IOError:
|
||||
self.log_exception('Failed to save service to disk: %s' % temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
@ -601,7 +602,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
except OSError as ose:
|
||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'An error occurred while writing the '
|
||||
'service file: %s') % ose.strerror,
|
||||
'service file: {error}').format(error=ose.strerror),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
success = False
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
@ -623,8 +624,8 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
self.log_debug('ServiceManager.save_file - %s' % path_file_name)
|
||||
service_file_name = '{name}.osj'.format(name=base_name)
|
||||
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = self.create_basic_service()
|
||||
self.application.set_busy_cursor()
|
||||
@ -645,7 +646,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
# First we add service contents.
|
||||
zip_file.writestr(service_file_name, service_content)
|
||||
except IOError:
|
||||
self.log_exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
@ -740,13 +741,13 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
try:
|
||||
ucs_file = zip_info.filename
|
||||
except UnicodeDecodeError:
|
||||
self.log_exception('file_name "%s" is not valid UTF-8' % zip_info.file_name)
|
||||
self.log_exception('file_name "{name}" is not valid UTF-8'.format(name=zip_info.file_name))
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n The content encoding is not UTF-8.'))
|
||||
continue
|
||||
os_file = ucs_file.replace('/', os.path.sep)
|
||||
os_file = os.path.basename(os_file)
|
||||
self.log_debug('Extract file: %s' % os_file)
|
||||
self.log_debug('Extract file: {name}'.format(name=os_file))
|
||||
zip_info.filename = os_file
|
||||
zip_file.extract(zip_info, self.service_path)
|
||||
if os_file.endswith('osj') or os_file.endswith('osd'):
|
||||
@ -774,18 +775,18 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
|
||||
self.log_error('File contains no service data')
|
||||
except (IOError, NameError, zipfile.BadZipfile):
|
||||
self.log_exception('Problem loading service file %s' % file_name)
|
||||
self.log_exception('Problem loading service file {name}'.format(name=file_name))
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File could not be opened because it is corrupt.'))
|
||||
except zipfile.BadZipfile:
|
||||
if os.path.getsize(file_name) == 0:
|
||||
self.log_exception('Service file is zero sized: %s' % file_name)
|
||||
self.log_exception('Service file is zero sized: {name}'.format(name=file_name))
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This service file does not contain '
|
||||
'any data.'))
|
||||
else:
|
||||
self.log_exception('Service file is cannot be extracted as zip: %s' % file_name)
|
||||
self.log_exception('Service file is cannot be extracted as zip: {name}'.format(name=file_name))
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This file is either corrupt or it is not an OpenLP 2 '
|
||||
@ -874,7 +875,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
self.auto_play_slides_loop.setChecked(service_item['service_item'].auto_play_slides_loop)
|
||||
self.timed_slide_interval.setChecked(service_item['service_item'].timed_slide_interval > 0)
|
||||
if service_item['service_item'].timed_slide_interval > 0:
|
||||
delay_suffix = ' %s s' % str(service_item['service_item'].timed_slide_interval)
|
||||
delay_suffix = ' {text} s'.format(text=str(service_item['service_item'].timed_slide_interval))
|
||||
else:
|
||||
delay_suffix = ' ...'
|
||||
self.timed_slide_interval.setText(
|
||||
@ -1268,14 +1269,17 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
tree_widget_item.setText(0, service_item_from_item.get_display_title())
|
||||
tips = []
|
||||
if service_item_from_item.temporary_edit:
|
||||
tips.append('<strong>%s:</strong> <em>%s</em>' % (translate('OpenLP.ServiceManager', 'Edit'),
|
||||
(translate('OpenLP.ServiceManager', 'Service copy only'))))
|
||||
text1 = translate('OpenLP.ServiceManager', 'Edit')
|
||||
text2 = translate('OpenLP.ServiceManager', 'Service copy only')
|
||||
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text1, text2=text2))
|
||||
if service_item_from_item.theme and service_item_from_item.theme != -1:
|
||||
tips.append('<strong>%s:</strong> <em>%s</em>' %
|
||||
(translate('OpenLP.ServiceManager', 'Slide theme'), service_item_from_item.theme))
|
||||
text = translate('OpenLP.ServiceManager', 'Slide theme')
|
||||
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text,
|
||||
text2=service_item_from_item.theme))
|
||||
if service_item_from_item.notes:
|
||||
tips.append('<strong>%s: </strong> %s' %
|
||||
(translate('OpenLP.ServiceManager', 'Notes'), html.escape(service_item_from_item.notes)))
|
||||
text1 = translate('OpenLP.ServiceManager', 'Notes')
|
||||
text2 = html.escape(service_item_from_item.notes)
|
||||
tips.append('<strong>{text1}: </strong> {text2}'.format(text1=text1, text2=text2))
|
||||
if item['service_item'].is_capable(ItemCapabilities.HasVariableStartTime):
|
||||
tips.append(item['service_item'].get_media_time())
|
||||
tree_widget_item.setToolTip(0, '<br>'.join(tips))
|
||||
@ -1324,8 +1328,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
|
||||
"""
|
||||
visible = not self.renderer.theme_level == ThemeLevel.Global
|
||||
self.theme_label.setVisible(visible)
|
||||
self.theme_combo_box.setVisible(visible)
|
||||
self.toolbar.actions['theme_combo_box'].setVisible(visible)
|
||||
self.toolbar.actions['theme_label'].setVisible(visible)
|
||||
self.regenerate_service_items()
|
||||
|
||||
def regenerate_service_items(self, changed=False):
|
||||
"""
|
||||
@ -1636,7 +1641,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
replace = True
|
||||
else:
|
||||
self.drop_position = get_parent_item_data(item) - 1
|
||||
Registry().execute('%s_add_service_item' % plugin, replace)
|
||||
Registry().execute('{plugin}_add_service_item'.format(plugin=plugin), replace)
|
||||
|
||||
def update_theme_list(self, theme_list):
|
||||
"""
|
||||
|
@ -60,7 +60,8 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
||||
"""
|
||||
Execute the form
|
||||
"""
|
||||
# load all the settings
|
||||
# load all the
|
||||
self.setting_list_widget.blockSignals(True)
|
||||
self.setting_list_widget.clear()
|
||||
while self.stacked_layout.count():
|
||||
# take at 0 and the rest shuffle up.
|
||||
@ -74,6 +75,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
||||
if plugin.settings_tab:
|
||||
self.insert_tab(plugin.settings_tab, plugin.is_active())
|
||||
self.setting_list_widget.setCurrentRow(0)
|
||||
self.setting_list_widget.blockSignals(False)
|
||||
return QtWidgets.QDialog.exec(self)
|
||||
|
||||
def insert_tab(self, tab_widget, is_visible=True):
|
||||
@ -83,7 +85,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
||||
:param tab_widget: The widget to add
|
||||
:param is_visible: If this tab should be visible
|
||||
"""
|
||||
log.debug('Inserting %s tab' % tab_widget.tab_title)
|
||||
log.debug('Inserting {text} tab'.format(text=tab_widget.tab_title))
|
||||
# add the tab to get it to display in the correct part of the screen
|
||||
self.stacked_layout.addWidget(tab_widget)
|
||||
if is_visible:
|
||||
@ -177,6 +179,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
||||
# Check that the title of the tab (i.e. plugin name) is the same as the data in the list item
|
||||
if tab_widget.tab_title == list_item.data(QtCore.Qt.UserRole):
|
||||
# Make the matching tab visible
|
||||
tab_widget.tab_visited = True
|
||||
self.stacked_layout.setCurrentIndex(tab_index)
|
||||
self.stacked_layout.currentWidget().tab_visible()
|
||||
|
||||
|
@ -425,11 +425,12 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if not is_valid:
|
||||
text = translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "{key}" is already assigned to another action, please'
|
||||
' use a different shortcut.'
|
||||
).format(key=self.get_shortcut_string(key_sequence))
|
||||
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "%s" is already assigned to another action, please'
|
||||
' use a different shortcut.') %
|
||||
self.get_shortcut_string(key_sequence, for_display=True))
|
||||
text, for_display=True)
|
||||
self.dialog_was_shown = True
|
||||
return is_valid
|
||||
|
||||
|
@ -98,7 +98,7 @@ class DisplayController(QtWidgets.QWidget):
|
||||
"""
|
||||
sender = self.sender().objectName() if self.sender().objectName() else self.sender().text()
|
||||
controller = self
|
||||
Registry().execute('%s' % sender, [controller, args])
|
||||
Registry().execute('{text}'.format(text=sender), [controller, args])
|
||||
|
||||
|
||||
class InfoLabel(QtWidgets.QLabel):
|
||||
@ -395,7 +395,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
{'key': 'O', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Other"')}
|
||||
]
|
||||
shortcuts.extend([{'key': str(number)} for number in range(10)])
|
||||
self.controller.addActions([create_action(self, 'shortcutAction_%s' % s['key'],
|
||||
self.controller.addActions([create_action(self, 'shortcutAction_{key}'.format(key=s['key']),
|
||||
text=s.get('text'),
|
||||
can_shortcuts=True,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
@ -417,14 +417,20 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
self.preview_widget.doubleClicked.connect(self.on_preview_double_click)
|
||||
self.toolbar.set_widget_visible(['editSong'], False)
|
||||
self.controller.addActions([self.next_item, self.previous_item])
|
||||
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
|
||||
Registry().register_function('slidecontroller_%s_change' % self.type_prefix, self.on_slide_change)
|
||||
Registry().register_function('slidecontroller_%s_blank' % self.type_prefix, self.on_slide_blank)
|
||||
Registry().register_function('slidecontroller_%s_unblank' % self.type_prefix, self.on_slide_unblank)
|
||||
Registry().register_function('slidecontroller_{text}_stop_loop'.format(text=self.type_prefix),
|
||||
self.on_stop_loop)
|
||||
Registry().register_function('slidecontroller_{text}_change'.format(text=self.type_prefix),
|
||||
self.on_slide_change)
|
||||
Registry().register_function('slidecontroller_{text}_blank'.format(text=self.type_prefix),
|
||||
self.on_slide_blank)
|
||||
Registry().register_function('slidecontroller_{text}_unblank'.format(text=self.type_prefix),
|
||||
self.on_slide_unblank)
|
||||
Registry().register_function('slidecontroller_update_slide_limits', self.update_slide_limits)
|
||||
getattr(self, 'slidecontroller_%s_set' % self.type_prefix).connect(self.on_slide_selected_index)
|
||||
getattr(self, 'slidecontroller_%s_next' % self.type_prefix).connect(self.on_slide_selected_next)
|
||||
getattr(self, 'slidecontroller_%s_previous' % self.type_prefix).connect(self.on_slide_selected_previous)
|
||||
getattr(self, 'slidecontroller_{text}_set'.format(text=self.type_prefix)).connect(self.on_slide_selected_index)
|
||||
getattr(self, 'slidecontroller_{text}_next'.format(text=self.type_prefix)).connect(self.on_slide_selected_next)
|
||||
# NOTE: {t} used to keep line length < maxline
|
||||
getattr(self,
|
||||
'slidecontroller_{t}_previous'.format(t=self.type_prefix)).connect(self.on_slide_selected_previous)
|
||||
|
||||
def _slide_shortcut_activated(self):
|
||||
"""
|
||||
@ -841,7 +847,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
self.service_item = copy.copy(service_item)
|
||||
if self.service_item.is_command():
|
||||
Registry().execute(
|
||||
'%s_start' % service_item.name.lower(), [self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
'{text}_start'.format(text=service_item.name.lower()),
|
||||
[self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
# Reset blanking if needed
|
||||
if old_item and self.is_live and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
|
||||
@ -879,8 +886,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if frame['verseTag']:
|
||||
# These tags are already translated.
|
||||
verse_def = frame['verseTag']
|
||||
verse_def = '%s%s' % (verse_def[0], verse_def[1:])
|
||||
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
|
||||
verse_def = '{def1}{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
|
||||
two_line_def = '{def1}\n{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
|
||||
row = two_line_def
|
||||
if verse_def not in self.slide_list:
|
||||
self.slide_list[verse_def] = frame_number
|
||||
@ -915,10 +922,10 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
# close the previous, so make sure we don't close the new one.
|
||||
if old_item.is_command() and not self.service_item.is_command() or \
|
||||
old_item.is_command() and not old_item.is_media() and self.service_item.is_media():
|
||||
Registry().execute('%s_stop' % old_item.name.lower(), [old_item, self.is_live])
|
||||
Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live])
|
||||
if old_item.is_media() and not self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
Registry().execute('slidecontroller_%s_started' % self.type_prefix, [self.service_item])
|
||||
Registry().execute('slidecontroller_{item}_started'.format(item=self.type_prefix), [self.service_item])
|
||||
|
||||
def on_slide_selected_index(self, message):
|
||||
"""
|
||||
@ -930,7 +937,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_slide' % self.service_item.name.lower(), [self.service_item, self.is_live, index])
|
||||
Registry().execute('{name}_slide'.format(name=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, index])
|
||||
self.update_preview()
|
||||
self.selected_row = index
|
||||
else:
|
||||
@ -975,7 +983,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
"""
|
||||
if checked is None:
|
||||
checked = self.blank_screen.isChecked()
|
||||
self.log_debug('on_blank_display %s' % checked)
|
||||
self.log_debug('on_blank_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.blank_screen)
|
||||
self.blank_screen.setChecked(checked)
|
||||
self.theme_screen.setChecked(False)
|
||||
@ -996,7 +1004,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
"""
|
||||
if checked is None:
|
||||
checked = self.theme_screen.isChecked()
|
||||
self.log_debug('on_theme_display %s' % checked)
|
||||
self.log_debug('on_theme_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.theme_screen)
|
||||
self.blank_screen.setChecked(False)
|
||||
self.theme_screen.setChecked(checked)
|
||||
@ -1017,7 +1025,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
"""
|
||||
if checked is None:
|
||||
checked = self.desktop_screen.isChecked()
|
||||
self.log_debug('on_hide_display %s' % checked)
|
||||
self.log_debug('on_hide_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.desktop_screen)
|
||||
self.blank_screen.setChecked(False)
|
||||
self.theme_screen.setChecked(False)
|
||||
@ -1035,17 +1043,18 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
Blank/Hide the display screen within a plugin if required.
|
||||
"""
|
||||
hide_mode = self.hide_mode()
|
||||
self.log_debug('blank_plugin %s ' % hide_mode)
|
||||
self.log_debug('blank_plugin {text}'.format(text=hide_mode))
|
||||
if self.service_item is not None:
|
||||
if hide_mode:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_hide', hide_mode)
|
||||
Registry().execute('%s_blank' %
|
||||
self.service_item.name.lower(), [self.service_item, self.is_live, hide_mode])
|
||||
Registry().execute('{text}_blank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, hide_mode])
|
||||
else:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_show')
|
||||
Registry().execute('%s_unblank' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_unblank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if hide_mode:
|
||||
Registry().execute('live_display_hide', hide_mode)
|
||||
@ -1056,15 +1065,17 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
"""
|
||||
Tell the plugin to hide the display screen.
|
||||
"""
|
||||
self.log_debug('hide_plugin %s ' % hide)
|
||||
self.log_debug('hide_plugin {text}'.format(text=hide))
|
||||
if self.service_item is not None:
|
||||
if hide:
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
Registry().execute('%s_hide' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_hide'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_show')
|
||||
Registry().execute('%s_unblank' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_unblank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if hide:
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
@ -1099,8 +1110,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if -1 < row < self.preview_widget.slide_count():
|
||||
if self.service_item.is_command():
|
||||
if self.is_live and not start:
|
||||
Registry().execute('%s_slide' %
|
||||
self.service_item.name.lower(), [self.service_item, self.is_live, row])
|
||||
Registry().execute('{text}_slide'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, row])
|
||||
else:
|
||||
to_display = self.service_item.get_rendered_frame(row)
|
||||
if self.service_item.is_text():
|
||||
@ -1133,11 +1144,23 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
"""
|
||||
This updates the preview frame, for example after changing a slide or using *Blank to Theme*.
|
||||
"""
|
||||
self.log_debug('update_preview %s ' % self.screens.current['primary'])
|
||||
self.log_debug('update_preview {text} '.format(text=self.screens.current['primary']))
|
||||
if self.service_item and self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
|
||||
# Grab now, but try again in a couple of seconds if slide change is slow
|
||||
QtCore.QTimer.singleShot(500, self.grab_maindisplay)
|
||||
QtCore.QTimer.singleShot(2500, self.grab_maindisplay)
|
||||
if self.is_live:
|
||||
# If live, grab screen-cap of main display now
|
||||
QtCore.QTimer.singleShot(500, self.grab_maindisplay)
|
||||
# but take another in a couple of seconds in case slide change is slow
|
||||
QtCore.QTimer.singleShot(2500, self.grab_maindisplay)
|
||||
else:
|
||||
# If not live, use the slide's thumbnail/icon instead
|
||||
image_path = self.service_item.get_rendered_frame(self.selected_row)
|
||||
if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
|
||||
image = self.image_manager.get_image(image_path, ImageSource.CommandPlugins)
|
||||
self.slide_image = QtGui.QPixmap.fromImage(image)
|
||||
else:
|
||||
self.slide_image = QtGui.QPixmap(image_path)
|
||||
self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
|
||||
self.slide_preview.setPixmap(self.slide_image)
|
||||
else:
|
||||
self.slide_image = self.display.preview()
|
||||
self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
|
||||
@ -1173,7 +1196,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_next' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_next'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.is_live:
|
||||
self.update_preview()
|
||||
else:
|
||||
@ -1201,7 +1225,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_previous' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_previous'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.is_live:
|
||||
self.update_preview()
|
||||
else:
|
||||
@ -1253,7 +1278,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
checked = self.play_slides_loop.isChecked()
|
||||
else:
|
||||
self.play_slides_loop.setChecked(checked)
|
||||
self.log_debug('on_play_slides_loop %s' % checked)
|
||||
self.log_debug('on_play_slides_loop {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_loop.setText(UiStrings().StopPlaySlidesInLoop)
|
||||
@ -1276,7 +1301,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
checked = self.play_slides_once.isChecked()
|
||||
else:
|
||||
self.play_slides_once.setChecked(checked)
|
||||
self.log_debug('on_play_slides_once %s' % checked)
|
||||
self.log_debug('on_play_slides_once {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_once.setText(UiStrings().StopPlaySlidesToEnd)
|
||||
@ -1342,7 +1367,8 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
# Live and Preview have issues if we have video or presentations
|
||||
# playing in both at the same time.
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_stop'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
self.on_go_live()
|
||||
|
@ -56,9 +56,9 @@ class StartTimeForm(QtWidgets.QDialog, Ui_StartTimeDialog, RegistryProperties):
|
||||
self.hour_finish_spin_box.setValue(hours)
|
||||
self.minute_finish_spin_box.setValue(minutes)
|
||||
self.second_finish_spin_box.setValue(seconds)
|
||||
self.hour_finish_label.setText('%s%s' % (str(hour), UiStrings().Hours))
|
||||
self.minute_finish_label.setText('%s%s' % (str(minutes), UiStrings().Minutes))
|
||||
self.second_finish_label.setText('%s%s' % (str(seconds), UiStrings().Seconds))
|
||||
self.hour_finish_label.setText('{val:d}{text}'.format(val=hour, text=UiStrings().Hours))
|
||||
self.minute_finish_label.setText('{val:d}{text}'.format(val=minutes, text=UiStrings().Minutes))
|
||||
self.second_finish_label.setText('{val:d}{text}'.format(val=seconds, text=UiStrings().Seconds))
|
||||
return QtWidgets.QDialog.exec(self)
|
||||
|
||||
def accept(self):
|
||||
|
@ -263,7 +263,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Run the wizard.
|
||||
"""
|
||||
log.debug('Editing theme %s' % self.theme.theme_name)
|
||||
log.debug('Editing theme {name}'.format(name=self.theme.theme_name))
|
||||
self.temp_background_filename = ''
|
||||
self.update_theme_allowed = False
|
||||
self.set_defaults()
|
||||
@ -272,7 +272,8 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
self.theme_name_edit.setVisible(not edit)
|
||||
self.edit_mode = edit
|
||||
if edit:
|
||||
self.setWindowTitle(translate('OpenLP.ThemeWizard', 'Edit Theme - %s') % self.theme.theme_name)
|
||||
self.setWindowTitle(translate('OpenLP.ThemeWizard', 'Edit Theme - {name}'
|
||||
).format(name=self.theme.theme_name))
|
||||
self.next()
|
||||
else:
|
||||
self.setWindowTitle(UiStrings().NewTheme)
|
||||
@ -282,7 +283,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Set up the pages for Initial run through dialog
|
||||
"""
|
||||
log.debug('initializePage %s' % page_id)
|
||||
log.debug('initializePage {page}'.format(page=page_id))
|
||||
wizard_page = self.page(page_id)
|
||||
if wizard_page == self.background_page:
|
||||
self.set_background_page_values()
|
||||
@ -445,7 +446,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
Background Image button pushed.
|
||||
"""
|
||||
images_filter = get_images_filter()
|
||||
images_filter = '%s;;%s (*.*)' % (images_filter, UiStrings().AllFiles)
|
||||
images_filter = '{name};;{text} (*.*)'.format(name=images_filter, text=UiStrings().AllFiles)
|
||||
filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
|
||||
self, translate('OpenLP.ThemeWizard', 'Select Image'),
|
||||
self.image_file_edit.text(), images_filter)
|
||||
@ -463,6 +464,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Background video button pushed.
|
||||
"""
|
||||
# TODO: Check this before converting
|
||||
visible_formats = '(%s)' % '; '.join(VIDEO_EXT)
|
||||
actual_formats = '(%s)' % ' '.join(VIDEO_EXT)
|
||||
video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
|
||||
|
@ -203,7 +203,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
Change the global theme when it is changed through the Themes settings tab
|
||||
"""
|
||||
self.global_theme = Settings().value(self.settings_section + '/global theme')
|
||||
self.log_debug('change_global_from_tab %s' % self.global_theme)
|
||||
self.log_debug('change_global_from_tab {text}'.format(text=self.global_theme))
|
||||
for count in range(0, self.theme_list_widget.count()):
|
||||
# reset the old name
|
||||
item = self.theme_list_widget.item(count)
|
||||
@ -213,7 +213,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
self.theme_list_widget.item(count).setText(new_name)
|
||||
# Set the new name
|
||||
if self.global_theme == new_name:
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % new_name
|
||||
name = translate('OpenLP.ThemeManager', '{text} (default)').format(text=new_name)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
self.delete_toolbar_action.setVisible(item not in self.theme_list_widget.selectedItems())
|
||||
|
||||
@ -233,7 +233,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
# Set the new name
|
||||
if count == selected_row:
|
||||
self.global_theme = self.theme_list_widget.item(count).text()
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % self.global_theme
|
||||
name = translate('OpenLP.ThemeManager', '{text} (default)').format(text=self.global_theme)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
Settings().setValue(self.settings_section + '/global theme', self.global_theme)
|
||||
Registry().execute('theme_update_global')
|
||||
@ -256,6 +256,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
Renames an existing theme to a new name
|
||||
:param field:
|
||||
"""
|
||||
# TODO: Check for delayed format() conversions
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to rename.'),
|
||||
translate('OpenLP.ThemeManager', 'Rename Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Rename %s theme?'), False, False):
|
||||
@ -284,7 +285,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
item = self.theme_list_widget.currentItem()
|
||||
old_theme_name = item.data(QtCore.Qt.UserRole)
|
||||
self.file_rename_form.file_name_edit.setText(translate('OpenLP.ThemeManager',
|
||||
'Copy of %s', 'Copy of <theme name>') % old_theme_name)
|
||||
'Copy of {name}',
|
||||
'Copy of <theme name>').format(name=old_theme_name))
|
||||
if self.file_rename_form.exec(True):
|
||||
new_theme_name = self.file_rename_form.file_name_edit.text()
|
||||
if self.check_if_theme_exists(new_theme_name):
|
||||
@ -331,6 +333,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
Delete a theme triggered by the UI.
|
||||
:param field:
|
||||
"""
|
||||
# TODO: Verify delayed format() conversions
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to delete.'),
|
||||
translate('OpenLP.ThemeManager', 'Delete Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Delete %s theme?')):
|
||||
@ -351,7 +354,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
:param theme: The theme to delete.
|
||||
"""
|
||||
self.theme_list.remove(theme)
|
||||
thumb = '%s.png' % theme
|
||||
thumb = '{name}.png'.format(name=theme)
|
||||
delete_file(os.path.join(self.path, thumb))
|
||||
delete_file(os.path.join(self.thumb_path, thumb))
|
||||
try:
|
||||
@ -363,7 +366,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
||||
except OSError as os_error:
|
||||
shutil.Error = os_error
|
||||
self.log_exception('Error deleting theme %s' % theme)
|
||||
self.log_exception('Error deleting theme {name}'.format(name=theme))
|
||||
|
||||
def on_export_theme(self, field=None):
|
||||
"""
|
||||
@ -376,7 +379,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
return
|
||||
theme = item.data(QtCore.Qt.UserRole)
|
||||
path = QtWidgets.QFileDialog.getExistingDirectory(self,
|
||||
translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme,
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Save Theme - ({name})').format(name=theme),
|
||||
Settings().value(self.settings_section +
|
||||
'/last directory export'))
|
||||
self.application.set_busy_cursor()
|
||||
@ -409,7 +413,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
self.log_exception('Export Theme Failed')
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||
translate('OpenLP.ThemeManager', 'The theme export failed because this error '
|
||||
'occurred: %s') % ose.strerror)
|
||||
'occurred: {err}').format(err=ose.strerror))
|
||||
if theme_zip:
|
||||
theme_zip.close()
|
||||
shutil.rmtree(theme_path, True)
|
||||
@ -425,7 +429,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
||||
Settings().value(self.settings_section + '/last directory import'),
|
||||
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
|
||||
self.log_info('New Themes %s' % str(files))
|
||||
self.log_info('New Themes {name}'.format(name=str(files)))
|
||||
if not files:
|
||||
return
|
||||
self.application.set_busy_cursor()
|
||||
@ -472,10 +476,10 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
if os.path.exists(theme):
|
||||
text_name = os.path.splitext(name)[0]
|
||||
if text_name == self.global_theme:
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % text_name
|
||||
name = translate('OpenLP.ThemeManager', '{name} (default)').format(name=text_name)
|
||||
else:
|
||||
name = text_name
|
||||
thumb = os.path.join(self.thumb_path, '%s.png' % text_name)
|
||||
thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=text_name))
|
||||
item_name = QtWidgets.QListWidgetItem(name)
|
||||
if validate_thumb(theme, thumb):
|
||||
icon = build_icon(thumb)
|
||||
@ -506,7 +510,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
:param theme_name: Name of the theme to load from file
|
||||
:return: The theme object.
|
||||
"""
|
||||
self.log_debug('get theme data for theme %s' % theme_name)
|
||||
self.log_debug('get theme data for theme {name}'.format(name=theme_name))
|
||||
xml_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.xml')
|
||||
xml = get_text_file_string(xml_file)
|
||||
if not xml:
|
||||
@ -524,8 +528,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
"""
|
||||
ret = QtWidgets.QMessageBox.question(self, translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Theme %s already exists. Do you want to replace it?')
|
||||
.replace('%s', theme_name),
|
||||
'Theme {name} already exists. '
|
||||
'Do you want to replace it?').format(name=theme_name),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
@ -538,7 +542,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
:param file_name:
|
||||
:param directory:
|
||||
"""
|
||||
self.log_debug('Unzipping theme %s' % file_name)
|
||||
self.log_debug('Unzipping theme {name}'.format(name=file_name))
|
||||
theme_zip = None
|
||||
out_file = None
|
||||
file_xml = None
|
||||
@ -547,7 +551,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
theme_zip = zipfile.ZipFile(file_name)
|
||||
xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
|
||||
if len(xml_file) != 1:
|
||||
self.log_error('Theme contains "%s" XML files' % len(xml_file))
|
||||
self.log_error('Theme contains "{val:d}" XML files'.format(val=len(xml_file)))
|
||||
raise ValidationError
|
||||
xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
|
||||
theme_version = xml_tree.get('version', default=None)
|
||||
@ -579,7 +583,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
out_file.write(theme_zip.read(name))
|
||||
out_file.close()
|
||||
except (IOError, zipfile.BadZipfile):
|
||||
self.log_exception('Importing theme from zip failed %s' % file_name)
|
||||
self.log_exception('Importing theme from zip failed {name|'.format(name=file_name))
|
||||
raise ValidationError
|
||||
except ValidationError:
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
@ -601,7 +605,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
||||
self.log_error('Theme file does not contain XML data %s' % file_name)
|
||||
self.log_error('Theme file does not contain XML data {name}'.format(name=file_name))
|
||||
|
||||
def check_if_theme_exists(self, theme_name):
|
||||
"""
|
||||
@ -682,7 +686,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
if os.path.exists(sample_path_name):
|
||||
os.unlink(sample_path_name)
|
||||
frame.save(sample_path_name, 'png')
|
||||
thumb = os.path.join(self.thumb_path, '%s.png' % name)
|
||||
thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=name))
|
||||
create_thumb(sample_path_name, thumb, False)
|
||||
|
||||
def update_preview_images(self):
|
||||
@ -760,14 +764,17 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
used_count = plugin.uses_theme(theme)
|
||||
if used_count:
|
||||
plugin_usage = "%s%s" % (plugin_usage, (translate('OpenLP.ThemeManager',
|
||||
'%(count)s time(s) by %(plugin)s') %
|
||||
{'count': used_count, 'plugin': plugin.name}))
|
||||
plugin_usage = "{plug}{text}".format(plug=plugin_usage,
|
||||
text=(translate('OpenLP.ThemeManager',
|
||||
'{count} time(s) by {plugin}'
|
||||
).format(name=used_count,
|
||||
plugin=plugin.name)))
|
||||
plugin_usage = "%s\n" % plugin_usage
|
||||
if plugin_usage:
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
|
||||
translate('OpenLP.ThemeManager', 'Theme is currently used \n\n%s') %
|
||||
plugin_usage)
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Theme is currently used \n\n{text}'
|
||||
).format(text=plugin_usage))
|
||||
|
||||
return False
|
||||
return True
|
||||
|
@ -405,8 +405,8 @@ class Ui_ThemeWizard(object):
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
theme_wizard.setWindowTitle(translate('OpenLP.ThemeWizard', 'Theme Wizard'))
|
||||
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard'))
|
||||
text = translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard')
|
||||
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}</span>'.format(text=text))
|
||||
self.information_label.setText(
|
||||
translate('OpenLP.ThemeWizard', 'This wizard will help you to create and edit your themes. Click the next '
|
||||
'button below to start the process by setting up your background.'))
|
||||
@ -435,9 +435,9 @@ class Ui_ThemeWizard(object):
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftBottom,
|
||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||
self.image_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.image_label.setText('%s:' % UiStrings().Image)
|
||||
self.image_label.setText('{text}:'.format(text=UiStrings().Image))
|
||||
self.video_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.video_label.setText('%s:' % UiStrings().Video)
|
||||
self.video_label.setText('{text}:'.format(text=UiStrings().Video))
|
||||
self.main_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
||||
self.main_area_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Define the font and display '
|
||||
'characteristics for the Display text'))
|
||||
|
@ -242,13 +242,13 @@ class PresentationDocument(object):
|
||||
|
||||
def convert_thumbnail(self, file, idx):
|
||||
"""
|
||||
Convert the slide image the application made to a standard 320x240 .png image.
|
||||
Convert the slide image the application made to a scaled 360px height .png image.
|
||||
"""
|
||||
if self.check_thumbnails():
|
||||
return
|
||||
if os.path.isfile(file):
|
||||
thumb_path = self.get_thumbnail_path(idx, False)
|
||||
create_thumb(file, thumb_path, False, QtCore.QSize(320, 240))
|
||||
create_thumb(file, thumb_path, False, QtCore.QSize(-1, 360))
|
||||
|
||||
def get_thumbnail_path(self, slide_no, check_exists):
|
||||
"""
|
||||
|
@ -221,9 +221,13 @@ class HttpRouter(RegistryProperties):
|
||||
self.request_data = None
|
||||
url_path_split = urlparse(url_path)
|
||||
url_query = parse_qs(url_path_split.query)
|
||||
# GET
|
||||
if 'data' in url_query.keys():
|
||||
self.request_data = url_query['data'][0]
|
||||
# Get data from HTTP request
|
||||
if self.command == 'GET':
|
||||
if 'data' in url_query.keys():
|
||||
self.request_data = url_query['data'][0]
|
||||
elif self.command == 'POST':
|
||||
content_len = int(self.headers['content-length'])
|
||||
self.request_data = self.rfile.read(content_len).decode("utf-8")
|
||||
for route, func in self.routes:
|
||||
match = re.match(route, url_path_split.path)
|
||||
if match:
|
||||
@ -401,10 +405,8 @@ class HttpRouter(RegistryProperties):
|
||||
log.debug('serve file request %s' % file_name)
|
||||
if not file_name:
|
||||
file_name = 'index.html'
|
||||
elif file_name == 'stage':
|
||||
file_name = 'stage.html'
|
||||
elif file_name == 'main':
|
||||
file_name = 'main.html'
|
||||
if '.' not in file_name:
|
||||
file_name += '.html'
|
||||
if file_name.startswith('/'):
|
||||
file_name = file_name[1:]
|
||||
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
||||
|
@ -167,7 +167,6 @@ class HTTPSServer(HTTPServer):
|
||||
local_data = AppLocation.get_directory(AppLocation.DataDir)
|
||||
self.socket = ssl.SSLSocket(
|
||||
sock=socket.socket(self.address_family, self.socket_type),
|
||||
ssl_version=ssl.PROTOCOL_TLSv1_2,
|
||||
certfile=os.path.join(local_data, 'remotes', 'openlp.crt'),
|
||||
keyfile=os.path.join(local_data, 'remotes', 'openlp.key'),
|
||||
server_side=True)
|
||||
|
@ -93,6 +93,7 @@ MODULES = [
|
||||
'bs4',
|
||||
'mako',
|
||||
'uno',
|
||||
'six'
|
||||
]
|
||||
|
||||
|
||||
|
@ -111,6 +111,21 @@ class TestCategoryActionList(TestCase):
|
||||
self.assertEqual(self.list.actions[0], (41, self.action2))
|
||||
self.assertEqual(self.list.actions[1], (42, self.action1))
|
||||
|
||||
def iterator_test(self):
|
||||
"""
|
||||
Test the __iter__ and __next__ methods
|
||||
"""
|
||||
# GIVEN: The list including two actions
|
||||
self.list.add(self.action1)
|
||||
self.list.add(self.action2)
|
||||
|
||||
# WHEN: Iterating over the list
|
||||
l = [a for a in self.list]
|
||||
# THEN: Make sure they are returned in correct order
|
||||
self.assertEquals(len(self.list), 2)
|
||||
self.assertIs(l[0], self.action1)
|
||||
self.assertIs(l[1], self.action2)
|
||||
|
||||
def remove_test(self):
|
||||
"""
|
||||
Test the remove() method
|
||||
|
@ -250,7 +250,7 @@ class TestLib(TestCase):
|
||||
|
||||
def create_thumb_with_size_test(self):
|
||||
"""
|
||||
Test the create_thumb() function
|
||||
Test the create_thumb() function with a given size.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
@ -270,7 +270,7 @@ class TestLib(TestCase):
|
||||
# WHEN: Create the thumb.
|
||||
icon = create_thumb(image_path, thumb_path, size=thumb_size)
|
||||
|
||||
# THEN: Check if the thumb was created.
|
||||
# THEN: Check if the thumb was created and scaled to the given size.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
@ -282,6 +282,193 @@ class TestLib(TestCase):
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_thumb_no_size_test(self):
|
||||
"""
|
||||
Test the create_thumb() function with no size specified.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
|
||||
expected_size = QtCore.QSize(63, 88)
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
|
||||
# last test.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Only continue when the thumb does not exist.
|
||||
self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
icon = create_thumb(image_path, thumb_path)
|
||||
|
||||
# THEN: Check if the thumb was created, retaining its aspect ratio.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_thumb_invalid_size_test(self):
|
||||
"""
|
||||
Test the create_thumb() function with invalid size specified.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
|
||||
thumb_size = QtCore.QSize(-1, -1)
|
||||
expected_size = QtCore.QSize(63, 88)
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
|
||||
# last test.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Only continue when the thumb does not exist.
|
||||
self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
icon = create_thumb(image_path, thumb_path, size=thumb_size)
|
||||
|
||||
# THEN: Check if the thumb was created, retaining its aspect ratio.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_thumb_width_only_test(self):
|
||||
"""
|
||||
Test the create_thumb() function with a size of only width specified.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
|
||||
thumb_size = QtCore.QSize(100, -1)
|
||||
expected_size = QtCore.QSize(100, 137)
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
|
||||
# last test.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Only continue when the thumb does not exist.
|
||||
self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
icon = create_thumb(image_path, thumb_path, size=thumb_size)
|
||||
|
||||
# THEN: Check if the thumb was created, retaining its aspect ratio.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_thumb_height_only_test(self):
|
||||
"""
|
||||
Test the create_thumb() function with a size of only height specified.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
|
||||
thumb_size = QtCore.QSize(-1, 100)
|
||||
expected_size = QtCore.QSize(72, 100)
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
|
||||
# last test.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Only continue when the thumb does not exist.
|
||||
self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
icon = create_thumb(image_path, thumb_path, size=thumb_size)
|
||||
|
||||
# THEN: Check if the thumb was created, retaining its aspect ratio.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_thumb_empty_img_test(self):
|
||||
"""
|
||||
Test the create_thumb() function with a size of only height specified.
|
||||
"""
|
||||
# GIVEN: An image to create a thumb of.
|
||||
image_path = os.path.join(TEST_PATH, 'church.jpg')
|
||||
thumb_path = os.path.join(TEST_PATH, 'church_thumb.jpg')
|
||||
thumb_size = QtCore.QSize(-1, 100)
|
||||
expected_size_1 = QtCore.QSize(88, 88)
|
||||
expected_size_2 = QtCore.QSize(100, 100)
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
|
||||
# last test.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Only continue when the thumb does not exist.
|
||||
self.assertFalse(os.path.exists(thumb_path), 'Test was not run, because the thumb already exists.')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
|
||||
mocked_size.return_value = QtCore.QSize(0, 0)
|
||||
icon = create_thumb(image_path, thumb_path, size=None)
|
||||
|
||||
# THEN: Check if the thumb was created with aspect ratio of 1.
|
||||
self.assertTrue(os.path.exists(thumb_path), 'Test was not ran, because the thumb already exists')
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size_1, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# WHEN: Create the thumb.
|
||||
with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
|
||||
mocked_size.return_value = QtCore.QSize(0, 0)
|
||||
icon = create_thumb(image_path, thumb_path, size=thumb_size)
|
||||
|
||||
# THEN: Check if the thumb was created with aspect ratio of 1.
|
||||
self.assertIsInstance(icon, QtGui.QIcon, 'The icon should be a QIcon')
|
||||
self.assertFalse(icon.isNull(), 'The icon should not be null')
|
||||
self.assertEqual(expected_size_2, QtGui.QImageReader(thumb_path).size(), 'The thumb should have the given size')
|
||||
|
||||
# Remove the thumb so that the test actually tests if the thumb will be created.
|
||||
try:
|
||||
os.remove(thumb_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def check_item_selected_true_test(self):
|
||||
"""
|
||||
Test that the check_item_selected() function returns True when there are selected indexes
|
||||
|
@ -112,7 +112,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def projector_process_lamp_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test setting lamp on/off and hours
|
||||
Test status lamp on/off and hours
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
@ -129,7 +129,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def projector_process_multiple_lamp_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test setting multiple lamp on/off and hours
|
||||
Test status multiple lamp on/off and hours
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
@ -156,7 +156,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def projector_process_power_on_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test setting power to ON
|
||||
Test status power to ON
|
||||
"""
|
||||
# GIVEN: Test object and preset
|
||||
pjlink = pjlink_test
|
||||
@ -171,7 +171,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def projector_process_power_off_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test setting power to STANDBY
|
||||
Test status power to STANDBY
|
||||
"""
|
||||
# GIVEN: Test object and preset
|
||||
pjlink = pjlink_test
|
||||
@ -182,3 +182,71 @@ class TestPJLink(TestCase):
|
||||
|
||||
# THEN: Power should be set to STANDBY
|
||||
self.assertEquals(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
def projector_process_avmt_closed_unmuted_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test avmt status shutter closed and audio muted
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
pjlink.shutter = False
|
||||
pjlink.mute = True
|
||||
|
||||
# WHEN: Called with setting shutter closed and mute off
|
||||
pjlink.process_avmt('11')
|
||||
|
||||
# THEN: Shutter should be True and mute should be False
|
||||
self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed')
|
||||
self.assertFalse(pjlink.mute, 'Audio should be off')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
def projector_process_avmt_open_muted_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test avmt status shutter open and mute on
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
pjlink.shutter = True
|
||||
pjlink.mute = False
|
||||
|
||||
# WHEN: Called with setting shutter closed and mute on
|
||||
pjlink.process_avmt('21')
|
||||
|
||||
# THEN: Shutter should be closed and mute should be True
|
||||
self.assertFalse(pjlink.shutter, 'Shutter should have been set to closed')
|
||||
self.assertTrue(pjlink.mute, 'Audio should be off')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
def projector_process_avmt_open_unmuted_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test avmt status shutter open and mute off off
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
pjlink.shutter = True
|
||||
pjlink.mute = True
|
||||
|
||||
# WHEN: Called with setting shutter to closed and mute on
|
||||
pjlink.process_avmt('30')
|
||||
|
||||
# THEN: Shutter should be closed and mute should be True
|
||||
self.assertFalse(pjlink.shutter, 'Shutter should have been set to open')
|
||||
self.assertFalse(pjlink.mute, 'Audio should be on')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
def projector_process_avmt_closed_muted_test(self, mock_projectorReceivedData):
|
||||
"""
|
||||
Test avmt status shutter closed and mute off
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
pjlink.shutter = False
|
||||
pjlink.mute = False
|
||||
|
||||
# WHEN: Called with setting shutter to closed and mute on
|
||||
pjlink.process_avmt('31')
|
||||
|
||||
# THEN: Shutter should be closed and mute should be True
|
||||
self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed')
|
||||
self.assertTrue(pjlink.mute, 'Audio should be on')
|
||||
|
@ -28,7 +28,7 @@ PREREQUISITE: add_record() and get_all() functions validated.
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.lib.projector.db import Manufacturer, Model, Projector, ProjectorDB, ProjectorSource
|
||||
from openlp.core.lib.projector.db import Manufacturer, Model, Projector, ProjectorDB, ProjectorSource, Source
|
||||
|
||||
from tests.functional import MagicMock, patch
|
||||
from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
|
||||
@ -206,3 +206,33 @@ class TestProjectorDB(TestCase):
|
||||
# THEN: __repr__ should return a proper string
|
||||
self.assertEqual(str(manufacturer), '<Manufacturer(name="OpenLP Test")>',
|
||||
'Manufacturer.__repr__() should have returned a proper representation string')
|
||||
|
||||
def model_repr_test(self):
|
||||
"""
|
||||
Test model class __repr__ text
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
model = Model()
|
||||
|
||||
# WHEN: Name is set
|
||||
model.name = 'OpenLP Test'
|
||||
|
||||
# THEN: __repr__ should return a proper string
|
||||
self.assertEqual(str(model), '<Model(name='"OpenLP Test"')>',
|
||||
'Model.__repr__() should have returned a proper representation string')
|
||||
|
||||
def source_repr_test(self):
|
||||
"""
|
||||
Test source.__repr__ text
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
source = Source()
|
||||
|
||||
# WHEN: Source() information is set
|
||||
source.pjlink_name = 'Test object'
|
||||
source.pjlink_code = '11'
|
||||
source.text = 'Input text'
|
||||
|
||||
# THEN: __repr__ should return a proper string
|
||||
self.assertEqual(str(source), '<Source(pjlink_name="Test object", pjlink_code="11", text="Input text")>',
|
||||
'Source.__repr__() should have returned a proper representation string')
|
||||
|
@ -244,14 +244,16 @@ class TestServiceItem(TestCase):
|
||||
self.assertEqual(service_item.service_item_type, ServiceItemType.Command, 'It should be a Command')
|
||||
self.assertEqual(service_item.get_frames()[0], frame, 'Frames should match')
|
||||
|
||||
@patch(u'openlp.core.lib.serviceitem.ServiceItem.image_manager')
|
||||
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
|
||||
def add_from_command_for_a_presentation_thumb_test(self, mocked_get_section_data_path):
|
||||
def add_from_command_for_a_presentation_thumb_test(self, mocked_get_section_data_path, mocked_image_manager):
|
||||
"""
|
||||
Test the Service Item - adding a presentation, and updating the thumb path
|
||||
Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager
|
||||
"""
|
||||
# GIVEN: A service item, a mocked AppLocation and presentation data
|
||||
mocked_get_section_data_path.return_value = os.path.join('mocked', 'section', 'path')
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_capability(ItemCapabilities.HasThumbnails)
|
||||
service_item.has_original_files = False
|
||||
service_item.name = 'presentations'
|
||||
presentation_name = 'test.pptx'
|
||||
@ -270,6 +272,7 @@ class TestServiceItem(TestCase):
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
self.assertEqual(service_item.service_item_type, ServiceItemType.Command, 'It should be a Command')
|
||||
self.assertEqual(service_item.get_frames()[0], frame, 'Frames should match')
|
||||
self.assertEqual(1, mocked_image_manager.add_image.call_count, 'image_manager should be used')
|
||||
|
||||
def service_item_load_optical_media_from_service_test(self):
|
||||
"""
|
||||
|
@ -26,7 +26,7 @@ from PyQt5 import QtCore, QtGui
|
||||
|
||||
from unittest import TestCase
|
||||
from openlp.core import Registry
|
||||
from openlp.core.lib import ServiceItemAction
|
||||
from openlp.core.lib import ImageSource, ServiceItemAction
|
||||
from openlp.core.ui import SlideController, LiveController, PreviewController
|
||||
from openlp.core.ui.slidecontroller import InfoLabel, WIDE_MENU, NON_TEXT_MENU
|
||||
|
||||
@ -713,6 +713,175 @@ class TestSlideController(TestCase):
|
||||
slide_controller.theme_screen, slide_controller.blank_screen
|
||||
])
|
||||
|
||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||
def update_preview_test_live(self, mocked_singleShot, mocked_image_manager):
|
||||
"""
|
||||
Test that the preview screen is updated with a screen grab for live service items
|
||||
"""
|
||||
# GIVEN: A mocked live service item, a mocked image_manager, a mocked Registry,
|
||||
# and a slide controller with many mocks.
|
||||
# Mocked Live Item
|
||||
mocked_live_item = MagicMock()
|
||||
mocked_live_item.get_rendered_frame.return_value = ''
|
||||
mocked_live_item.is_capable = MagicMock()
|
||||
mocked_live_item.is_capable.side_effect = [True, True]
|
||||
# Mock image_manager
|
||||
mocked_image_manager.get_image.return_value = QtGui.QImage()
|
||||
# Mock Registry
|
||||
Registry.create()
|
||||
mocked_main_window = MagicMock()
|
||||
Registry().register('main_window', mocked_main_window)
|
||||
# Mock SlideController
|
||||
slide_controller = SlideController(None)
|
||||
slide_controller.service_item = mocked_live_item
|
||||
slide_controller.is_live = True
|
||||
slide_controller.log_debug = MagicMock()
|
||||
slide_controller.selected_row = MagicMock()
|
||||
slide_controller.screens = MagicMock()
|
||||
slide_controller.screens.current = {'primary': ''}
|
||||
slide_controller.display = MagicMock()
|
||||
slide_controller.display.preview.return_value = QtGui.QImage()
|
||||
slide_controller.grab_maindisplay = MagicMock()
|
||||
slide_controller.slide_preview = MagicMock()
|
||||
slide_controller.slide_count = 0
|
||||
|
||||
# WHEN: update_preview is called
|
||||
slide_controller.update_preview()
|
||||
|
||||
# THEN: A screen_grab should have been called
|
||||
self.assertEqual(0, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should not be called')
|
||||
self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
|
||||
self.assertEqual(2, mocked_singleShot.call_count,
|
||||
'Timer to grab_maindisplay should have been called 2 times')
|
||||
self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager not be called')
|
||||
|
||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||
def update_preview_test_pres(self, mocked_singleShot, mocked_image_manager):
|
||||
"""
|
||||
Test that the preview screen is updated with the correct preview for presentation service items
|
||||
"""
|
||||
# GIVEN: A mocked presentation service item, a mocked image_manager, a mocked Registry,
|
||||
# and a slide controller with many mocks.
|
||||
# Mocked Presentation Item
|
||||
mocked_pres_item = MagicMock()
|
||||
mocked_pres_item.get_rendered_frame.return_value = ''
|
||||
mocked_pres_item.is_capable = MagicMock()
|
||||
mocked_pres_item.is_capable.side_effect = [True, True]
|
||||
# Mock image_manager
|
||||
mocked_image_manager.get_image.return_value = QtGui.QImage()
|
||||
# Mock Registry
|
||||
Registry.create()
|
||||
mocked_main_window = MagicMock()
|
||||
Registry().register('main_window', mocked_main_window)
|
||||
# Mock SlideController
|
||||
slide_controller = SlideController(None)
|
||||
slide_controller.service_item = mocked_pres_item
|
||||
slide_controller.is_live = False
|
||||
slide_controller.log_debug = MagicMock()
|
||||
slide_controller.selected_row = MagicMock()
|
||||
slide_controller.screens = MagicMock()
|
||||
slide_controller.screens.current = {'primary': ''}
|
||||
slide_controller.display = MagicMock()
|
||||
slide_controller.display.preview.return_value = QtGui.QImage()
|
||||
slide_controller.grab_maindisplay = MagicMock()
|
||||
slide_controller.slide_preview = MagicMock()
|
||||
slide_controller.slide_count = 0
|
||||
|
||||
# WHEN: update_preview is called
|
||||
slide_controller.update_preview()
|
||||
|
||||
# THEN: setPixmap and the image_manager should have been called
|
||||
self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
|
||||
self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
|
||||
self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
|
||||
self.assertEqual(1, mocked_image_manager.get_image.call_count, 'image_manager should be called')
|
||||
|
||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||
def update_preview_test_media(self, mocked_singleShot, mocked_image_manager):
|
||||
"""
|
||||
Test that the preview screen is updated with the correct preview for media service items
|
||||
"""
|
||||
# GIVEN: A mocked media service item, a mocked image_manager, a mocked Registry,
|
||||
# and a slide controller with many mocks.
|
||||
# Mocked Media Item
|
||||
mocked_media_item = MagicMock()
|
||||
mocked_media_item.get_rendered_frame.return_value = ''
|
||||
mocked_media_item.is_capable = MagicMock()
|
||||
mocked_media_item.is_capable.side_effect = [True, False]
|
||||
# Mock image_manager
|
||||
mocked_image_manager.get_image.return_value = QtGui.QImage()
|
||||
# Mock Registry
|
||||
Registry.create()
|
||||
mocked_main_window = MagicMock()
|
||||
Registry().register('main_window', mocked_main_window)
|
||||
# Mock SlideController
|
||||
slide_controller = SlideController(None)
|
||||
slide_controller.service_item = mocked_media_item
|
||||
slide_controller.is_live = False
|
||||
slide_controller.log_debug = MagicMock()
|
||||
slide_controller.selected_row = MagicMock()
|
||||
slide_controller.screens = MagicMock()
|
||||
slide_controller.screens.current = {'primary': ''}
|
||||
slide_controller.display = MagicMock()
|
||||
slide_controller.display.preview.return_value = QtGui.QImage()
|
||||
slide_controller.grab_maindisplay = MagicMock()
|
||||
slide_controller.slide_preview = MagicMock()
|
||||
slide_controller.slide_count = 0
|
||||
|
||||
# WHEN: update_preview is called
|
||||
slide_controller.update_preview()
|
||||
|
||||
# THEN: setPixmap should have been called
|
||||
self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
|
||||
self.assertEqual(0, slide_controller.display.preview.call_count, 'display.preview() should not be called')
|
||||
self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
|
||||
self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager should not be called')
|
||||
|
||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||
def update_preview_test_image(self, mocked_singleShot, mocked_image_manager):
|
||||
"""
|
||||
Test that the preview screen is updated with the correct preview for image service items
|
||||
"""
|
||||
# GIVEN: A mocked image service item, a mocked image_manager, a mocked Registry,
|
||||
# and a slide controller with many mocks.
|
||||
# Mocked Image Item
|
||||
mocked_img_item = MagicMock()
|
||||
mocked_img_item.get_rendered_frame.return_value = ''
|
||||
mocked_img_item.is_capable = MagicMock()
|
||||
mocked_img_item.is_capable.side_effect = [False, True]
|
||||
# Mock image_manager
|
||||
mocked_image_manager.get_image.return_value = QtGui.QImage()
|
||||
# Mock Registry
|
||||
Registry.create()
|
||||
mocked_main_window = MagicMock()
|
||||
Registry().register('main_window', mocked_main_window)
|
||||
# Mock SlideController
|
||||
slide_controller = SlideController(None)
|
||||
slide_controller.service_item = mocked_img_item
|
||||
slide_controller.is_live = False
|
||||
slide_controller.log_debug = MagicMock()
|
||||
slide_controller.selected_row = MagicMock()
|
||||
slide_controller.screens = MagicMock()
|
||||
slide_controller.screens.current = {'primary': ''}
|
||||
slide_controller.display = MagicMock()
|
||||
slide_controller.display.preview.return_value = QtGui.QImage()
|
||||
slide_controller.grab_maindisplay = MagicMock()
|
||||
slide_controller.slide_preview = MagicMock()
|
||||
slide_controller.slide_count = 0
|
||||
|
||||
# WHEN: update_preview is called
|
||||
slide_controller.update_preview()
|
||||
|
||||
# THEN: setPixmap and display.preview should have been called
|
||||
self.assertEqual(1, slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called')
|
||||
self.assertEqual(1, slide_controller.display.preview.call_count, 'display.preview() should be called')
|
||||
self.assertEqual(0, mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called')
|
||||
self.assertEqual(0, mocked_image_manager.get_image.call_count, 'image_manager should not be called')
|
||||
|
||||
|
||||
class TestInfoLabel(TestCase):
|
||||
|
||||
|
84
tests/functional/openlp_core_ui/test_themetab.py
Normal file
84
tests/functional/openlp_core_ui/test_themetab.py
Normal file
@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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 #
|
||||
###############################################################################
|
||||
"""
|
||||
Package to test the openlp.core.ui.ThemeTab package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.ui.themestab import ThemesTab
|
||||
from openlp.core.ui.settingsform import SettingsForm
|
||||
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
from tests.functional import MagicMock
|
||||
|
||||
|
||||
class TestThemeTab(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up a few things for the tests
|
||||
"""
|
||||
Registry.create()
|
||||
|
||||
def test_creation(self):
|
||||
"""
|
||||
Test that Themes Tab is created.
|
||||
"""
|
||||
# GIVEN: A new Advanced Tab
|
||||
settings_form = SettingsForm(None)
|
||||
|
||||
# WHEN: I create an advanced tab
|
||||
themes_tab = ThemesTab(settings_form)
|
||||
|
||||
# THEN:
|
||||
self.assertEqual("Themes", themes_tab.tab_title, 'The tab title should be Theme')
|
||||
|
||||
def test_save_triggers_processes_true(self):
|
||||
"""
|
||||
Test that the global theme event is triggered when the tab is visited.
|
||||
"""
|
||||
# GIVEN: A new Advanced Tab
|
||||
settings_form = SettingsForm(None)
|
||||
themes_tab = ThemesTab(settings_form)
|
||||
Registry().register('renderer', MagicMock())
|
||||
themes_tab.tab_visited = True
|
||||
# WHEN: I change search as type check box
|
||||
themes_tab.save()
|
||||
|
||||
# THEN: we should have two post save processed to run
|
||||
self.assertEqual(1, len(settings_form.processes), 'One post save processes should be created')
|
||||
|
||||
def test_save_triggers_processes_false(self):
|
||||
"""
|
||||
Test that the global theme event is not triggered when the tab is not visited.
|
||||
"""
|
||||
# GIVEN: A new Advanced Tab
|
||||
settings_form = SettingsForm(None)
|
||||
themes_tab = ThemesTab(settings_form)
|
||||
Registry().register('renderer', MagicMock())
|
||||
themes_tab.tab_visited = False
|
||||
# WHEN: I change search as type check box
|
||||
themes_tab.save()
|
||||
|
||||
# THEN: we should have two post save processed to run
|
||||
self.assertEqual(0, len(settings_form.processes), 'No post save processes should be created')
|
@ -24,9 +24,11 @@ Package to test the openlp.core.ui.lib.listpreviewwidget package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from PyQt5 import QtGui
|
||||
|
||||
from openlp.core.common import Settings
|
||||
from openlp.core.ui.lib.listpreviewwidget import ListPreviewWidget
|
||||
from openlp.core.lib import ServiceItem
|
||||
from openlp.core.lib import ImageSource, ServiceItem
|
||||
|
||||
from tests.functional import MagicMock, patch, call
|
||||
|
||||
@ -72,6 +74,53 @@ class TestListPreviewWidget(TestCase):
|
||||
self.assertIsNotNone(list_preview_widget, 'The ListPreviewWidget object should not be None')
|
||||
self.assertEquals(list_preview_widget.screen_ratio, 1, 'Should not be called')
|
||||
|
||||
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.image_manager')
|
||||
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.resizeRowsToContents')
|
||||
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.setRowHeight')
|
||||
def replace_service_item_test_thumbs(self, mocked_setRowHeight, mocked_resizeRowsToContents,
|
||||
mocked_image_manager):
|
||||
"""
|
||||
Test that thubmails for different slides are loaded properly in replace_service_item.
|
||||
"""
|
||||
# GIVEN: A setting to adjust "Max height for non-text slides in slide controller",
|
||||
# different ServiceItem(s), an ImageManager, and a ListPreviewWidget.
|
||||
|
||||
# Mock Settings().value('advanced/slide max height')
|
||||
self.mocked_Settings_obj.value.return_value = 0
|
||||
# Mock self.viewport().width()
|
||||
self.mocked_viewport_obj.width.return_value = 200
|
||||
# Mock Image service item
|
||||
mocked_img_service_item = MagicMock()
|
||||
mocked_img_service_item.is_text.return_value = False
|
||||
mocked_img_service_item.is_media.return_value = False
|
||||
mocked_img_service_item.is_command.return_value = False
|
||||
mocked_img_service_item.is_capable.return_value = False
|
||||
mocked_img_service_item.get_frames.return_value = [{'title': None, 'path': 'TEST1', 'image': 'FAIL'},
|
||||
{'title': None, 'path': 'TEST2', 'image': 'FAIL'}]
|
||||
# Mock Command service item
|
||||
mocked_cmd_service_item = MagicMock()
|
||||
mocked_cmd_service_item.is_text.return_value = False
|
||||
mocked_cmd_service_item.is_media.return_value = False
|
||||
mocked_cmd_service_item.is_command.return_value = True
|
||||
mocked_cmd_service_item.is_capable.return_value = True
|
||||
mocked_cmd_service_item.get_frames.return_value = [{'title': None, 'path': 'FAIL', 'image': 'TEST3'},
|
||||
{'title': None, 'path': 'FAIL', 'image': 'TEST4'}]
|
||||
# Mock image_manager
|
||||
mocked_image_manager.get_image.return_value = QtGui.QImage()
|
||||
|
||||
# init ListPreviewWidget and load service item
|
||||
list_preview_widget = ListPreviewWidget(None, 1)
|
||||
|
||||
# WHEN: replace_service_item is called
|
||||
list_preview_widget.replace_service_item(mocked_img_service_item, 200, 0)
|
||||
list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0)
|
||||
|
||||
# THEN: The ImageManager should be called in the appriopriate manner for each service item.
|
||||
self.assertEquals(mocked_image_manager.get_image.call_count, 4, 'Should be called once for each slide')
|
||||
calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin),
|
||||
call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)]
|
||||
mocked_image_manager.get_image.assert_has_calls(calls)
|
||||
|
||||
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.resizeRowsToContents')
|
||||
@patch(u'openlp.core.ui.lib.listpreviewwidget.ListPreviewWidget.setRowHeight')
|
||||
def replace_recalculate_layout_test_text(self, mocked_setRowHeight, mocked_resizeRowsToContents):
|
||||
@ -120,6 +169,7 @@ class TestListPreviewWidget(TestCase):
|
||||
# Mock image service item
|
||||
service_item = MagicMock()
|
||||
service_item.is_text.return_value = False
|
||||
service_item.is_capable.return_value = False
|
||||
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
|
||||
{'title': None, 'path': None, 'image': None}]
|
||||
# init ListPreviewWidget and load service item
|
||||
@ -156,6 +206,7 @@ class TestListPreviewWidget(TestCase):
|
||||
# Mock image service item
|
||||
service_item = MagicMock()
|
||||
service_item.is_text.return_value = False
|
||||
service_item.is_capable.return_value = False
|
||||
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
|
||||
{'title': None, 'path': None, 'image': None}]
|
||||
# init ListPreviewWidget and load service item
|
||||
@ -225,6 +276,7 @@ class TestListPreviewWidget(TestCase):
|
||||
# Mock image service item
|
||||
service_item = MagicMock()
|
||||
service_item.is_text.return_value = False
|
||||
service_item.is_capable.return_value = False
|
||||
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
|
||||
{'title': None, 'path': None, 'image': None}]
|
||||
# Mock self.cellWidget().children().setMaximumWidth()
|
||||
@ -261,6 +313,7 @@ class TestListPreviewWidget(TestCase):
|
||||
# Mock image service item
|
||||
service_item = MagicMock()
|
||||
service_item.is_text.return_value = False
|
||||
service_item.is_capable.return_value = False
|
||||
service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': None},
|
||||
{'title': None, 'path': None, 'image': None}]
|
||||
# Mock self.cellWidget().children().setMaximumWidth()
|
||||
|
@ -94,6 +94,7 @@ class TestRouter(TestCase, TestMixin):
|
||||
(r'^/stage/api/poll$', {'function': mocked_function, 'secure': False}),
|
||||
]
|
||||
self.router.routes = test_route
|
||||
self.router.command = 'GET'
|
||||
|
||||
# WHEN: called with a poll route
|
||||
function, args = self.router.process_http_request('/stage/api/poll', None)
|
||||
@ -121,6 +122,7 @@ class TestRouter(TestCase, TestMixin):
|
||||
self.router.send_header = MagicMock()
|
||||
self.router.end_headers = MagicMock()
|
||||
self.router.wfile = MagicMock()
|
||||
self.router.command = 'GET'
|
||||
|
||||
# WHEN: called with a poll route
|
||||
self.router.do_post_processor()
|
||||
@ -211,6 +213,29 @@ class TestRouter(TestCase, TestMixin):
|
||||
self.router.send_header.assert_called_once_with('Content-type', 'text/html')
|
||||
self.assertEqual(self.router.end_headers.call_count, 1, 'end_headers called once')
|
||||
|
||||
def serve_file_with_partial_params_test(self):
|
||||
"""
|
||||
Test the serve_file method with an existing file
|
||||
"""
|
||||
# GIVEN: mocked environment
|
||||
self.router.send_response = MagicMock()
|
||||
self.router.send_header = MagicMock()
|
||||
self.router.end_headers = MagicMock()
|
||||
self.router.wfile = MagicMock()
|
||||
self.router.html_dir = os.path.normpath('test/dir')
|
||||
self.router.template_vars = MagicMock()
|
||||
with patch('openlp.core.lib.os.path.exists') as mocked_exists, \
|
||||
patch('builtins.open', mock_open(read_data='123')):
|
||||
mocked_exists.return_value = True
|
||||
|
||||
# WHEN: call serve_file with an existing html file
|
||||
self.router.serve_file(os.path.normpath('test/dir/test'))
|
||||
|
||||
# THEN: it should return a 200 and the file
|
||||
self.router.send_response.assert_called_once_with(200)
|
||||
self.router.send_header.assert_called_once_with('Content-type', 'text/html')
|
||||
self.assertEqual(self.router.end_headers.call_count, 1, 'end_headers called once')
|
||||
|
||||
def serve_thumbnail_without_params_test(self):
|
||||
"""
|
||||
Test the serve_thumbnail routine without params
|
||||
|
Loading…
Reference in New Issue
Block a user