- Replaced Escape item with "Show desktop"

(Same as blank to desktop,  but does not unblank).
- Combined Offline & Online help buttons into "User Manual" button,
  which launches the appropriate help based on OS. (Offline for Win/Mac)
- Improved blank to modes shortcut descriptions.
- Setting migration for old help/escape help keys.

- Fixed bugs:
https://bugs.launchpad.net/openlp/+bug/805082
https://bugs.launchpad.net/openlp/+bug/1612187
https://bugs.launchpad.net/openlp/+bug/1616441
https...

bzr-revno: 2699
This commit is contained in:
suutari.olli@gmail.com 2016-10-18 18:04:50 +01:00 committed by Tim Bentley
commit bbf93bdf7c
13 changed files with 87 additions and 100 deletions

View File

@ -214,7 +214,10 @@ class Settings(QtCore.QSettings):
('media/players', 'media/players_temp', [(media_players_conv, None)]), # Convert phonon to system
('media/players_temp', 'media/players', []), # Move temp setting from above to correct setting
('advanced/default color', 'core/logo background color', []), # Default image renamed + moved to general > 2.4.
('advanced/default image', '/core/logo file', []) # Default image renamed + moved to general after 2.4.
('advanced/default image', 'core/logo file', []), # Default image renamed + moved to general after 2.4.
('shortcuts/escapeItem', 'shortcuts/desktopScreenEnable', []), # Escape item was removed in 2.6.
('shortcuts/offlineHelpItem', 'shortcuts/HelpItem', []), # Online and Offline help were combined in 2.6.
('shortcuts/onlineHelpItem', 'shortcuts/HelpItem', []) # Online and Offline help were combined in 2.6.
]
@staticmethod
@ -261,10 +264,10 @@ class Settings(QtCore.QSettings):
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key_D)],
'shortcuts/desktopScreenEnable': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
'shortcuts/editSong': [],
'shortcuts/escapeItem': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
'shortcuts/exportThemeItem': [],
'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.New)],
@ -273,6 +276,7 @@ class Settings(QtCore.QSettings):
'shortcuts/fileSaveItem': [QtGui.QKeySequence(QtGui.QKeySequence.Save)],
'shortcuts/fileOpenItem': [QtGui.QKeySequence(QtGui.QKeySequence.Open)],
'shortcuts/goLive': [],
'shortcuts/HelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
'shortcuts/importThemeItem': [],
'shortcuts/importBibleItem': [],
'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
@ -333,8 +337,6 @@ class Settings(QtCore.QSettings):
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
'shortcuts/newService': [],
'shortcuts/offlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
'shortcuts/onlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
'shortcuts/openService': [],
'shortcuts/saveService': [],
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),

View File

@ -107,7 +107,7 @@ class Ui_ExceptionDialog(object):
'<strong>No email app? </strong> You can <strong>save</strong> this '
'information to a <strong>file</strong> and<br>'
'send it from your <strong>mail on browser</strong> via an <strong>attachment.</strong><br><br>'
'<strong>Thank you<strong> for being part of making OpenLP better!<br>'
'<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.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File'))

View File

@ -208,7 +208,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
self.__button_state(False)
self.description_word_count.setText(
translate('OpenLP.ExceptionDialog', '<strong>Please enter a more detailed description of the situation'
))
'</strong>'))
def on_attach_file_button_clicked(self):
"""

View File

@ -309,21 +309,13 @@ class Ui_MainWindow(object):
self.about_item.setMenuRole(QtWidgets.QAction.AboutRole)
if is_win():
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offline_help_item = create_action(main_window, 'offlineHelpItem',
icon=':/system/system_help_contents.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
elif is_macosx():
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir),
'..', 'Resources', 'OpenLP.help')
self.offline_help_item = create_action(main_window, 'offlineHelpItem',
icon=':/system/system_help_contents.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
self.on_line_help_item = create_action(main_window, 'onlineHelpItem',
icon=':/system/system_online_help.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_online_help_clicked)
self.on_help_item = create_action(main_window, 'HelpItem',
icon=':/system/system_help_contents.png',
can_shortcuts=True,
category=UiStrings().Help, triggers=self.on_help_clicked)
self.web_site_item = create_action(main_window, 'webSiteItem', can_shortcuts=True, category=UiStrings().Help)
# Shortcuts not connected to buttons or menu entries.
self.search_shortcut_action = create_action(main_window,
@ -362,11 +354,7 @@ class Ui_MainWindow(object):
add_actions(self.tools_menu, (self.tools_open_data_folder, None))
add_actions(self.tools_menu, (self.tools_first_time_wizard, None))
add_actions(self.tools_menu, [self.update_theme_images])
if (is_win() or is_macosx()) and (hasattr(sys, 'frozen') and sys.frozen == 1):
add_actions(self.help_menu, (self.offline_help_item, self.on_line_help_item, None, self.web_site_item,
self.about_item))
else:
add_actions(self.help_menu, (self.on_line_help_item, None, self.web_site_item, self.about_item))
add_actions(self.help_menu, (self.on_help_item, None, self.web_site_item, self.about_item))
add_actions(self.menu_bar, (self.file_menu.menuAction(), self.view_menu.menuAction(),
self.tools_menu.menuAction(), self.settings_menu.menuAction(), self.help_menu.menuAction()))
add_actions(self, [self.search_shortcut_action])
@ -462,9 +450,7 @@ class Ui_MainWindow(object):
'from here.'))
self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP.'))
if is_win() or is_macosx():
self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide'))
self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help'))
self.on_help_item.setText(translate('OpenLP.MainWindow', '&User Manual'))
self.search_shortcut_action.setText(UiStrings().Search)
self.search_shortcut_action.setToolTip(
translate('OpenLP.MainWindow', 'Jump to the search box of the current active plugin.'))
@ -778,18 +764,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
import webbrowser
webbrowser.open_new('http://openlp.org/')
def on_offline_help_clicked(self):
def on_help_clicked(self):
"""
Load the local OpenLP help file
If is_macosx or is_win, open the local OpenLP help file.
Use the Online manual in other cases. (Linux)
"""
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + self.local_help_file))
def on_online_help_clicked(self):
"""
Load the online OpenLP manual
"""
import webbrowser
webbrowser.open_new('http://manual.openlp.org/')
if is_macosx() or is_win():
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + self.local_help_file))
else:
import webbrowser
webbrowser.open_new('http://manual.openlp.org/')
def on_about_item_clicked(self):
"""

View File

@ -426,11 +426,11 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
is_valid = False
if not is_valid:
text = translate('OpenLP.ShortcutListDialog',
'The shortcut "{key}" is already assigned to another action, please'
' use a different shortcut.'
'The shortcut "{key}" is already assigned to another action,\n'
'please use a different shortcut.'
).format(key=self.get_shortcut_string(key_sequence))
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
text, for_display=True)
text)
self.dialog_was_shown = True
return is_valid

View File

@ -234,25 +234,32 @@ class SlideController(DisplayController, RegistryProperties):
self.hide_menu.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
self.hide_menu.setMenu(QtWidgets.QMenu(translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.toolbar.add_toolbar_widget(self.hide_menu)
self.blank_screen = create_action(self, 'blankScreen',
text=translate('OpenLP.SlideController', 'Blank Screen'),
icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_blank_display)
self.theme_screen = create_action(self, 'themeScreen',
text=translate('OpenLP.SlideController', 'Blank to Theme'),
icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
# The order of the blank to modes in Shortcuts list comes from here.
self.desktop_screen_enable = create_action(self, 'desktopScreenEnable',
text=translate('OpenLP.SlideController', 'Show Desktop'),
icon=':/slides/slide_desktop.png', can_shortcuts=True,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_hide_display_enable)
self.desktop_screen = create_action(self, 'desktopScreen',
text=translate('OpenLP.SlideController', 'Show Desktop'),
text=translate('OpenLP.SlideController', 'Toggle Desktop'),
icon=':/slides/slide_desktop.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_hide_display)
self.theme_screen = create_action(self, 'themeScreen',
text=translate('OpenLP.SlideController', 'Toggle Blank to Theme'),
icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
self.blank_screen = create_action(self, 'blankScreen',
text=translate('OpenLP.SlideController', 'Toggle Blank Screen'),
icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_blank_display)
self.hide_menu.setDefaultAction(self.blank_screen)
self.hide_menu.menu().addAction(self.blank_screen)
self.hide_menu.menu().addAction(self.theme_screen)
self.hide_menu.menu().addAction(self.desktop_screen)
self.hide_menu.menu().addAction(self.desktop_screen_enable)
# Wide menu of display control buttons.
self.blank_screen_button = QtWidgets.QToolButton(self.toolbar)
self.blank_screen_button.setObjectName('blank_screen_button')
@ -512,23 +519,6 @@ class SlideController(DisplayController, RegistryProperties):
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.service_next)
self.escape_item = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.live_escape)
def live_escape(self, field=None):
"""
If you press ESC on the live screen it should close the display temporarily.
"""
self.display.setVisible(False)
self.media_controller.media_stop(self)
# Stop looping if active
if self.play_slides_loop.isChecked():
self.on_play_slides_loop(False)
elif self.play_slides_once.isChecked():
self.on_play_slides_once(False)
def toggle_display(self, action):
"""
@ -622,7 +612,7 @@ class SlideController(DisplayController, RegistryProperties):
widget.addActions([
self.previous_item, self.next_item,
self.previous_service, self.next_service,
self.escape_item,
self.desktop_screen_enable,
self.desktop_screen,
self.theme_screen,
self.blank_screen])
@ -965,7 +955,7 @@ class SlideController(DisplayController, RegistryProperties):
else:
Registry().execute('live_display_show')
else:
self.live_escape()
self.on_hide_display_enable()
def on_slide_blank(self):
"""
@ -1025,6 +1015,7 @@ class SlideController(DisplayController, RegistryProperties):
def on_hide_display(self, checked=None):
"""
Handle the Hide screen button
This toggles the desktop screen.
:param checked: the new state of the of the widget
"""
@ -1043,6 +1034,20 @@ class SlideController(DisplayController, RegistryProperties):
self.update_preview()
self.on_toggle_loop()
def on_hide_display_enable(self, checked=None):
"""
Handle the on_hide_display_enable
This only enables the desktop screen.
:param checked: the new state of the of the widget
"""
self.blank_screen.setChecked(False)
self.theme_screen.setChecked(False)
Registry().execute('live_display_hide', HideMode.Screen)
self.desktop_screen.setChecked(True)
self.update_preview()
self.on_toggle_loop()
def blank_plugin(self):
"""
Blank/Hide the display screen within a plugin if required.

View File

@ -350,7 +350,7 @@ class CustomMediaItem(MediaManagerItem):
:param string: The search string
:param show_error: The error string to be show.
"""
search = '%{search}%'.forma(search=string.lower())
search = '%{search}%'.format(search=string.lower())
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
or_(func.lower(CustomSlide.title).like(search),
func.lower(CustomSlide.text).like(search)),

View File

@ -317,7 +317,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
self.song.verse_order = re.sub('([' + verse.upper() + verse.lower() + '])(\W|$)',
r'\g<1>1\2', self.song.verse_order)
except:
log.exception('Problem processing song Lyrics \n{xml}'.forma(xml=sxml.dump_xml()))
log.exception('Problem processing song Lyrics \n{xml}'.format(xml=sxml.dump_xml()))
raise
def keyPressEvent(self, event):

View File

@ -130,7 +130,6 @@
<file>clear_shortcut.png</file>
<file>system_about.png</file>
<file>system_help_contents.png</file>
<file>system_online_help.png</file>
<file>system_mediamanager.png</file>
<file>system_volunteer.png</file>
<file>system_servicemanager.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 953 B

View File

@ -208,29 +208,6 @@ class TestSlideController(TestCase):
mocked_on_theme_display.assert_called_once_with(False)
mocked_on_hide_display.assert_called_once_with(False)
def test_live_escape(self):
"""
Test that when the live_escape() method is called, the display is set to invisible and any media is stopped
"""
# GIVEN: A new SlideController instance and mocked out display and media_controller
mocked_display = MagicMock()
mocked_media_controller = MagicMock()
Registry.create()
Registry().register('media_controller', mocked_media_controller)
slide_controller = SlideController(None)
slide_controller.display = mocked_display
play_slides = MagicMock()
play_slides.isChecked.return_value = False
slide_controller.play_slides_loop = play_slides
slide_controller.play_slides_once = play_slides
# WHEN: live_escape() is called
slide_controller.live_escape()
# THEN: the display should be set to invisible and the media controller stopped
mocked_display.setVisible.assert_called_once_with(False)
mocked_media_controller.media_stop.assert_called_once_with(slide_controller)
def test_on_go_live_live_controller(self):
"""
Test that when the on_go_live() method is called the message is sent to the live controller and focus is
@ -697,7 +674,7 @@ class TestSlideController(TestCase):
slide_controller.next_item = MagicMock()
slide_controller.previous_service = MagicMock()
slide_controller.next_service = MagicMock()
slide_controller.escape_item = MagicMock()
slide_controller.desktop_screen_enable = MagicMock()
slide_controller.desktop_screen = MagicMock()
slide_controller.blank_screen = MagicMock()
slide_controller.theme_screen = MagicMock()
@ -709,7 +686,7 @@ class TestSlideController(TestCase):
mocked_widget.addActions.assert_called_with([
slide_controller.previous_item, slide_controller.next_item,
slide_controller.previous_service, slide_controller.next_service,
slide_controller.escape_item, slide_controller.desktop_screen,
slide_controller.desktop_screen_enable, slide_controller.desktop_screen,
slide_controller.theme_screen, slide_controller.blank_screen
])

View File

@ -114,6 +114,27 @@ class TestMediaItem(TestCase, TestMixin):
self.assertEqual(self.media_item.search_results, {})
self.assertEqual(self.media_item.second_search_results, {})
def test_required_icons(self):
"""
Test that all the required icons are set properly.
"""
# GIVEN: Mocked icons that need to be called.
self.media_item.has_import_icon = MagicMock()
self.media_item.has_new_icon = MagicMock()
self.media_item.has_edit_icon = MagicMock()
self.media_item.has_delete_icon = MagicMock()
self.media_item.add_to_service_item = MagicMock()
# WHEN: self.media_item.required_icons is called
self.media_item.required_icons()
# THEN: On windows it should return True, on other platforms False
self.assertTrue(self.media_item.has_import_icon, 'Check that the icon is as True.')
self.assertFalse(self.media_item.has_new_icon, 'Check that the icon is called as False.')
self.assertTrue(self.media_item.has_edit_icon, 'Check that the icon is called as True.')
self.assertTrue(self.media_item.has_delete_icon, 'Check that the icon is called as True.')
self.assertFalse(self.media_item.add_to_service_item, 'Check that the icon is called as False')
def test_on_quick_search_button_general(self):
"""
Test that general things, which should be called on all Quick searches are called.

View File

@ -70,8 +70,7 @@ class TestSwordImport(TestCase):
@patch('openlp.plugins.bibles.lib.importers.sword.SwordBible.application')
@patch('openlp.plugins.bibles.lib.importers.sword.modules')
@patch('openlp.core.common.languages')
def test_simple_import(self, mocked_languages, mocked_pysword_modules, mocked_application):
def test_simple_import(self, mocked_pysword_modules, mocked_application):
"""
Test that a simple SWORD import works
"""
@ -88,7 +87,7 @@ class TestSwordImport(TestCase):
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
mocked_languages.get_language.return_value = 'Danish'
importer.get_language = MagicMock(return_value='Danish')
mocked_bible = MagicMock()
mocked_genesis = MagicMock()
mocked_genesis.name = 'Genesis'