This commit is contained in:
Philip Ridout 2016-08-11 18:38:20 +01:00
commit 226432a3c3
43 changed files with 542 additions and 188 deletions

View File

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

View File

@ -141,6 +141,7 @@ class Settings(QtCore.QSettings):
'core/auto preview': False, 'core/auto preview': False,
'core/audio start paused': True, 'core/audio start paused': True,
'core/auto unblank': False, 'core/auto unblank': False,
'core/click live slide to unblank': False,
'core/blank warning': False, 'core/blank warning': False,
'core/ccli number': '', 'core/ccli number': '',
'core/has run wizard': False, 'core/has run wizard': False,

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

@ -488,6 +488,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
'You must select one or more items to preview.')) 'You must select one or more items to preview.'))
else: else:
log.debug('%s Preview requested' % self.plugin.name) log.debug('%s Preview requested' % self.plugin.name)
Registry().set_flag('has doubleclick added item to service', False)
service_item = self.build_service_item() service_item = self.build_service_item()
if service_item: if service_item:
service_item.from_plugin = True service_item.from_plugin = True

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

@ -209,6 +209,9 @@ class GeneralTab(SettingsTab):
self.auto_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box) self.auto_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
self.auto_unblank_check_box.setObjectName('auto_unblank_check_box') self.auto_unblank_check_box.setObjectName('auto_unblank_check_box')
self.settings_layout.addRow(self.auto_unblank_check_box) self.settings_layout.addRow(self.auto_unblank_check_box)
self.click_live_slide_to_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
self.click_live_slide_to_unblank_check_box.setObjectName('click_live_slide_to_unblank')
self.settings_layout.addRow(self.click_live_slide_to_unblank_check_box)
self.auto_preview_check_box = QtWidgets.QCheckBox(self.settings_group_box) self.auto_preview_check_box = QtWidgets.QCheckBox(self.settings_group_box)
self.auto_preview_check_box.setObjectName('auto_preview_check_box') self.auto_preview_check_box.setObjectName('auto_preview_check_box')
self.settings_layout.addRow(self.auto_preview_check_box) self.settings_layout.addRow(self.auto_preview_check_box)
@ -246,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)
@ -258,9 +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',
'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'))
@ -292,6 +298,7 @@ class GeneralTab(SettingsTab):
self.password_edit.setText(settings.value('songselect password')) self.password_edit.setText(settings.value('songselect password'))
self.save_check_service_check_box.setChecked(settings.value('save prompt')) self.save_check_service_check_box.setChecked(settings.value('save prompt'))
self.auto_unblank_check_box.setChecked(settings.value('auto unblank')) self.auto_unblank_check_box.setChecked(settings.value('auto unblank'))
self.click_live_slide_to_unblank_check_box.setChecked(settings.value('click live slide to unblank'))
self.display_on_monitor_check.setChecked(self.screens.display) self.display_on_monitor_check.setChecked(self.screens.display)
self.warning_check_box.setChecked(settings.value('blank warning')) self.warning_check_box.setChecked(settings.value('blank warning'))
self.auto_open_check_box.setChecked(settings.value('auto open')) self.auto_open_check_box.setChecked(settings.value('auto open'))
@ -336,6 +343,7 @@ class GeneralTab(SettingsTab):
settings.setValue('update check', self.check_for_updates_check_box.isChecked()) settings.setValue('update check', self.check_for_updates_check_box.isChecked())
settings.setValue('save prompt', self.save_check_service_check_box.isChecked()) settings.setValue('save prompt', self.save_check_service_check_box.isChecked())
settings.setValue('auto unblank', self.auto_unblank_check_box.isChecked()) settings.setValue('auto unblank', self.auto_unblank_check_box.isChecked())
settings.setValue('click live slide to unblank', self.click_live_slide_to_unblank_check_box.isChecked())
settings.setValue('auto preview', self.auto_preview_check_box.isChecked()) settings.setValue('auto preview', self.auto_preview_check_box.isChecked())
settings.setValue('loop delay', self.timeout_spin_box.value()) settings.setValue('loop delay', self.timeout_spin_box.value())
settings.setValue('ccli number', self.number_edit.displayText()) settings.setValue('ccli number', self.number_edit.displayText())

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

@ -87,6 +87,8 @@ class DisplayController(QtWidgets.QWidget):
self.is_live = False self.is_live = False
self.display = None self.display = None
self.controller_type = None self.controller_type = None
Registry().set_flag('has doubleclick added item to service', True)
Registry().set_flag('replace service manager item', False)
def send_to_plugins(self, *args): def send_to_plugins(self, *args):
""" """
@ -289,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)
@ -796,12 +798,15 @@ class SlideController(DisplayController, RegistryProperties):
def replace_service_manager_item(self, item): def replace_service_manager_item(self, item):
""" """
Replacement item following a remote edit Replacement item following a remote edit.
This action also takes place when a song that is sent to live from Service Manager is edited.
:param item: The current service item :param item: The current service item
""" """
if item == self.service_item: if item == self.service_item:
Registry().set_flag('replace service manager item', True)
self._process_item(item, self.preview_widget.current_slide_number()) self._process_item(item, self.preview_widget.current_slide_number())
Registry().set_flag('replace service manager item', False)
def add_service_manager_item(self, item, slide_no): def add_service_manager_item(self, item, slide_no):
""" """
@ -970,9 +975,10 @@ class SlideController(DisplayController, RegistryProperties):
def on_slide_unblank(self): def on_slide_unblank(self):
""" """
Handle the slidecontroller unblank event Handle the slidecontroller unblank event.
""" """
self.on_blank_display(False) if not Registry().get_flag('replace service manager item') is True:
self.on_blank_display(False)
def on_blank_display(self, checked=None): def on_blank_display(self, checked=None):
""" """
@ -1103,6 +1109,11 @@ class SlideController(DisplayController, RegistryProperties):
self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.' self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
% timeout) % timeout)
return return
# If "click live slide to unblank" is enabled, unblank the display. And start = Item is sent to Live.
# Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
if self.is_live and Settings().value('core/click live slide to unblank'):
if not start:
Registry().execute('slidecontroller_live_unblank')
row = self.preview_widget.current_slide_number() row = self.preview_widget.current_slide_number()
old_selected_row = self.selected_row old_selected_row = self.selected_row
self.selected_row = 0 self.selected_row = 0
@ -1285,6 +1296,8 @@ class SlideController(DisplayController, RegistryProperties):
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
self.play_slides_menu.setDefaultAction(self.play_slides_loop) self.play_slides_menu.setDefaultAction(self.play_slides_loop)
self.play_slides_once.setChecked(False) self.play_slides_once.setChecked(False)
if Settings().value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank')
else: else:
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png')) self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop) self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
@ -1308,6 +1321,8 @@ class SlideController(DisplayController, RegistryProperties):
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop) self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
self.play_slides_menu.setDefaultAction(self.play_slides_once) self.play_slides_menu.setDefaultAction(self.play_slides_once)
self.play_slides_loop.setChecked(False) self.play_slides_loop.setChecked(False)
if Settings().value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank')
else: else:
self.play_slides_once.setIcon(build_icon(':/media/media_time')) self.play_slides_once.setIcon(build_icon(':/media/media_time'))
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
@ -1362,7 +1377,7 @@ class SlideController(DisplayController, RegistryProperties):
Triggered when a preview slide item is doubleclicked Triggered when a preview slide item is doubleclicked
""" """
if self.service_item: if self.service_item:
if Settings().value('advanced/double click live'): if Settings().value('advanced/double click live') and Settings().value('core/auto unblank'):
# Live and Preview have issues if we have video or presentations # Live and Preview have issues if we have video or presentations
# playing in both at the same time. # playing in both at the same time.
if self.service_item.is_command(): if self.service_item.is_command():
@ -1371,8 +1386,13 @@ class SlideController(DisplayController, RegistryProperties):
if self.service_item.is_media(): if self.service_item.is_media():
self.on_media_close() self.on_media_close()
self.on_go_live() self.on_go_live()
else: # If ('advanced/double click live') is not enabled, double clicking preview adds the item to Service.
# Prevent same item in preview from being sent to Service multiple times.
# Changing the preview slide resets this flag to False.
# Do note that this still allows to add item to Service multiple times if icon is clicked.
elif not Registry().get_flag('has doubleclick added item to service') is True:
self.on_preview_add_to_service() self.on_preview_add_to_service()
Registry().set_flag('has doubleclick added item to service', True)
def on_go_live(self, field=None): def on_go_live(self, field=None):
""" """

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

@ -26,7 +26,7 @@ import os
from PyQt5 import QtCore from PyQt5 import QtCore
from openlp.core.common import Registry from openlp.core.common import Registry, Settings
from openlp.core.ui import HideMode from openlp.core.ui import HideMode
from openlp.core.lib import ServiceItemContext from openlp.core.lib import ServiceItemContext
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
@ -419,6 +419,8 @@ class MessageListener(object):
is_live = message[1] is_live = message[1]
if is_live: if is_live:
self.live_handler.next() self.live_handler.next()
if Settings().value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank')
else: else:
self.preview_handler.next() self.preview_handler.next()
@ -431,6 +433,8 @@ class MessageListener(object):
is_live = message[1] is_live = message[1]
if is_live: if is_live:
self.live_handler.previous() self.live_handler.previous()
if Settings().value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank')
else: else:
self.preview_handler.previous() self.preview_handler.previous()

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):
""" """

View File

@ -713,6 +713,52 @@ class TestSlideController(TestCase):
slide_controller.theme_screen, slide_controller.blank_screen slide_controller.theme_screen, slide_controller.blank_screen
]) ])
@patch('openlp.core.ui.slidecontroller.Settings')
def on_preview_double_click_unblank_display_test(self, MockedSettings):
# GIVEN: A slide controller, actions needed, settins set to True.
slide_controller = SlideController(None)
mocked_settings = MagicMock()
mocked_settings.return_value = True
MockedSettings.return_value = mocked_settings
slide_controller.service_item = MagicMock()
slide_controller.service_item.is_media = MagicMock()
slide_controller.on_media_close = MagicMock()
slide_controller.on_go_live = MagicMock()
slide_controller.on_preview_add_to_service = MagicMock()
slide_controller.media_reset = MagicMock()
Registry.create()
Registry().set_flag('has doubleclick added item to service', True)
# WHEN: on_preview_double_click is called
slide_controller.on_preview_double_click()
# THEN: The call to addActions should be correct
self.assertEqual(1, slide_controller.on_go_live.call_count, 'on_go_live should have been called once.')
self.assertEqual(0, slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.')
@patch('openlp.core.ui.slidecontroller.Settings')
def on_preview_double_click_add_to_service_test(self, MockedSettings):
# GIVEN: A slide controller, actions needed, settins set to False.
slide_controller = SlideController(None)
mocked_settings = MagicMock()
mocked_settings.value.return_value = False
MockedSettings.return_value = mocked_settings
slide_controller.service_item = MagicMock()
slide_controller.service_item.is_media = MagicMock()
slide_controller.on_media_close = MagicMock()
slide_controller.on_go_live = MagicMock()
slide_controller.on_preview_add_to_service = MagicMock()
slide_controller.media_reset = MagicMock()
Registry.create()
Registry().set_flag('has doubleclick added item to service', False)
# WHEN: on_preview_double_click is called
slide_controller.on_preview_double_click()
# THEN: The call to addActions should be correct
self.assertEqual(0, slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.')
self.assertEqual(1, slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.')
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager') @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
@patch(u'PyQt5.QtCore.QTimer.singleShot') @patch(u'PyQt5.QtCore.QTimer.singleShot')
def test_update_preview_live(self, mocked_singleShot, mocked_image_manager): def test_update_preview_live(self, mocked_singleShot, mocked_image_manager):