- Merged trunk and resolved conflict that was created by ui-messages-part-1 branch.

This commit is contained in:
Olli Suutari 2016-08-10 21:50:40 +03:00
commit 50131ba202
39 changed files with 457 additions and 182 deletions

View File

@ -1,5 +0,0 @@
[run]
source = openlp
[html]
directory = coverage

View File

@ -53,6 +53,7 @@ class UiStrings(object):
self.About = translate('OpenLP.Ui', 'About') self.About = translate('OpenLP.Ui', 'About')
self.Add = translate('OpenLP.Ui', '&Add') self.Add = translate('OpenLP.Ui', '&Add')
self.AddGroup = translate('OpenLP.Ui', 'Add group') self.AddGroup = translate('OpenLP.Ui', 'Add group')
self.AddGroupDot = translate('OpenLP.Ui', 'Add group.')
self.Advanced = translate('OpenLP.Ui', 'Advanced') self.Advanced = translate('OpenLP.Ui', 'Advanced')
self.AllFiles = translate('OpenLP.Ui', 'All Files') self.AllFiles = translate('OpenLP.Ui', 'All Files')
self.Automatic = translate('OpenLP.Ui', 'Automatic') self.Automatic = translate('OpenLP.Ui', 'Automatic')
@ -81,8 +82,8 @@ class UiStrings(object):
self.Export = translate('OpenLP.Ui', 'Export') self.Export = translate('OpenLP.Ui', 'Export')
self.File = translate('OpenLP.Ui', 'File') self.File = translate('OpenLP.Ui', 'File')
self.FileNotFound = translate('OpenLP.Ui', 'File Not Found') self.FileNotFound = translate('OpenLP.Ui', 'File Not Found')
# TODO: Check before converting to python3 string self.FileNotFoundMessage = translate('OpenLP.Ui',
self.FileNotFoundMessage = translate('OpenLP.Ui', 'File %s not found.\nPlease try selecting it individually.') 'File {name} not found.\nPlease try selecting it individually.')
self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit')
self.Help = translate('OpenLP.Ui', 'Help') self.Help = translate('OpenLP.Ui', 'Help')
self.Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours') self.Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours')
@ -141,8 +142,8 @@ class UiStrings(object):
self.Split = translate('OpenLP.Ui', 'Optional &Split') self.Split = translate('OpenLP.Ui', 'Optional &Split')
self.SplitToolTip = translate('OpenLP.Ui', self.SplitToolTip = translate('OpenLP.Ui',
'Split a slide into two only if it does not fit on the screen as one slide.') 'Split a slide into two only if it does not fit on the screen as one slide.')
# TODO: Check before converting to python3 string # TODO: WHERE is this used at? cannot find where it's used at in code.
self.StartTimeCode = translate('OpenLP.Ui', 'Start %s') self.StartTimeCode = translate('OpenLP.Ui', 'Start {code}')
self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop') self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop')
self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End') self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End')
self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular') self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular')

View File

@ -323,8 +323,7 @@ def create_separated_list(string_list):
return '' return ''
elif len(string_list) == 1: elif len(string_list) == 1:
return string_list[0] return string_list[0]
# TODO: # TODO: Verify mocking of translate() test before conversion
# Cannot convert these strings to python3 yet until I can figure out how to mock translate() with the new format
elif len(string_list) == 2: elif len(string_list) == 2:
return translate('OpenLP.core.lib', '%s and %s', return translate('OpenLP.core.lib', '%s and %s',
'Locale list separator: 2 items') % (string_list[0], string_list[1]) 'Locale list separator: 2 items') % (string_list[0], string_list[1])

View File

@ -51,9 +51,8 @@ class FileDialog(QtWidgets.QFileDialog):
file = parse.unquote(file) file = parse.unquote(file)
if not os.path.exists(file): if not os.path.exists(file):
log.error('File {text} not found.'.format(text=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, QtWidgets.QMessageBox.information(parent, UiStrings().FileNotFound,
UiStrings().FileNotFoundMessage % file) UiStrings().FileNotFoundMessage.format(name=file))
continue continue
file_list.append(file) file_list.append(file)
return file_list return file_list

View File

@ -436,7 +436,7 @@ class PJLink1(QTcpSocket):
return return
return self.process_command(cmd, data) return self.process_command(cmd, data)
@pyqtSlot(int) @pyqtSlot(QAbstractSocket.SocketError)
def get_error(self, err): def get_error(self, err):
""" """
Process error from SocketError signal. Process error from SocketError signal.

View File

@ -22,6 +22,7 @@
import re import re
from string import Template
from PyQt5 import QtGui, QtCore, QtWebKitWidgets from PyQt5 import QtGui, QtCore, QtWebKitWidgets
from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, RegistryMixin, Settings from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, RegistryMixin, Settings
@ -370,8 +371,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
self.web.resize(self.page_width, self.page_height) self.web.resize(self.page_width, self.page_height)
self.web_frame = self.web.page().mainFrame() self.web_frame = self.web.page().mainFrame()
# Adjust width and height to account for shadow. outline done in css. # Adjust width and height to account for shadow. outline done in css.
# TODO: Verify before converting to python3 strings html = Template("""<!DOCTYPE html><html><head><script>
html = """<!DOCTYPE html><html><head><script>
function show_text(newtext) { function show_text(newtext) {
var main = document.getElementById('main'); var main = document.getElementById('main');
main.innerHTML = newtext; main.innerHTML = newtext;
@ -380,12 +380,16 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
// returned value). // returned value).
return main.offsetHeight; return main.offsetHeight;
} }
</script><style>*{margin: 0; padding: 0; border: 0;} </script>
#main {position: absolute; top: 0px; %s %s}</style></head><body> <style>
<div id="main"></div></body></html>""" % \ *{margin: 0; padding: 0; border: 0;}
(build_lyrics_format_css(theme_data, self.page_width, self.page_height), #main {position: absolute; top: 0px; ${format_css} ${outline_css}}
build_lyrics_outline_css(theme_data)) </style></head>
self.web.setHtml(html) <body><div id="main"></div></body></html>""")
self.web.setHtml(html.substitute(format_css=build_lyrics_format_css(theme_data,
self.page_width,
self.page_height),
outline_css=build_lyrics_outline_css(theme_data)))
self.empty_height = self.web_frame.contentsSize().height() self.empty_height = self.web_frame.contentsSize().height()
def _paginate_slide(self, lines, line_end): def _paginate_slide(self, lines, line_end):

View File

@ -514,8 +514,8 @@ class ThemeXML(object):
theme_strings = [] theme_strings = []
for key in dir(self): for key in dir(self):
if key[0:1] != '_': if key[0:1] != '_':
# TODO: Verify spacing format before converting to python3 string # TODO: Due to bound methods returned, I don't know how to write a proper test
theme_strings.append('%30s: %s' % (key, getattr(self, key))) theme_strings.append('{key:>30}: {value}'.format(key=key, value=getattr(self, key)))
return '\n'.join(theme_strings) return '\n'.join(theme_strings)
def _build_xml_from_attrs(self): def _build_xml_from_attrs(self):

View File

@ -255,17 +255,17 @@ class AdvancedTab(SettingsTab):
self.tab_title_visible = UiStrings().Advanced self.tab_title_visible = UiStrings().Advanced
self.ui_group_box.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings')) self.ui_group_box.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
self.data_directory_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Data Location')) self.data_directory_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Data Location'))
self.recent_label.setText(translate('OpenLP.AdvancedTab', 'Number of recent files to display:')) self.recent_label.setText(translate('OpenLP.AdvancedTab', 'Number of recent service files to display:'))
self.media_plugin_check_box.setText(translate('OpenLP.AdvancedTab', self.media_plugin_check_box.setText(translate('OpenLP.AdvancedTab',
'Remember active media manager tab on startup')) 'Open the last used Library category on startup'))
self.double_click_live_check_box.setText(translate('OpenLP.AdvancedTab', self.double_click_live_check_box.setText(translate('OpenLP.AdvancedTab',
'Double-click to send items straight to live')) 'Double-click to send items straight to Live'))
self.single_click_preview_check_box.setText(translate('OpenLP.AdvancedTab', self.single_click_preview_check_box.setText(translate('OpenLP.AdvancedTab',
'Preview items when clicked in Media Manager')) 'Preview items when clicked in Library'))
self.single_click_service_preview_check_box.setText(translate('OpenLP.AdvancedTab', self.single_click_service_preview_check_box.setText(translate('OpenLP.AdvancedTab',
'Preview items when clicked in Service Manager')) 'Preview items when clicked in Service'))
self.expand_service_item_check_box.setText(translate('OpenLP.AdvancedTab', self.expand_service_item_check_box.setText(translate('OpenLP.AdvancedTab',
'Expand new service items on creation')) 'Expand new Service items on creation'))
self.slide_max_height_label.setText(translate('OpenLP.AdvancedTab', self.slide_max_height_label.setText(translate('OpenLP.AdvancedTab',
'Max height for non-text slides\nin slide controller:')) 'Max height for non-text slides\nin slide controller:'))
self.slide_max_height_combo_box.setItemText(0, translate('OpenLP.AdvancedTab', 'Disabled')) self.slide_max_height_combo_box.setItemText(0, translate('OpenLP.AdvancedTab', 'Disabled'))

View File

@ -43,6 +43,8 @@ class Ui_ExceptionDialog(object):
self.exception_layout.setObjectName('exception_layout') self.exception_layout.setObjectName('exception_layout')
self.message_layout = QtWidgets.QHBoxLayout() self.message_layout = QtWidgets.QHBoxLayout()
self.message_layout.setObjectName('messageLayout') self.message_layout.setObjectName('messageLayout')
# Set margin to make the box a bit wider so the traceback is easier to read. (left, top, right, bottom)
self.message_layout.setContentsMargins(0, 0, 50, 0)
self.message_layout.addSpacing(12) self.message_layout.addSpacing(12)
self.bug_label = QtWidgets.QLabel(exception_dialog) self.bug_label = QtWidgets.QLabel(exception_dialog)
self.bug_label.setPixmap(QtGui.QPixmap(':/graphics/exception.png')) self.bug_label.setPixmap(QtGui.QPixmap(':/graphics/exception.png'))
@ -88,17 +90,25 @@ class Ui_ExceptionDialog(object):
""" """
Translate the widgets on the fly. Translate the widgets on the fly.
""" """
# Note that bugs mail is not clicable, but it adds the blue color and underlining and makes the test copyable.
exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred')) exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred'))
# Explanation text, &nbsp; adds a small space before: If possible, write in English.
self.description_explanation.setText( self.description_explanation.setText(
translate('OpenLP.ExceptionDialog', 'Please enter a description of what you were doing to cause this error.' translate('OpenLP.ExceptionDialog', '<strong>Please describe what you were trying to do.</strong> '
' If possible, write in English.' '&nbsp;If possible, write in English.'))
'\n(Minimum 20 characters)')) exception_part1 = (translate('OpenLP.ExceptionDialog',
'<strong>Oops, OpenLP hit a problem and couldn\'t recover!</strong> <br><br>'
'<strong>You can help </strong> the OpenLP developers to <strong>fix this</strong>'
' by<br> sending them a <strong>bug report</strong> to {email}{newlines}'
).format(email='<a href = "mailto:bugs@openlp.org" > bugs@openlp.org</a>',
newlines='<br><br>'))
self.message_label.setText( self.message_label.setText(
translate('OpenLP.ExceptionDialog', 'Oops! OpenLP hit a problem, and couldn\'t recover. The text in the ' translate('OpenLP.ExceptionDialog', '{first_part}'
'box below contains information that might be helpful to the OpenLP ' '<strong>No email app? </strong> You can <strong>save</strong> this '
'developers, so please e-mail it to bugs@openlp.org, along with a ' 'information to a <strong>file</strong> and<br>'
'detailed description of what you were doing when the problem ' 'send it from your <strong>mail on browser</strong> via an <strong>attachement.</strong><br><br>'
'occurred. Also attach any files that triggered the problem.')) '<strong>Thank you<strong> for being part of making OpenLP better!<br>'
).format(first_part=exception_part1))
self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail')) self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail'))
self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File')) self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File'))
self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File')) self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File'))

View File

@ -90,13 +90,12 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self) self.setupUi(self)
self.settings_section = 'crashreport' 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' \ self.report_text = '**OpenLP Bug Report**\n' \
'Version: %s\n\n' \ 'Version: {version}\n\n' \
'--- Details of the Exception. ---\n\n%s\n\n ' \ '--- Details of the Exception. ---\n\n{description}\n\n ' \
'--- Exception Traceback ---\n%s\n' \ '--- Exception Traceback ---\n{traceback}\n' \
'--- System information ---\n%s\n' \ '--- System information ---\n{system}\n' \
'--- Library Versions ---\n%s\n' '--- Library Versions ---\n{libs}\n'
def exec(self): def exec(self):
""" """
@ -132,7 +131,9 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
system += 'Desktop: GNOME\n' system += 'Desktop: GNOME\n'
elif os.environ.get('DESKTOP_SESSION') == 'xfce': elif os.environ.get('DESKTOP_SESSION') == 'xfce':
system += 'Desktop: Xfce\n' system += 'Desktop: Xfce\n'
return openlp_version, description, traceback, system, libraries # NOTE: Keys match the expected input for self.report_text.format()
return {'version': openlp_version, 'description': description, 'traceback': traceback,
'system': system, 'libs': libraries}
def on_save_report_button_clicked(self): def on_save_report_button_clicked(self):
""" """
@ -146,7 +147,9 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
if filename: if filename:
filename = str(filename).replace('/', os.path.sep) filename = str(filename).replace('/', os.path.sep)
Settings().setValue(self.settings_section + '/last directory', os.path.dirname(filename)) Settings().setValue(self.settings_section + '/last directory', os.path.dirname(filename))
report_text = self.report_text % self._create_report() opts = self._create_report()
report_text = self.report_text.format(version=opts['version'], description=opts['description'],
traceback=opts['traceback'], libs=opts['libs'], system=opts['system'])
try: try:
report_file = open(filename, 'w') report_file = open(filename, 'w')
try: try:
@ -169,7 +172,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
content = self._create_report() content = self._create_report()
source = '' source = ''
exception = '' exception = ''
for line in content[2].split('\n'): for line in content['traceback'].split('\n'):
if re.search(r'[/\\]openlp[/\\]', line): if re.search(r'[/\\]openlp[/\\]', line):
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line) source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
if ':' in line: if ':' in line:
@ -177,8 +180,11 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
subject = 'Bug report: {error} in {source}'.format(error=exception, source=source) subject = 'Bug report: {error} in {source}'.format(error=exception, source=source)
mail_urlquery = QtCore.QUrlQuery() mail_urlquery = QtCore.QUrlQuery()
mail_urlquery.addQueryItem('subject', subject) mail_urlquery.addQueryItem('subject', subject)
# TODO: Find out how to format() text that is in a variable mail_urlquery.addQueryItem('body', self.report_text.format(version=content['version'],
mail_urlquery.addQueryItem('body', self.report_text % content) description=content['description'],
traceback=content['traceback'],
system=content['system'],
libs=content['libs']))
if self.file_attachment: if self.file_attachment:
mail_urlquery.addQueryItem('attach', self.file_attachment) mail_urlquery.addQueryItem('attach', self.file_attachment)
mail_to_url = QtCore.QUrl('mailto:bugs@openlp.org') mail_to_url = QtCore.QUrl('mailto:bugs@openlp.org')
@ -196,7 +202,8 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
else: else:
self.__button_state(False) self.__button_state(False)
self.description_word_count.setText( self.description_word_count.setText(
translate('OpenLP.ExceptionDialog', 'Description characters to enter : {count}').format(count=count)) translate('OpenLP.ExceptionDialog', '{count} characters remaining from the minimum description.'
).format(count=count))
def on_attach_file_button_clicked(self): def on_attach_file_button_clicked(self):
""" """
@ -208,7 +215,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
Settings().value(self.settings_section + Settings().value(self.settings_section +
'/last directory'), '/last directory'),
'{text} (*)'.format(text=UiStrings().AllFiles)) '{text} (*)'.format(text=UiStrings().AllFiles))
log.info('New files(s) %s', str(files)) log.info('New files(s) {files}'.format(files=str(files)))
if files: if files:
self.file_attachment = str(files) self.file_attachment = str(files)

View File

@ -207,8 +207,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
trace_error_handler(log) trace_error_handler(log)
self.update_screen_list_combo() self.update_screen_list_combo()
self.application.process_events() self.application.process_events()
# TODO: Figure out how to use a variable with format() # TODO: Tested at home
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...') self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading {name}...')
if self.has_run_wizard: if self.has_run_wizard:
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active()) self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active()) self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active())
@ -632,7 +632,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
item = self.songs_list_widget.item(i) item = self.songs_list_widget.item(i)
if item.checkState() == QtCore.Qt.Checked: if item.checkState() == QtCore.Qt.Checked:
filename, sha256 = item.data(QtCore.Qt.UserRole) filename, sha256 = item.data(QtCore.Qt.UserRole)
self._increment_progress_bar(self.downloading % filename, 0) # TODO: Tested at home
self._increment_progress_bar(self.downloading.format(name=filename), 0)
self.previous_size = 0 self.previous_size = 0
destination = os.path.join(songs_destination, str(filename)) destination = os.path.join(songs_destination, str(filename))
if not self.url_get_file('{path}{name}'.format(path=self.songs_url, name=filename), if not self.url_get_file('{path}{name}'.format(path=self.songs_url, name=filename),
@ -644,7 +645,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
item = bibles_iterator.value() item = bibles_iterator.value()
if item.parent() and item.checkState(0) == QtCore.Qt.Checked: if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
bible, sha256 = item.data(0, QtCore.Qt.UserRole) bible, sha256 = item.data(0, QtCore.Qt.UserRole)
self._increment_progress_bar(self.downloading % bible, 0) # TODO: Tested at home
self._increment_progress_bar(self.downloading.format(name=bible), 0)
self.previous_size = 0 self.previous_size = 0
if not self.url_get_file('{path}{name}'.format(path=self.bibles_url, name=bible), if not self.url_get_file('{path}{name}'.format(path=self.bibles_url, name=bible),
os.path.join(bibles_destination, bible), os.path.join(bibles_destination, bible),
@ -656,8 +658,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
item = self.themes_list_widget.item(i) item = self.themes_list_widget.item(i)
if item.checkState() == QtCore.Qt.Checked: if item.checkState() == QtCore.Qt.Checked:
theme, sha256 = item.data(QtCore.Qt.UserRole) theme, sha256 = item.data(QtCore.Qt.UserRole)
# TODO: Verify how to use format() with strings in a variable # TODO: Tested at home
self._increment_progress_bar(self.downloading % theme, 0) self._increment_progress_bar(self.downloading.format(name=theme), 0)
self.previous_size = 0 self.previous_size = 0
if not self.url_get_file('{path}{name}'.format(path=self.themes_url, name=theme), if not self.url_get_file('{path}{name}'.format(path=self.themes_url, name=theme),
os.path.join(themes_destination, theme), os.path.join(themes_destination, theme),

View File

@ -249,7 +249,7 @@ class GeneralTab(SettingsTab):
self.display_on_monitor_check.setText(translate('OpenLP.GeneralTab', 'Display if a single screen')) self.display_on_monitor_check.setText(translate('OpenLP.GeneralTab', 'Display if a single screen'))
self.startup_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Startup')) self.startup_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Startup'))
self.warning_check_box.setText(translate('OpenLP.GeneralTab', 'Show blank screen warning')) self.warning_check_box.setText(translate('OpenLP.GeneralTab', 'Show blank screen warning'))
self.auto_open_check_box.setText(translate('OpenLP.GeneralTab', 'Automatically open the last service')) self.auto_open_check_box.setText(translate('OpenLP.GeneralTab', 'Automatically open the previous service file'))
self.show_splash_check_box.setText(translate('OpenLP.GeneralTab', 'Show the splash screen')) self.show_splash_check_box.setText(translate('OpenLP.GeneralTab', 'Show the splash screen'))
self.logo_group_box.setTitle(translate('OpenLP.GeneralTab', 'Logo')) self.logo_group_box.setTitle(translate('OpenLP.GeneralTab', 'Logo'))
self.logo_color_label.setText(UiStrings().BackgroundColorColon) self.logo_color_label.setText(UiStrings().BackgroundColorColon)
@ -261,11 +261,12 @@ class GeneralTab(SettingsTab):
self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings')) self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings'))
self.save_check_service_check_box.setText(translate('OpenLP.GeneralTab', self.save_check_service_check_box.setText(translate('OpenLP.GeneralTab',
'Prompt to save before starting a new service')) 'Prompt to save before starting a new service'))
self.auto_unblank_check_box.setText(translate('OpenLP.GeneralTab', 'Unblank display when adding new live item'))
self.click_live_slide_to_unblank_check_box.setText(translate('OpenLP.GeneralTab', self.click_live_slide_to_unblank_check_box.setText(translate('OpenLP.GeneralTab',
'Unblank display when changing slide in Live')) 'Unblank display when changing slide in Live'))
self.auto_unblank_check_box.setText(translate('OpenLP.GeneralTab', 'Unblank display when sending '
'items to Live'))
self.auto_preview_check_box.setText(translate('OpenLP.GeneralTab', self.auto_preview_check_box.setText(translate('OpenLP.GeneralTab',
'Automatically preview next item in service')) 'Automatically preview the next item in service'))
self.timeout_label.setText(translate('OpenLP.GeneralTab', 'Timed slide interval:')) self.timeout_label.setText(translate('OpenLP.GeneralTab', 'Timed slide interval:'))
self.timeout_spin_box.setSuffix(translate('OpenLP.GeneralTab', ' sec')) self.timeout_spin_box.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
self.ccli_group_box.setTitle(translate('OpenLP.GeneralTab', 'CCLI Details')) self.ccli_group_box.setTitle(translate('OpenLP.GeneralTab', 'CCLI Details'))

View File

@ -386,21 +386,21 @@ class Ui_MainWindow(object):
""" """
Set up the translation system Set up the translation system
""" """
main_window.setWindowTitle(UiStrings().OLPV2x) main_window.setWindowTitle(UiStrings().OLP)
self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File')) self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import')) self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import'))
self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export')) self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))
self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Services')) self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Services'))
self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View')) self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View'))
self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', 'M&ode')) self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', '&Layout Presets'))
self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools')) self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings')) self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language')) self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language'))
self.help_menu.setTitle(translate('OpenLP.MainWindow', '&Help')) self.help_menu.setTitle(translate('OpenLP.MainWindow', '&Help'))
self.media_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Library')) self.media_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Library'))
self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager')) self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service'))
self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager')) self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Themes'))
self.projector_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Projector Manager')) self.projector_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Projectors'))
self.file_new_item.setText(translate('OpenLP.MainWindow', '&New Service')) self.file_new_item.setText(translate('OpenLP.MainWindow', '&New Service'))
self.file_new_item.setToolTip(UiStrings().NewService) self.file_new_item.setToolTip(UiStrings().NewService)
self.file_new_item.setStatusTip(UiStrings().CreateService) self.file_new_item.setStatusTip(UiStrings().CreateService)
@ -417,7 +417,7 @@ class Ui_MainWindow(object):
self.print_service_order_item.setText(UiStrings().PrintService) self.print_service_order_item.setText(UiStrings().PrintService)
self.print_service_order_item.setStatusTip(translate('OpenLP.MainWindow', 'Print the current service.')) self.print_service_order_item.setStatusTip(translate('OpenLP.MainWindow', 'Print the current service.'))
self.file_exit_item.setText(translate('OpenLP.MainWindow', 'E&xit')) self.file_exit_item.setText(translate('OpenLP.MainWindow', 'E&xit'))
self.file_exit_item.setStatusTip(translate('OpenLP.MainWindow', 'Quit OpenLP')) self.file_exit_item.setStatusTip(translate('OpenLP.MainWindow', 'Close OpenLP - Shut down the program.'))
self.import_theme_item.setText(translate('OpenLP.MainWindow', '&Theme')) self.import_theme_item.setText(translate('OpenLP.MainWindow', '&Theme'))
self.import_language_item.setText(translate('OpenLP.MainWindow', '&Language')) self.import_language_item.setText(translate('OpenLP.MainWindow', '&Language'))
self.export_theme_item.setText(translate('OpenLP.MainWindow', '&Theme')) self.export_theme_item.setText(translate('OpenLP.MainWindow', '&Theme'))
@ -426,41 +426,42 @@ class Ui_MainWindow(object):
self.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...')) self.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...'))
self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...')) self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...'))
self.settings_export_item.setStatusTip( self.settings_export_item.setStatusTip(
translate('OpenLP.MainWindow', 'Export OpenLP settings to a specified *.config file')) translate('OpenLP.MainWindow', 'Export settings to a *.config file.'))
self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings')) self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.settings_import_item.setStatusTip( self.settings_import_item.setStatusTip(
translate('OpenLP.MainWindow', 'Import OpenLP settings from a specified *.config file previously ' translate('OpenLP.MainWindow', 'Import OpenLP settings from a *.config file previously exported from '
'exported on this or another machine')) 'this or an another machine.'))
self.settings_import_item.setText(translate('OpenLP.MainWindow', 'Settings')) self.settings_import_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.view_projector_manager_item.setText(translate('OPenLP.MainWindow', '&Projector Manager')) self.view_projector_manager_item.setText(translate('OPenLP.MainWindow', '&Projectors'))
self.view_projector_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Projector Manager')) self.view_projector_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Hide or show Projectors.'))
self.view_projector_manager_item.setStatusTip(translate('OpenLP.MainWindow', self.view_projector_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the Projector Manager')) 'Toggle the visibility of the Projectors.'))
self.view_media_manager_item.setText(translate('OpenLP.MainWindow', '&Media Manager')) self.view_media_manager_item.setText(translate('OpenLP.MainWindow', 'L&ibrary'))
self.view_media_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Media Manager')) self.view_media_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Hide or show the Library.'))
self.view_media_manager_item.setStatusTip(translate('OpenLP.MainWindow', self.view_media_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the media manager.')) 'Toggle the visibility of the Library.'))
self.view_theme_manager_item.setText(translate('OpenLP.MainWindow', '&Theme Manager')) self.view_theme_manager_item.setText(translate('OpenLP.MainWindow', '&Themes'))
self.view_theme_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Theme Manager')) self.view_theme_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Hide or show themes'))
self.view_theme_manager_item.setStatusTip(translate('OpenLP.MainWindow', self.view_theme_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the theme manager.')) 'Toggle the visibility of the Themes.'))
self.view_service_manager_item.setText(translate('OpenLP.MainWindow', '&Service Manager')) self.view_service_manager_item.setText(translate('OpenLP.MainWindow', '&Service'))
self.view_service_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Service Manager')) self.view_service_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Hide or show Service.'))
self.view_service_manager_item.setStatusTip(translate('OpenLP.MainWindow', self.view_service_manager_item.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the service manager.')) 'Toggle the visibility of the Service.'))
self.view_preview_panel.setText(translate('OpenLP.MainWindow', '&Preview Panel')) self.view_preview_panel.setText(translate('OpenLP.MainWindow', '&Preview'))
self.view_preview_panel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Preview Panel')) self.view_preview_panel.setToolTip(translate('OpenLP.MainWindow', 'Hide or show Preview.'))
self.view_preview_panel.setStatusTip( self.view_preview_panel.setStatusTip(
translate('OpenLP.MainWindow', 'Toggle the visibility of the preview panel.')) translate('OpenLP.MainWindow', 'Toggle the visibility of the Preview.'))
self.view_live_panel.setText(translate('OpenLP.MainWindow', '&Live Panel')) self.view_live_panel.setText(translate('OpenLP.MainWindow', 'Li&ve'))
self.view_live_panel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Live Panel')) self.view_live_panel.setToolTip(translate('OpenLP.MainWindow', 'Hide or show Live'))
self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels')) self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock visibility of the panels'))
self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.')) self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Lock visibility of the panels.'))
self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the Live.'))
self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Manage Plugins')) self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Manage Plugins'))
self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins')) self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'You can activate or disable plugins'
'from here.'))
self.about_item.setText(translate('OpenLP.MainWindow', '&About')) self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP')) self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP.'))
if is_win() or is_macosx(): if is_win() or is_macosx():
self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide')) self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide'))
self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help')) self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help'))
@ -487,11 +488,13 @@ class Ui_MainWindow(object):
self.update_theme_images.setStatusTip(translate('OpenLP.MainWindow', self.update_theme_images.setStatusTip(translate('OpenLP.MainWindow',
'Update the preview images for all themes.')) 'Update the preview images for all themes.'))
self.mode_default_item.setText(translate('OpenLP.MainWindow', '&Default')) self.mode_default_item.setText(translate('OpenLP.MainWindow', '&Default'))
self.mode_default_item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode back to the default.')) self.mode_default_item.setStatusTip(translate('OpenLP.MainWindow', 'Reset the interface layout back to the '
'default settings.'))
self.mode_setup_item.setText(translate('OpenLP.MainWindow', '&Setup')) self.mode_setup_item.setText(translate('OpenLP.MainWindow', '&Setup'))
self.mode_setup_item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode to Setup.')) self.mode_setup_item.setStatusTip(translate('OpenLP.MainWindow', 'Use layout that focuses on setting'
' up the Service.'))
self.mode_live_item.setText(translate('OpenLP.MainWindow', '&Live')) self.mode_live_item.setText(translate('OpenLP.MainWindow', '&Live'))
self.mode_live_item.setStatusTip(translate('OpenLP.MainWindow', 'Set the view mode to Live.')) self.mode_live_item.setStatusTip(translate('OpenLP.MainWindow', 'Use layout that focuses on Live.'))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties): class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
@ -859,9 +862,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
return return
import_file_name, filter_used = QtWidgets.QFileDialog.getOpenFileName( import_file_name, filter_used = QtWidgets.QFileDialog.getOpenFileName(
self, self,
translate('OpenLP.MainWindow', 'Open File'), translate('OpenLP.MainWindow', 'Import settings'),
'', '',
translate('OpenLP.MainWindow', 'OpenLP Export Settings Files (*.conf)')) translate('OpenLP.MainWindow', 'OpenLP Settings (*.conf)'))
if not import_file_name: if not import_file_name:
return return
setting_sections = [] setting_sections = []
@ -951,7 +954,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
self, self,
translate('OpenLP.MainWindow', 'Export Settings File'), translate('OpenLP.MainWindow', 'Export Settings File'),
'', '',
translate('OpenLP.MainWindow', 'OpenLP Export Settings File (*.conf)')) translate('OpenLP.MainWindow', 'Exported OpenLP Settings (*.conf)'))
if not export_file_name: if not export_file_name:
return return
# Make sure it's a .conf file. # Make sure it's a .conf file.
@ -1168,9 +1171,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
:param file_name: The file name of the service file. :param file_name: The file name of the service file.
""" """
if modified: if modified:
title = '{title} - {name}*'.format(title=UiStrings().OLPV2x, name=file_name) title = '{title} - {name}*'.format(title=UiStrings().OLP, name=file_name)
else: else:
title = '{title} - {name}'.format(title=UiStrings().OLPV2x, name=file_name) title = '{title} - {name}'.format(title=UiStrings().OLP, name=file_name)
self.setWindowTitle(title) self.setWindowTitle(title)
def show_status_message(self, message): def show_status_message(self, message):
@ -1333,7 +1336,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
self.recent_files_menu.clear() self.recent_files_menu.clear()
for file_id, filename in enumerate(recent_files_to_display): for file_id, filename in enumerate(recent_files_to_display):
log.debug('Recent file name: {name}'.format(name=filename)) log.debug('Recent file name: {name}'.format(name=filename))
# TODO: Verify ''.format() before committing # TODO: Should be good
action = create_action(self, '', action = create_action(self, '',
text='&{n} {name}'.format(n=file_id + 1, text='&{n} {name}'.format(n=file_id + 1,
name=os.path.splitext(os.path.basename(str(filename)))[0]), name=os.path.splitext(os.path.basename(str(filename)))[0]),

View File

@ -126,7 +126,7 @@ class PlayerTab(SettingsTab):
self.media_player_group_box.setTitle(translate('OpenLP.PlayerTab', 'Available Media Players')) self.media_player_group_box.setTitle(translate('OpenLP.PlayerTab', 'Available Media Players'))
self.player_order_group_box.setTitle(translate('OpenLP.PlayerTab', 'Player Search Order')) self.player_order_group_box.setTitle(translate('OpenLP.PlayerTab', 'Player Search Order'))
self.background_color_group_box.setTitle(UiStrings().BackgroundColor) self.background_color_group_box.setTitle(UiStrings().BackgroundColor)
self.background_color_label.setText(UiStrings().DefaultColor) self.background_color_label.setText(UiStrings().BackgroundColorColon)
self.information_label.setText(translate('OpenLP.PlayerTab', self.information_label.setText(translate('OpenLP.PlayerTab',
'Visible background for videos with aspect ratio different to screen.')) 'Visible background for videos with aspect ratio different to screen.'))
self.retranslate_players() self.retranslate_players()

View File

@ -60,7 +60,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
self._clear_details() self._clear_details()
self.programatic_change = True self.programatic_change = True
plugin_list_width = 0 plugin_list_width = 0
# TODO: See how to use format() with variables # TODO: Tested at home
for plugin in self.plugin_manager.plugins: for plugin in self.plugin_manager.plugins:
item = QtWidgets.QListWidgetItem(self.plugin_list_widget) item = QtWidgets.QListWidgetItem(self.plugin_list_widget)
# We do this just to make 100% sure the status is an integer as # We do this just to make 100% sure the status is an integer as
@ -68,19 +68,19 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
plugin.status = int(plugin.status) plugin.status = int(plugin.status)
# Set the little status text in brackets next to the plugin name. # Set the little status text in brackets next to the plugin name.
if plugin.status == PluginStatus.Disabled: if plugin.status == PluginStatus.Disabled:
status_text = translate('OpenLP.PluginForm', '%s (Disabled)') status_text = translate('OpenLP.PluginForm', '{name} (Disabled)')
elif plugin.status == PluginStatus.Active: elif plugin.status == PluginStatus.Active:
status_text = translate('OpenLP.PluginForm', '%s (Active)') status_text = translate('OpenLP.PluginForm', '{name} (Active)')
else: else:
# PluginStatus.Inactive # PluginStatus.Inactive
status_text = translate('OpenLP.PluginForm', '%s (Inactive)') status_text = translate('OpenLP.PluginForm', '{name} (Inactive)')
item.setText(status_text % plugin.name_strings['singular']) item.setText(status_text.format(name=plugin.name_strings['singular']))
# If the plugin has an icon, set it! # If the plugin has an icon, set it!
if plugin.icon: if plugin.icon:
item.setIcon(plugin.icon) item.setIcon(plugin.icon)
self.plugin_list_widget.addItem(item) self.plugin_list_widget.addItem(item)
plugin_list_width = max(plugin_list_width, self.fontMetrics().width( plugin_list_width = max(plugin_list_width, self.fontMetrics().width(
translate('OpenLP.PluginForm', '%s (Inactive)') % plugin.name_strings['singular'])) translate('OpenLP.PluginForm', '{name} (Inactive)').format(name=plugin.name_strings['singular'])))
self.plugin_list_widget.setFixedWidth(plugin_list_width + self.plugin_list_widget.iconSize().width() + 48) self.plugin_list_widget.setFixedWidth(plugin_list_width + self.plugin_list_widget.iconSize().width() + 48)
def _clear_details(self): def _clear_details(self):
@ -137,13 +137,13 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
self.active_plugin.app_startup() self.active_plugin.app_startup()
else: else:
self.active_plugin.toggle_status(PluginStatus.Inactive) self.active_plugin.toggle_status(PluginStatus.Inactive)
# TODO: Verify using format() with a variable # TODO: Tested at home
status_text = translate('OpenLP.PluginForm', '%s (Inactive)') status_text = translate('OpenLP.PluginForm', '{name} (Inactive)')
if self.active_plugin.status == PluginStatus.Active: if self.active_plugin.status == PluginStatus.Active:
status_text = translate('OpenLP.PluginForm', '%s (Active)') status_text = translate('OpenLP.PluginForm', '{name} (Active)')
elif self.active_plugin.status == PluginStatus.Inactive: elif self.active_plugin.status == PluginStatus.Inactive:
status_text = translate('OpenLP.PluginForm', '%s (Inactive)') status_text = translate('OpenLP.PluginForm', '{name} (Inactive)')
elif self.active_plugin.status == PluginStatus.Disabled: elif self.active_plugin.status == PluginStatus.Disabled:
status_text = translate('OpenLP.PluginForm', '%s (Disabled)') status_text = translate('OpenLP.PluginForm', '{name} (Disabled)')
self.plugin_list_widget.currentItem().setText( self.plugin_list_widget.currentItem().setText(
status_text % self.active_plugin.name_strings['singular']) status_text.format(name=self.active_plugin.name_strings['singular']))

View File

@ -30,8 +30,8 @@ log.debug('editform loaded')
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSlot, QSize from PyQt5.QtCore import pyqtSlot, QSize
from PyQt5.QtWidgets import QDialog, QButtonGroup, QDialogButtonBox, QFormLayout, QLineEdit, QRadioButton, \ from PyQt5.QtWidgets import QAbstractButton, QDialog, QButtonGroup, QDialogButtonBox, QFormLayout, QLineEdit, \
QStyle, QStylePainter, QStyleOptionTab, QTabBar, QTabWidget, QVBoxLayout, QWidget QRadioButton, QStyle, QStylePainter, QStyleOptionTab, QTabBar, QTabWidget, QVBoxLayout, QWidget
from openlp.core.common import translate, is_macosx from openlp.core.common import translate, is_macosx
from openlp.core.lib import build_icon from openlp.core.lib import build_icon
@ -452,7 +452,7 @@ class SourceSelectSingle(QDialog):
selected = super(SourceSelectSingle, self).exec() selected = super(SourceSelectSingle, self).exec()
return selected return selected
@pyqtSlot(object) @pyqtSlot(QAbstractButton)
def button_clicked(self, button): def button_clicked(self, button):
""" """
Checks which button was clicked Checks which button was clicked

View File

@ -291,7 +291,7 @@ class SlideController(DisplayController, RegistryProperties):
self.delay_spin_box = QtWidgets.QSpinBox() self.delay_spin_box = QtWidgets.QSpinBox()
self.delay_spin_box.setObjectName('delay_spin_box') self.delay_spin_box.setObjectName('delay_spin_box')
self.delay_spin_box.setRange(1, 180) self.delay_spin_box.setRange(1, 180)
self.delay_spin_box.setSuffix(UiStrings().Seconds) self.delay_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().Seconds))
self.delay_spin_box.setToolTip(translate('OpenLP.SlideController', 'Delay between slides in seconds.')) self.delay_spin_box.setToolTip(translate('OpenLP.SlideController', 'Delay between slides in seconds.'))
self.receive_spin_delay() self.receive_spin_delay()
self.toolbar.add_toolbar_widget(self.delay_spin_box) self.toolbar.add_toolbar_widget(self.delay_spin_box)

View File

@ -464,9 +464,9 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
""" """
Background video button pushed. Background video button pushed.
""" """
# TODO: Check this before converting # TODO: Should work
visible_formats = '(%s)' % '; '.join(VIDEO_EXT) visible_formats = '({name})'.format(name='; '.join(VIDEO_EXT))
actual_formats = '(%s)' % ' '.join(VIDEO_EXT) actual_formats = '({name})'.format(name=' '.join(VIDEO_EXT))
video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'), video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
visible=visible_formats, actual=actual_formats) visible=visible_formats, actual=actual_formats)
video_filter = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles) video_filter = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles)

View File

@ -769,7 +769,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
'{count} time(s) by {plugin}' '{count} time(s) by {plugin}'
).format(name=used_count, ).format(name=used_count,
plugin=plugin.name))) plugin=plugin.name)))
plugin_usage = "%s\n" % plugin_usage plugin_usage = "{text}\n".format(text=plugin_usage)
if plugin_usage: if plugin_usage:
critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'), critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',

View File

@ -444,15 +444,15 @@ class Ui_ThemeWizard(object):
self.main_font_label.setText(translate('OpenLP.ThemeWizard', 'Font:')) self.main_font_label.setText(translate('OpenLP.ThemeWizard', 'Font:'))
self.main_color_label.setText(translate('OpenLP.ThemeWizard', 'color:')) self.main_color_label.setText(translate('OpenLP.ThemeWizard', 'color:'))
self.main_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.main_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.main_size_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.main_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.line_spacing_label.setText(translate('OpenLP.ThemeWizard', 'Line Spacing:')) self.line_spacing_label.setText(translate('OpenLP.ThemeWizard', 'Line Spacing:'))
self.line_spacing_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.line_spacing_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.outline_check_box.setText(translate('OpenLP.ThemeWizard', '&Outline:')) self.outline_check_box.setText(translate('OpenLP.ThemeWizard', '&Outline:'))
self.outline_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.outline_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.outline_size_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.outline_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.shadow_check_box.setText(translate('OpenLP.ThemeWizard', '&Shadow:')) self.shadow_check_box.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
self.shadow_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.shadow_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.shadow_size_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.shadow_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.main_bold_check_box.setText(translate('OpenLP.ThemeWizard', 'Bold')) self.main_bold_check_box.setText(translate('OpenLP.ThemeWizard', 'Bold'))
self.main_italics_check_box.setText(translate('OpenLP.ThemeWizard', 'Italic')) self.main_italics_check_box.setText(translate('OpenLP.ThemeWizard', 'Italic'))
self.footer_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Footer Area Font Details')) self.footer_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Footer Area Font Details'))
@ -461,7 +461,7 @@ class Ui_ThemeWizard(object):
self.footer_font_label.setText(translate('OpenLP.ThemeWizard', 'Font:')) self.footer_font_label.setText(translate('OpenLP.ThemeWizard', 'Font:'))
self.footer_color_label.setText(translate('OpenLP.ThemeWizard', 'color:')) self.footer_color_label.setText(translate('OpenLP.ThemeWizard', 'color:'))
self.footer_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.footer_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.footer_size_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.footer_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.alignment_page.setTitle(translate('OpenLP.ThemeWizard', 'Text Formatting Details')) self.alignment_page.setTitle(translate('OpenLP.ThemeWizard', 'Text Formatting Details'))
self.alignment_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Allows additional display ' self.alignment_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Allows additional display '
'formatting information to be defined')) 'formatting information to be defined'))

View File

@ -99,11 +99,11 @@ class AlertsTab(SettingsTab):
self.font_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Font')) self.font_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Font'))
self.font_label.setText(translate('AlertsPlugin.AlertsTab', 'Font name:')) self.font_label.setText(translate('AlertsPlugin.AlertsTab', 'Font name:'))
self.font_color_label.setText(translate('AlertsPlugin.AlertsTab', 'Font color:')) self.font_color_label.setText(translate('AlertsPlugin.AlertsTab', 'Font color:'))
self.background_color_label.setText(translate('AlertsPlugin.AlertsTab', 'Background color:')) self.background_color_label.setText(UiStrings().BackgroundColorColon)
self.font_size_label.setText(translate('AlertsPlugin.AlertsTab', 'Font size:')) self.font_size_label.setText(translate('AlertsPlugin.AlertsTab', 'Font size:'))
self.font_size_spin_box.setSuffix(UiStrings().FontSizePtUnit) self.font_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
self.timeout_label.setText(translate('AlertsPlugin.AlertsTab', 'Alert timeout:')) self.timeout_label.setText(translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.timeout_spin_box.setSuffix(UiStrings().Seconds) self.timeout_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().Seconds))
self.preview_group_box.setTitle(UiStrings().Preview) self.preview_group_box.setTitle(UiStrings().Preview)
self.font_preview.setText(UiStrings().OLPV2x) self.font_preview.setText(UiStrings().OLPV2x)

View File

@ -191,13 +191,13 @@ class BiblesTab(SettingsTab):
self.display_style_combo_box.setItemText(DisplayStyle.Square, self.display_style_combo_box.setItemText(DisplayStyle.Square,
translate('BiblesPlugin.BiblesTab', '[ And ]')) translate('BiblesPlugin.BiblesTab', '[ And ]'))
self.change_note_label.setText(translate('BiblesPlugin.BiblesTab', self.change_note_label.setText(translate('BiblesPlugin.BiblesTab',
'Note:\nChanges do not affect verses already in the service.')) 'Note: Changes do not affect verses in the Service'))
self.bible_second_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Display second Bible verses')) self.bible_second_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
self.scripture_reference_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Custom Scripture References')) self.scripture_reference_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Custom Scripture References'))
self.verse_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Verse Separator:')) self.verse_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Verse separator:'))
self.range_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Range Separator:')) self.range_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Range separator:'))
self.list_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'List Separator:')) self.list_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'List separator:'))
self.end_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'End Mark:')) self.end_separator_check_box.setText(translate('BiblesPlugin.BiblesTab', 'End mark:'))
tip_text = translate('BiblesPlugin.BiblesTab', tip_text = translate('BiblesPlugin.BiblesTab',
'Multiple alternative verse separators may be defined.\nThey have to be separated by a ' 'Multiple alternative verse separators may be defined.\nThey have to be separated by a '
'vertical bar "|".\nPlease clear this edit line to use the default value.') 'vertical bar "|".\nPlease clear this edit line to use the default value.')

View File

@ -195,7 +195,7 @@ class BibleMediaItem(MediaManagerItem):
self.search_tab_bar.setObjectName('search_tab_bar') self.search_tab_bar.setObjectName('search_tab_bar')
self.page_layout.addWidget(self.search_tab_bar) self.page_layout.addWidget(self.search_tab_bar)
# Add the Quick Search tab. # Add the Quick Search tab.
self.add_search_tab('quick', translate('BiblesPlugin.MediaItem', 'Quick')) self.add_search_tab('quick', translate('BiblesPlugin.MediaItem', 'Search'))
self.quick_search_label = QtWidgets.QLabel(self.quickTab) self.quick_search_label = QtWidgets.QLabel(self.quickTab)
self.quick_search_label.setObjectName('quick_search_label') self.quick_search_label.setObjectName('quick_search_label')
self.quickLayout.addWidget(self.quick_search_label, 0, 0, QtCore.Qt.AlignRight) self.quickLayout.addWidget(self.quick_search_label, 0, 0, QtCore.Qt.AlignRight)
@ -204,10 +204,10 @@ class BibleMediaItem(MediaManagerItem):
self.quick_search_edit.setObjectName('quick_search_edit') self.quick_search_edit.setObjectName('quick_search_edit')
self.quick_search_label.setBuddy(self.quick_search_edit) self.quick_search_label.setBuddy(self.quick_search_edit)
self.quickLayout.addWidget(self.quick_search_edit, 0, 1, 1, 2) self.quickLayout.addWidget(self.quick_search_edit, 0, 1, 1, 2)
self.add_search_fields('quick', translate('BiblesPlugin.MediaItem', 'Quick')) self.add_search_fields('quick', translate('BiblesPlugin.MediaItem', 'Search'))
self.quickTab.setVisible(True) self.quickTab.setVisible(True)
# Add the Advanced Search tab. # Add the Advanced Search tab.
self.add_search_tab('advanced', translate('BiblesPlugin.MediaItem', 'Advanced')) self.add_search_tab('advanced', translate('BiblesPlugin.MediaItem', 'Select'))
self.advanced_book_label = QtWidgets.QLabel(self.advancedTab) self.advanced_book_label = QtWidgets.QLabel(self.advancedTab)
self.advanced_book_label.setObjectName('advanced_book_label') self.advanced_book_label.setObjectName('advanced_book_label')
self.advancedLayout.addWidget(self.advanced_book_label, 0, 0, QtCore.Qt.AlignRight) self.advancedLayout.addWidget(self.advanced_book_label, 0, 0, QtCore.Qt.AlignRight)

View File

@ -88,7 +88,7 @@ class ImagePlugin(Plugin):
self.text_strings[StringContent.VisibleName] = {'title': translate('ImagePlugin', 'Images', 'container title')} self.text_strings[StringContent.VisibleName] = {'title': translate('ImagePlugin', 'Images', 'container title')}
# Middle Header Bar # Middle Header Bar
tooltips = { tooltips = {
'load': translate('ImagePlugin', 'Load a new image.'), 'load': translate('ImagePlugin', 'Add new image(s).'),
'import': '', 'import': '',
'new': translate('ImagePlugin', 'Add a new image.'), 'new': translate('ImagePlugin', 'Add a new image.'),
'edit': translate('ImagePlugin', 'Edit the selected image.'), 'edit': translate('ImagePlugin', 'Edit the selected image.'),

View File

@ -62,7 +62,7 @@ class ImageTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.background_color_group_box.setTitle(UiStrings().BackgroundColor) self.background_color_group_box.setTitle(UiStrings().BackgroundColor)
self.background_color_label.setText(UiStrings().DefaultColor) self.background_color_label.setText(UiStrings().BackgroundColorColon)
self.information_label.setText( self.information_label.setText(
translate('ImagesPlugin.ImageTab', 'Visible background for images with aspect ratio different to screen.')) translate('ImagesPlugin.ImageTab', 'Visible background for images with aspect ratio different to screen.'))

View File

@ -75,8 +75,8 @@ class ImageMediaItem(MediaManagerItem):
self.on_new_prompt = translate('ImagePlugin.MediaItem', 'Select Image(s)') self.on_new_prompt = translate('ImagePlugin.MediaItem', 'Select Image(s)')
file_formats = get_images_filter() file_formats = get_images_filter()
self.on_new_file_masks = '{formats};;{files} (*)'.format(formats=file_formats, files=UiStrings().AllFiles) self.on_new_file_masks = '{formats};;{files} (*)'.format(formats=file_formats, files=UiStrings().AllFiles)
self.add_group_action.setText(UiStrings().AddGroup) self.add_group_action.setText(UiStrings().AddGroupDot)
self.add_group_action.setToolTip(UiStrings().AddGroup) self.add_group_action.setToolTip(UiStrings().AddGroupDot)
self.replace_action.setText(UiStrings().ReplaceBG) self.replace_action.setText(UiStrings().ReplaceBG)
self.replace_action.setToolTip(UiStrings().ReplaceLiveBG) self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
self.reset_action.setText(UiStrings().ResetBG) self.reset_action.setText(UiStrings().ResetBG)
@ -180,7 +180,7 @@ class ImageMediaItem(MediaManagerItem):
text=UiStrings().AddGroup, icon=':/images/image_new_group.png', triggers=self.on_add_group_click) text=UiStrings().AddGroup, icon=':/images/image_new_group.png', triggers=self.on_add_group_click)
create_widget_action( create_widget_action(
self.list_view, self.list_view,
text=self.plugin.get_string(StringContent.Load)['tooltip'], text=translate('ImagePlugin', 'Add new image(s)'),
icon=':/general/general_open.png', triggers=self.on_file_click) icon=':/general/general_open.png', triggers=self.on_file_click)
def add_start_header_bar(self): def add_start_header_bar(self):

View File

@ -133,7 +133,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
disable_optical_button_text = True disable_optical_button_text = True
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD') optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
optical_button_tooltip = translate('MediaPlugin.MediaItem', optical_button_tooltip = translate('MediaPlugin.MediaItem',
'Load CD/DVD - only supported when VLC is installed and enabled') 'CD/DVD Playback is only supported if VLC is installed and enabled.')
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=self.optical_icon, self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=self.optical_icon,
text=optical_button_text, text=optical_button_text,
tooltip=optical_button_tooltip, tooltip=optical_button_tooltip,

View File

@ -54,7 +54,7 @@ class MediaTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.advanced_group_box.setTitle(UiStrings().Advanced) self.advanced_group_box.setTitle(UiStrings().Advanced)
self.override_player_check_box.setText(translate('MediaPlugin.MediaTab', 'Allow media player to be overridden')) self.override_player_check_box.setText(translate('MediaPlugin.MediaTab', 'Allow media player to be overridden'))
self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start Live items automatically')) self.auto_start_check_box.setText(translate('MediaPlugin.MediaTab', 'Start new Live media automatically'))
def load(self): def load(self):
self.override_player_check_box.setChecked(Settings().value(self.settings_section + '/override player')) self.override_player_check_box.setChecked(Settings().value(self.settings_section + '/override player'))

View File

@ -523,7 +523,7 @@ class PowerpointDocument(PresentationDocument):
log.exception('Failed to exit Powerpoint presentation after error') log.exception('Failed to exit Powerpoint presentation after error')
log.exception(e) log.exception(e)
critical_error_message_box(UiStrings().Error, translate('PresentationPlugin.PowerpointDocument', critical_error_message_box(UiStrings().Error, translate('PresentationPlugin.PowerpointDocument',
'An error occurred in the Powerpoint integration ' 'An error occurred in the PowerPoint integration '
'and the presentation will be stopped. ' 'and the presentation will be stopped. '
'Restart the presentation if you wish to present it.')) 'Restart the presentation if you wish to present it.'))

View File

@ -125,11 +125,11 @@ class PresentationTab(SettingsTab):
translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden')) translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
self.ppt_slide_click_check_box.setText( self.ppt_slide_click_check_box.setText(
translate('PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab',
'Clicking on a selected slide in the slidecontroller advances to next effect.')) 'Clicking on current slide advances to the next effect'))
self.ppt_window_check_box.setText( self.ppt_window_check_box.setText(
translate('PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab',
'Let PowerPoint control the size and position of the presentation window ' 'Let PowerPoint control the size and monitor of the presentations\n'
'(workaround for Windows 8 scaling issue).')) '(This may fixes PowerPoint scaling issues in Windows 8 and 10)'))
self.pdf_program_check_box.setText( self.pdf_program_check_box.setText(
translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:')) translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:'))
@ -152,7 +152,7 @@ class PresentationTab(SettingsTab):
if controller.name == 'Powerpoint' and controller.is_available(): if controller.name == 'Powerpoint' and controller.is_available():
powerpoint_available = True powerpoint_available = True
self.override_app_check_box.setChecked(Settings().value(self.settings_section + '/override app')) self.override_app_check_box.setChecked(Settings().value(self.settings_section + '/override app'))
# Load Powerpoint settings # Load PowerPoint settings
self.ppt_slide_click_check_box.setChecked(Settings().value(self.settings_section + self.ppt_slide_click_check_box.setChecked(Settings().value(self.settings_section +
'/powerpoint slide click advance')) '/powerpoint slide click advance'))
self.ppt_slide_click_check_box.setEnabled(powerpoint_available) self.ppt_slide_click_check_box.setEnabled(powerpoint_available)

View File

@ -317,12 +317,11 @@ class HttpRouter(RegistryProperties):
Translate various strings in the mobile app. Translate various strings in the mobile app.
""" """
remote = translate('RemotePlugin.Mobile', 'Remote') remote = translate('RemotePlugin.Mobile', 'Remote')
stage = translate('RemotePlugin.Mobile', 'Stage View') stage = translate('RemotePlugin.Mobile', 'Stage')
live = translate('RemotePlugin.Mobile', 'Live View')
self.template_vars = { self.template_vars = {
'app_title': "{main} {remote}".format(main=UiStrings().OLPV2x, remote=remote), 'app_title': "{remote} | OpenLP".format(remote=remote),
'stage_title': "{main} {stage}".format(main=UiStrings().OLPV2x, stage=stage), 'stage_title': "{stage} | OpenLP".format(stage=stage),
'live_title': "{main} {live}".format(main=UiStrings().OLPV2x, live=live), 'live_title': "{live} | OpenLP".format(live=UiStrings().Live),
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'), 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'), 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
'alerts': translate('RemotePlugin.Mobile', 'Alerts'), 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),

View File

@ -643,7 +643,7 @@ class OpenLyrics(object):
# Append text from tail and add formatting end tag. # Append text from tail and add formatting end tag.
# TODO: Verify format() with template variables # TODO: Verify format() with template variables
if element.tag == NSMAP % 'tag' and use_endtag: if element.tag == NSMAP % 'tag' and use_endtag:
text += '{{{name}}}'.format(name=element.get('name')) text += '{{/{name}}}'.format(name=element.get('name'))
# Append text from tail. # Append text from tail.
if element.tail: if element.tail:
text += element.tail text += element.tail

View File

@ -68,10 +68,10 @@ class SongsTab(SettingsTab):
def retranslateUi(self): def retranslateUi(self):
self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode')) self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))
self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab', self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab',
'Display verses on live tool bar')) 'Enable "Go to verse" button in Live panel'))
self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit')) self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
self.add_from_service_check_box.setText(translate('SongsPlugin.SongsTab', self.add_from_service_check_box.setText(translate('SongsPlugin.SongsTab',
'Import missing songs from service files')) 'Import missing songs from Service files'))
self.display_songbook_check_box.setText(translate('SongsPlugin.SongsTab', 'Display songbook in footer')) self.display_songbook_check_box.setText(translate('SongsPlugin.SongsTab', 'Display songbook in footer'))
self.display_copyright_check_box.setText(translate('SongsPlugin.SongsTab', self.display_copyright_check_box.setText(translate('SongsPlugin.SongsTab',
'Display "{symbol}" symbol before copyright ' 'Display "{symbol}" symbol before copyright '

View File

@ -60,7 +60,7 @@ class TestFileDialog(TestCase):
self.mocked_os.path.exists.side_effect = lambda file_name: file_name in [ self.mocked_os.path.exists.side_effect = lambda file_name: file_name in [
'/Valid File', '/url encoded file #1'] '/Valid File', '/url encoded file #1']
self.mocked_ui_strings().FileNotFound = 'File Not Found' self.mocked_ui_strings().FileNotFound = 'File Not Found'
self.mocked_ui_strings().FileNotFoundMessage = 'File %s not found.\nPlease try selecting it individually.' self.mocked_ui_strings().FileNotFoundMessage = 'File {name} not found.\nPlease try selecting it individually.'
# WHEN: FileDialog.getOpenFileNames is called # WHEN: FileDialog.getOpenFileNames is called
result = FileDialog.getOpenFileNames(self.mocked_parent) result = FileDialog.getOpenFileNames(self.mocked_parent)

View File

@ -29,26 +29,12 @@ from openlp.core.lib.projector.pjlink1 import PJLink1
from openlp.core.lib.projector.constants import E_PARAMETER, ERROR_STRING, S_OFF, S_STANDBY, S_WARMUP, S_ON, \ from openlp.core.lib.projector.constants import E_PARAMETER, ERROR_STRING, S_OFF, S_STANDBY, S_WARMUP, S_ON, \
S_COOLDOWN, PJLINK_POWR_STATUS S_COOLDOWN, PJLINK_POWR_STATUS
from tests.functional import patch from tests.functional import patch, MagicMock
from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH
pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True) pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
class DummyTimer(object):
'''
Dummy class to fake timers
'''
def __init__(self, *args, **kwargs):
pass
def start(self, *args, **kwargs):
pass
def stop(self, *args, **kwargs):
pass
class TestPJLink(TestCase): class TestPJLink(TestCase):
""" """
Tests for the PJLink module Tests for the PJLink module
@ -308,8 +294,8 @@ class TestPJLink(TestCase):
pjlink.other_info = 'ANOTHER TEST' pjlink.other_info = 'ANOTHER TEST'
pjlink.send_queue = True pjlink.send_queue = True
pjlink.send_busy = True pjlink.send_busy = True
pjlink.timer = DummyTimer() pjlink.timer = MagicMock()
pjlink.socket_timer = DummyTimer() pjlink.socket_timer = MagicMock()
# WHEN: reset_information() is called # WHEN: reset_information() is called
with patch.object(pjlink.timer, 'stop') as mock_timer: with patch.object(pjlink.timer, 'stop') as mock_timer:

View File

@ -284,3 +284,16 @@ class TestProjectorDB(TestCase):
self.assertEqual(str(source), self.assertEqual(str(source),
'<ProjectorSource(id="1", code="11", text="First RGB source", projector_id="1")>', '<ProjectorSource(id="1", code="11", text="First RGB source", projector_id="1")>',
'ProjectorSource.__repr__)_ should have returned a proper representation string') 'ProjectorSource.__repr__)_ should have returned a proper representation string')
def test_get_projector_by_id_none(self):
"""
Test get_projector_by_id returns None if no db entry
"""
# GIVEN: Test object and data
projector = self.projector
# WHEN: DB search for entry not saved
results = projector.get_projector_by_id(dbid=123134556409824506)
# THEN: Verify return was None
self.assertEqual(results, None, 'Returned results should have equaled None')

View File

@ -29,6 +29,7 @@ from PyQt5 import QtCore
from openlp.core.common import Registry from openlp.core.common import Registry
from openlp.core.lib import Renderer, ScreenList, ServiceItem, FormattingTags from openlp.core.lib import Renderer, ScreenList, ServiceItem, FormattingTags
from openlp.core.lib.renderer import words_split, get_start_tags from openlp.core.lib.renderer import words_split, get_start_tags
from openlp.core.lib.theme import ThemeXML
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
@ -39,6 +40,24 @@ SCREEN = {
} }
# WARNING: Leave formatting alone - this is how it's returned in renderer.py
CSS_TEST_ONE = """<!DOCTYPE html><html><head><script>
function show_text(newtext) {
var main = document.getElementById('main');
main.innerHTML = newtext;
// We need to be sure that the page is loaded, that is why we
// return the element's height (even though we do not use the
// returned value).
return main.offsetHeight;
}
</script>
<style>
*{margin: 0; padding: 0; border: 0;}
#main {position: absolute; top: 0px; FORMAT CSS; OUTLINE CSS; }
</style></head>
<body><div id="main"></div></body></html>'"""
class TestRenderer(TestCase): class TestRenderer(TestCase):
def setUp(self): def setUp(self):
@ -159,3 +178,28 @@ class TestRenderer(TestCase):
# THEN: The blanks have been removed. # THEN: The blanks have been removed.
self.assertListEqual(result_words, expected_words) self.assertListEqual(result_words, expected_words)
@patch('openlp.core.lib.renderer.QtWebKitWidgets.QWebView')
@patch('openlp.core.lib.renderer.build_lyrics_format_css')
@patch('openlp.core.lib.renderer.build_lyrics_outline_css')
def test_set_text_rectangle(self, mock_outline_css, mock_lyrics_css, mock_webview):
"""
Test set_text_rectangle returns a proper html string
"""
# GIVEN: test object and data
mock_lyrics_css.return_value = ' FORMAT CSS; '
mock_outline_css.return_value = ' OUTLINE CSS; '
theme_data = ThemeXML()
theme_data.font_main_name = 'Arial'
theme_data.font_main_size = 20
theme_data.font_main_color = '#FFFFFF'
theme_data.font_main_outline_color = '#FFFFFF'
main = QtCore.QRect(10, 10, 1280, 900)
foot = QtCore.QRect(10, 1000, 1260, 24)
renderer = Renderer()
# WHEN: Calling method
renderer._set_text_rectangle(theme_data=theme_data, rect_main=main, rect_footer=foot)
# THEN: QtWebKitWidgets should be called with the proper string
mock_webview.setHtml.called_with(CSS_TEST_ONE, 'Should be the same')

View File

@ -0,0 +1,212 @@
# -*- 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.exeptionform package.
"""
import os
import socket
import tempfile
import urllib
from unittest import TestCase
from unittest.mock import mock_open
from PyQt5.QtCore import QUrlQuery
from openlp.core.common import Registry
from openlp.core.ui.firsttimeform import FirstTimeForm
from tests.functional import MagicMock, patch
from tests.helpers.testmixin import TestMixin
from openlp.core.ui import exceptionform
exceptionform.WEBKIT_VERSION = 'Webkit Test'
exceptionform.MIGRATE_VERSION = 'Migrate Test'
exceptionform.CHARDET_VERSION = 'CHARDET Test'
exceptionform.ENCHANT_VERSION = 'Enchant Test'
exceptionform.MAKO_VERSION = 'Mako Test'
exceptionform.ICU_VERSION = 'ICU Test'
exceptionform.VLC_VERSION = 'VLC Test'
MAIL_ITEM_TEXT = ('**OpenLP Bug Report**\nVersion: Trunk Test\n\n--- Details of the Exception. ---\n\n'
'Description Test\n\n --- Exception Traceback ---\nopenlp: Traceback Test\n'
'--- System information ---\nPlatform: Nose Test\n\n--- Library Versions ---\n'
'Python: Python Test\nQt5: Qt5 test\nPyQt5: PyQt5 Test\nQtWebkit: Webkit Test\n'
'SQLAlchemy: SqlAlchemy Test\nSQLAlchemy Migrate: Migrate Test\nBeautifulSoup: BeautifulSoup Test\n'
'lxml: ETree Test\nChardet: CHARDET Test\nPyEnchant: Enchant Test\nMako: Mako Test\n'
'pyICU: ICU Test\npyUNO bridge: UNO Bridge Test\nVLC: VLC Test\n\n')
@patch("openlp.core.ui.exceptionform.Qt.qVersion")
@patch("openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl")
@patch("openlp.core.ui.exceptionform.get_application_version")
@patch("openlp.core.ui.exceptionform.sqlalchemy")
@patch("openlp.core.ui.exceptionform.bs4")
@patch("openlp.core.ui.exceptionform.etree")
@patch("openlp.core.ui.exceptionform.is_linux")
@patch("openlp.core.ui.exceptionform.platform.platform")
@patch("openlp.core.ui.exceptionform.platform.python_version")
class TestExceptionForm(TestMixin, TestCase):
"""
Test functionality of exception form functions
"""
def __method_template_for_class_patches(self,
__PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__,
mocked_python_version,
mocked_platform,
mocked_is_linux,
mocked_etree,
mocked_bs4,
mocked_sqlalchemy,
mocked_application_version,
mocked_openlurl,
mocked_qversion,
):
"""
Template so you don't have to remember the layout of class mock options for methods
"""
mocked_etree.__version__ = 'ETree Test'
mocked_bs4.__version__ = 'BeautifulSoup Test'
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
mocked_python_version.return_value = 'Python Test'
mocked_platform.return_value = 'Nose Test'
mocked_qversion.return_value = 'Qt5 test'
mocked_is_linux.return_value = False
mocked_application_version.return_value = 'Trunk Test'
def setUp(self):
self.setup_application()
self.app.setApplicationVersion('0.0')
# Set up a fake "set_normal_cursor" method since we're not dealing with an actual OpenLP application object
self.app.set_normal_cursor = lambda: None
self.app.process_events = lambda: None
Registry.create()
Registry().register('application', self.app)
self.tempfile = os.path.join(tempfile.gettempdir(), 'testfile')
def tearDown(self):
if os.path.isfile(self.tempfile):
os.remove(self.tempfile)
@patch("openlp.core.ui.exceptionform.Ui_ExceptionDialog")
@patch("openlp.core.ui.exceptionform.QtWidgets.QFileDialog")
@patch("openlp.core.ui.exceptionform.QtCore.QUrl")
@patch("openlp.core.ui.exceptionform.QtCore.QUrlQuery.addQueryItem")
@patch("openlp.core.ui.exceptionform.Qt")
def test_on_send_report_button_clicked(self,
mocked_qt,
mocked_add_query_item,
mocked_qurl,
mocked_file_dialog,
mocked_ui_exception_dialog,
mocked_python_version,
mocked_platform,
mocked_is_linux,
mocked_etree,
mocked_bs4,
mocked_sqlalchemy,
mocked_application_version,
mocked_openlurl,
mocked_qversion,
):
"""
Test send report creates the proper system information text
"""
# GIVEN: Test environment
mocked_etree.__version__ = 'ETree Test'
mocked_bs4.__version__ = 'BeautifulSoup Test'
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
mocked_python_version.return_value = 'Python Test'
mocked_platform.return_value = 'Nose Test'
mocked_qversion.return_value = 'Qt5 test'
mocked_is_linux.return_value = False
mocked_application_version.return_value = 'Trunk Test'
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False
mocked_application_version.return_value = 'Trunk Test'
test_form = exceptionform.ExceptionForm()
test_form.file_attachment = None
with patch.object(test_form, '_pyuno_import') as mock_pyuno:
with patch.object(test_form.exception_text_edit, 'toPlainText') as mock_traceback:
with patch.object(test_form.description_text_edit, 'toPlainText') as mock_description:
mock_pyuno.return_value = 'UNO Bridge Test'
mock_traceback.return_value = 'openlp: Traceback Test'
mock_description.return_value = 'Description Test'
# WHEN: on_save_report_button_clicked called
test_form.on_send_report_button_clicked()
# THEN: Verify strings were formatted properly
mocked_add_query_item.assert_called_with('body', MAIL_ITEM_TEXT)
@patch("openlp.core.ui.exceptionform.QtWidgets.QFileDialog.getSaveFileName")
@patch("openlp.core.ui.exceptionform.Qt")
def test_on_save_report_button_clicked(self,
mocked_qt,
mocked_save_filename,
mocked_python_version,
mocked_platform,
mocked_is_linux,
mocked_etree,
mocked_bs4,
mocked_sqlalchemy,
mocked_application_version,
mocked_openlurl,
mocked_qversion,
):
"""
Test save report saves the correct information to a file
"""
mocked_etree.__version__ = 'ETree Test'
mocked_bs4.__version__ = 'BeautifulSoup Test'
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
mocked_python_version.return_value = 'Python Test'
mocked_platform.return_value = 'Nose Test'
mocked_qversion.return_value = 'Qt5 test'
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False
mocked_application_version.return_value = 'Trunk Test'
mocked_save_filename.return_value = ['testfile.txt', ]
test_form = exceptionform.ExceptionForm()
test_form.file_attachment = None
with patch.object(test_form, '_pyuno_import') as mock_pyuno:
with patch.object(test_form.exception_text_edit, 'toPlainText') as mock_traceback:
with patch.object(test_form.description_text_edit, 'toPlainText') as mock_description:
with patch("openlp.core.ui.exceptionform.open", mock_open(), create=True) as mocked_open:
mock_pyuno.return_value = 'UNO Bridge Test'
mock_traceback.return_value = 'openlp: Traceback Test'
mock_description.return_value = 'Description Test'
# WHEN: on_save_report_button_clicked called
test_form.on_save_report_button_clicked()
# THEN: Verify proper calls to save file
# self.maxDiff = None
check_text = "call().write({text})".format(text=MAIL_ITEM_TEXT.__repr__())
write_text = "{text}".format(text=mocked_open.mock_calls[1])
mocked_open.assert_called_with('testfile.txt', 'w')
self.assertEquals(check_text, write_text, "Saved information should match test text")

View File

@ -110,9 +110,9 @@ class TestMainWindow(TestCase, TestMixin):
# WHEN no changes are made to the service # WHEN no changes are made to the service
# THEN the main window's title shoud be the same as the OLPV2x string in the UiStrings class # THEN the main window's title shoud be the same as the OLP string in the UiStrings class
self.assertEqual(self.main_window.windowTitle(), UiStrings().OLPV2x, self.assertEqual(self.main_window.windowTitle(), UiStrings().OLP,
'The main window\'s title should be the same as the OLPV2x string in UiStrings class') 'The main window\'s title should be the same as the OLP string in UiStrings class')
def test_set_service_modifed(self): def test_set_service_modifed(self):
""" """
@ -124,8 +124,8 @@ class TestMainWindow(TestCase, TestMixin):
self.main_window.set_service_modified(True, 'test.osz') self.main_window.set_service_modified(True, 'test.osz')
# THEN the main window's title should be set to the # THEN the main window's title should be set to the
self.assertEqual(self.main_window.windowTitle(), '%s - %s*' % (UiStrings().OLPV2x, 'test.osz'), self.assertEqual(self.main_window.windowTitle(), '%s - %s*' % (UiStrings().OLP, 'test.osz'),
'The main window\'s title should be set to "<the contents of UiStrings().OLPV2x> - test.osz*"') 'The main window\'s title should be set to "<the contents of UiStrings().OLP> - test.osz*"')
def test_set_service_unmodified(self): def test_set_service_unmodified(self):
""" """
@ -137,8 +137,8 @@ class TestMainWindow(TestCase, TestMixin):
self.main_window.set_service_modified(False, 'test.osz') self.main_window.set_service_modified(False, 'test.osz')
# THEN the main window's title should be set to the # THEN the main window's title should be set to the
self.assertEqual(self.main_window.windowTitle(), '%s - %s' % (UiStrings().OLPV2x, 'test.osz'), self.assertEqual(self.main_window.windowTitle(), '%s - %s' % (UiStrings().OLP, 'test.osz'),
'The main window\'s title should be set to "<the contents of UiStrings().OLPV2x> - test.osz"') 'The main window\'s title should be set to "<the contents of UiStrings().OLP> - test.osz"')
def test_mainwindow_configuration(self): def test_mainwindow_configuration(self):
""" """