diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index e62cb3e44..491f3e652 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -166,58 +166,6 @@ def build_icon(icon): QtGui.QIcon.Normal, QtGui.QIcon.Off) return button_icon -def context_menu_action(base, icon, text, slot, shortcuts=None): - """ - Utility method to help build context menus for plugins - - ``base`` - The parent menu to add this menu item to - - ``icon`` - An icon for this action - - ``text`` - The text to display for this action - - ``slot`` - The code to run when this action is triggered - """ - action = QtGui.QAction(text, base) - if icon: - action.setIcon(build_icon(icon)) - QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot) - if shortcuts: - action.setShortcuts(shortcuts) - return action - -def context_menu(base, icon, text): - """ - Utility method to help build context menus for plugins - - ``base`` - The parent object to add this menu to - - ``icon`` - An icon for this menu - - ``text`` - The text to display for this menu - """ - action = QtGui.QMenu(text, base) - action.setIcon(build_icon(icon)) - return action - -def context_menu_separator(base): - """ - Add a separator to a context menu - - ``base`` - The menu object to add the separator to - """ - action = QtGui.QAction(u'', base) - action.setSeparator(True) - return action - def image_to_byte(image): """ Resize an image to fit on the current screen for the web and returns @@ -343,3 +291,4 @@ from dockwidget import OpenLPDockWidget from renderer import Renderer from rendermanager import RenderManager from mediamanageritem import MediaManagerItem +from openlp.core.utils.actions import ActionList diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 63132b141..7671064df 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -31,10 +31,10 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import context_menu_action, context_menu_separator, \ - SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \ - translate, Receiver, ListWidgetWithDnD -from openlp.core.lib.ui import UiStrings +from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \ + StringContent, build_icon, translate, Receiver, ListWidgetWithDnD +from openlp.core.lib.ui import UiStrings, context_menu_action, \ + context_menu_separator log = logging.getLogger(__name__) @@ -260,39 +260,42 @@ class MediaManagerItem(QtGui.QWidget): context_menu_action( self.listView, u':/general/general_edit.png', self.plugin.getString(StringContent.Edit)[u'title'], - self.onEditClick)) + self.onEditClick, context=QtCore.Qt.WidgetShortcut)) self.listView.addAction(context_menu_separator(self.listView)) if self.hasDeleteIcon: self.listView.addAction( context_menu_action( self.listView, u':/general/general_delete.png', self.plugin.getString(StringContent.Delete)[u'title'], - self.onDeleteClick, [QtCore.Qt.Key_Delete])) + self.onDeleteClick, [QtCore.Qt.Key_Delete], + context=QtCore.Qt.WidgetShortcut)) self.listView.addAction(context_menu_separator(self.listView)) self.listView.addAction( context_menu_action( self.listView, u':/general/general_preview.png', self.plugin.getString(StringContent.Preview)[u'title'], - self.onPreviewClick, [QtCore.Qt.Key_Enter])) + self.onPreviewClick, [QtCore.Qt.Key_Enter, + QtCore.Qt.Key_Return], context=QtCore.Qt.WidgetShortcut)) self.listView.addAction( context_menu_action( self.listView, u':/general/general_live.png', self.plugin.getString(StringContent.Live)[u'title'], self.onLiveClick, [QtCore.Qt.ShiftModifier + \ QtCore.Qt.Key_Enter, QtCore.Qt.ShiftModifier + \ - QtCore.Qt.Key_Return])) + QtCore.Qt.Key_Return], context=QtCore.Qt.WidgetShortcut)) self.listView.addAction( context_menu_action( self.listView, u':/general/general_add.png', self.plugin.getString(StringContent.Service)[u'title'], - self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal])) + self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + context=QtCore.Qt.WidgetShortcut)) if self.addToServiceItem: self.listView.addAction( context_menu_action( self.listView, u':/general/general_add.png', translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'), - self.onAddEditClick)) + self.onAddEditClick, context=QtCore.Qt.WidgetShortcut)) QtCore.QObject.connect(self.listView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onClickPressed) diff --git a/openlp/core/lib/searchedit.py b/openlp/core/lib/searchedit.py index 4841d76dc..d32961ef9 100644 --- a/openlp/core/lib/searchedit.py +++ b/openlp/core/lib/searchedit.py @@ -29,6 +29,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon +from openlp.core.lib.ui import icon_action log = logging.getLogger(__name__) @@ -132,7 +133,8 @@ class SearchEdit(QtGui.QLineEdit): menu = QtGui.QMenu(self) first = None for identifier, icon, title in items: - action = QtGui.QAction(build_icon(icon), title, menu) + action = icon_action(menu, u'', icon) + action.setText(title) action.setData(QtCore.QVariant(identifier)) menu.addAction(action) QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), diff --git a/openlp/core/lib/toolbar.py b/openlp/core/lib/toolbar.py index d5d2fa4f8..d2b37df51 100644 --- a/openlp/core/lib/toolbar.py +++ b/openlp/core/lib/toolbar.py @@ -51,8 +51,7 @@ class OpenLPToolbar(QtGui.QToolBar): log.debug(u'Init done for %s' % parent.__class__.__name__) def addToolbarButton(self, title, icon, tooltip=None, slot=None, - checkable=False, shortcut=0, alternate=0, - context=QtCore.Qt.WidgetShortcut): + checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut): """ A method to help developers easily add a button to the toolbar. @@ -74,16 +73,12 @@ class OpenLPToolbar(QtGui.QToolBar): If *True* the button has two, *off* and *on*, states. Default is *False*, which means the buttons has only one state. - ``shortcut`` - The primary shortcut for this action - - ``alternate`` - The alternate shortcut for this action + ``shortcuts`` + The list of shortcuts for this action ``context`` Specify the context in which this shortcut is valid """ - newAction = None if icon: actionIcon = build_icon(icon) if slot and not checkable: @@ -92,7 +87,7 @@ class OpenLPToolbar(QtGui.QToolBar): newAction = self.addAction(actionIcon, title) self.icons[title] = actionIcon else: - newAction = QtGui.QAction(title, newAction) + newAction = QtGui.QAction(title, self) self.addAction(newAction) QtCore.QObject.connect(newAction, QtCore.SIGNAL(u'triggered()'), slot) @@ -103,8 +98,9 @@ class OpenLPToolbar(QtGui.QToolBar): QtCore.QObject.connect(newAction, QtCore.SIGNAL(u'toggled(bool)'), slot) self.actions[title] = newAction - newAction.setShortcuts([shortcut, alternate]) - newAction.setShortcutContext(context) + if shortcuts is not None: + newAction.setShortcuts(shortcuts) + newAction.setShortcutContext(context) return newAction def addToolbarSeparator(self, handle): diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index fa0bc8afa..b8a02b043 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -31,6 +31,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, Receiver, translate +from openlp.core.utils.actions import ActionList log = logging.getLogger(__name__) @@ -57,8 +58,10 @@ class UiStrings(object): EmptyField = translate('OpenLP.Ui', 'Empty Field') Error = translate('OpenLP.Ui', 'Error') Export = translate('OpenLP.Ui', 'Export') + File = translate('OpenLP.Ui', 'File') FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') + Help = translate('OpenLP.Ui', 'Help') Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours') Image = translate('OpenLP.Ui', 'Image') Import = translate('OpenLP.Ui', 'Import') @@ -67,6 +70,7 @@ class UiStrings(object): Live = translate('OpenLP.Ui', 'Live') LiveBGError = translate('OpenLP.Ui', 'Live Background Error') LivePanel = translate('OpenLP.Ui', 'Live Panel') + LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar') Load = translate('OpenLP.Ui', 'Load') Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes') Middle = translate('OpenLP.Ui', 'Middle') @@ -84,6 +88,7 @@ class UiStrings(object): OpenService = translate('OpenLP.Ui', 'Open Service') Preview = translate('OpenLP.Ui', 'Preview') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') + PreviewToolbar = translate('OpenLP.Ui', 'Preview Toolbar') PrintServiceOrder = translate('OpenLP.Ui', 'Print Service Order') ReplaceBG = translate('OpenLP.Ui', 'Replace Background') ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background') @@ -94,15 +99,19 @@ class UiStrings(object): Search = translate('OpenLP.Ui', 'Search') SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.') SelectEdit = translate('OpenLP.Ui', 'You must select an item to edit.') + Settings = translate('OpenLP.Ui', 'Settings') SaveService = translate('OpenLP.Ui', 'Save Service') Service = translate('OpenLP.Ui', 'Service') StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s')) Theme = translate('OpenLP.Ui', 'Theme', 'Singular') Themes = translate('OpenLP.Ui', 'Themes', 'Plural') + Tools = translate('OpenLP.Ui', 'Tools') Top = translate('OpenLP.Ui', 'Top') VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide') VersePerLine = translate('OpenLP.Ui', 'Verse Per Line') Version = translate('OpenLP.Ui', 'Version') + View = translate('OpenLP.Ui', 'View') + ViewMode = translate('OpenLP.Ui', 'View Model') def add_welcome_page(parent, image): """ @@ -243,45 +252,128 @@ def create_up_down_push_button_set(parent): QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked) return up_button, down_button -def base_action(parent, name): +def base_action(parent, name, category=None): """ Return the most basic action with the object name set. + + ``category`` + The category the action should be listed in the shortcut dialog. If you + not wish, that this action is added to the shortcut dialog, then do not + state any. """ action = QtGui.QAction(parent) action.setObjectName(name) + if category is not None: + action_list = ActionList.get_instance() + action_list.add_action(action, category) return action -def checkable_action(parent, name, checked=None): +def checkable_action(parent, name, checked=None, category=None): """ Return a standard action with the checkable attribute set. """ - action = base_action(parent, name) + action = base_action(parent, name, category) action.setCheckable(True) if checked is not None: action.setChecked(checked) return action -def icon_action(parent, name, icon, checked=None): +def icon_action(parent, name, icon, checked=None, category=None): """ Return a standard action with an icon. """ if checked is not None: - action = checkable_action(parent, name, checked) + action = checkable_action(parent, name, checked, category) else: - action = base_action(parent, name) + action = base_action(parent, name, category) action.setIcon(build_icon(icon)) return action -def shortcut_action(parent, text, shortcuts, function): +def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None, + category=None, context=QtCore.Qt.WindowShortcut): """ Return a shortcut enabled action. """ - action = QtGui.QAction(text, parent) + action = QtGui.QAction(parent) + action.setObjectName(name) + if icon is not None: + action.setIcon(build_icon(icon)) + if checked is not None: + action.setCheckable(True) + action.setChecked(checked) action.setShortcuts(shortcuts) - action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) + action.setShortcutContext(context) + action_list = ActionList.get_instance() + action_list.add_action(action, category) QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function) return action +def context_menu_action(base, icon, text, slot, shortcuts=None, category=None, + context=QtCore.Qt.WindowShortcut): + """ + Utility method to help build context menus for plugins + + ``base`` + The parent menu to add this menu item to + + ``icon`` + An icon for this action + + ``text`` + The text to display for this action + + ``slot`` + The code to run when this action is triggered + + ``shortcuts`` + The action's shortcuts. + + ``category`` + The category the shortcut should be listed in the shortcut dialog. If + left to None, then the action will be hidden in the shortcut dialog. + + ``context`` + The context the shortcut is valid. + """ + action = QtGui.QAction(text, base) + if icon: + action.setIcon(build_icon(icon)) + QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot) + if shortcuts is not None: + action.setShortcuts(shortcuts) + action.setShortcutContext(context) + action_list = ActionList.get_instance() + action_list.add_action(action) + return action + +def context_menu(base, icon, text): + """ + Utility method to help build context menus for plugins + + ``base`` + The parent object to add this menu to + + ``icon`` + An icon for this menu + + ``text`` + The text to display for this menu + """ + action = QtGui.QMenu(text, base) + action.setIcon(build_icon(icon)) + return action + +def context_menu_separator(base): + """ + Add a separator to a context menu + + ``base`` + The menu object to add the separator to + """ + action = QtGui.QAction(u'', base) + action.setSeparator(True) + return action + def add_widget_completer(cache, widget): """ Adds a text autocompleter to a widget. diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 38775d68e..2038e1972 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -33,12 +33,13 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \ SettingsManager, PluginManager, Receiver, translate from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \ - icon_action + icon_action, shortcut_action from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \ ShortcutListForm, DisplayTagForm from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ - ActionList, get_application_version + get_application_version +from openlp.core.utils.actions import ActionList, CategoryOrder log = logging.getLogger(__name__) @@ -161,74 +162,86 @@ class Ui_MainWindow(object): mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock) # Create the menu items - self.FileNewItem = icon_action(mainWindow, u'FileNewItem', - u':/general/general_new.png') - mainWindow.actionList.add_action(self.FileNewItem, u'File') - self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem', - u':/general/general_open.png') - mainWindow.actionList.add_action(self.FileOpenItem, u'File') - self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem', - u':/general/general_save.png') - mainWindow.actionList.add_action(self.FileSaveItem, u'File') - self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem') - mainWindow.actionList.add_action(self.FileSaveAsItem, u'File') - self.printServiceOrderItem = base_action( - mainWindow, u'printServiceItem') - mainWindow.actionList.add_action( - self.printServiceOrderItem, u'Print Service Order') - self.FileExitItem = icon_action(mainWindow, u'FileExitItem', - u':/system/system_exit.png') - mainWindow.actionList.add_action(self.FileExitItem, u'File') - self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem') - mainWindow.actionList.add_action(self.ImportThemeItem, u'Import') - self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem') - mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') - self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem') - mainWindow.actionList.add_action(self.ExportThemeItem, u'Export') - self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem') - mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') - self.ViewMediaManagerItem = icon_action(mainWindow, - u'ViewMediaManagerItem', u':/system/system_mediamanager.png', - self.mediaManagerDock.isVisible()) - self.ViewThemeManagerItem = icon_action(mainWindow, - u'ViewThemeManagerItem', u':/system/system_thememanager.png', - self.themeManagerDock.isVisible()) - mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') - self.ViewServiceManagerItem = icon_action(mainWindow, - u'ViewServiceManagerItem', u':/system/system_servicemanager.png', - self.serviceManagerDock.isVisible()) - mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') - self.ViewPreviewPanel = checkable_action(mainWindow, - u'ViewPreviewPanel', previewVisible) - mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') - self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel', - liveVisible) - mainWindow.actionList.add_action(self.ViewLivePanel, u'View') - self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem') - mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') - self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem') - mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') - self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem', True) - mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode') + action_list = ActionList.get_instance() + action_list.add_category(UiStrings.File, CategoryOrder.standardMenu) + self.FileNewItem = shortcut_action(mainWindow, u'FileNewItem', + [QtGui.QKeySequence(u'Ctrl+N')], + self.ServiceManagerContents.onNewServiceClicked, + u':/general/general_new.png', category=UiStrings.File) + self.FileOpenItem = shortcut_action(mainWindow, u'FileOpenItem', + [QtGui.QKeySequence(u'Ctrl+O')], + self.ServiceManagerContents.onLoadServiceClicked, + u':/general/general_open.png', category=UiStrings.File) + self.FileSaveItem = shortcut_action(mainWindow, u'FileSaveItem', + [QtGui.QKeySequence(u'Ctrl+S')], + self.ServiceManagerContents.saveFile, + u':/general/general_save.png', category=UiStrings.File) + self.FileSaveAsItem = shortcut_action(mainWindow, u'FileSaveAsItem', + [QtGui.QKeySequence(u'Ctrl+Shift+S')], + self.ServiceManagerContents.saveFileAs, category=UiStrings.File) + self.printServiceOrderItem = shortcut_action(mainWindow, + u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')], + self.ServiceManagerContents.printServiceOrder, + category=UiStrings.File) + self.FileExitItem = shortcut_action(mainWindow, u'FileExitItem', + [QtGui.QKeySequence(u'Alt+F4')], mainWindow.close, + u':/system/system_exit.png', category=UiStrings.File) + action_list.add_category(UiStrings.Import, CategoryOrder.standardMenu) + self.ImportThemeItem = base_action( + mainWindow, u'ImportThemeItem', UiStrings.Import) + self.ImportLanguageItem = base_action( + mainWindow, u'ImportLanguageItem')#, UiStrings.Import) + action_list.add_category(UiStrings.Export, CategoryOrder.standardMenu) + self.ExportThemeItem = base_action( + mainWindow, u'ExportThemeItem', UiStrings.Export) + self.ExportLanguageItem = base_action( + mainWindow, u'ExportLanguageItem')#, UiStrings.Export) + action_list.add_category(UiStrings.View, CategoryOrder.standardMenu) + self.ViewMediaManagerItem = shortcut_action(mainWindow, + u'ViewMediaManagerItem', [QtGui.QKeySequence(u'F8')], + self.toggleMediaManager, u':/system/system_mediamanager.png', + self.mediaManagerDock.isVisible(), UiStrings.View) + self.ViewThemeManagerItem = shortcut_action(mainWindow, + u'ViewThemeManagerItem', [QtGui.QKeySequence(u'F10')], + self.toggleThemeManager, u':/system/system_thememanager.png', + self.themeManagerDock.isVisible(), UiStrings.View) + self.ViewServiceManagerItem = shortcut_action(mainWindow, + u'ViewServiceManagerItem', [QtGui.QKeySequence(u'F9')], + self.toggleServiceManager, u':/system/system_servicemanager.png', + self.serviceManagerDock.isVisible(), UiStrings.View) + self.ViewPreviewPanel = shortcut_action(mainWindow, + u'ViewPreviewPanel', [QtGui.QKeySequence(u'F11')], + self.setPreviewPanelVisibility, checked=previewVisible, + category=UiStrings.View) + self.ViewLivePanel = shortcut_action(mainWindow, u'ViewLivePanel', + [QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility, + checked=liveVisible, category=UiStrings.View) + action_list.add_category(UiStrings.ViewMode, CategoryOrder.standardMenu) + self.ModeDefaultItem = checkable_action( + mainWindow, u'ModeDefaultItem', category=UiStrings.ViewMode) + self.ModeSetupItem = checkable_action( + mainWindow, u'ModeLiveItem', category=UiStrings.ViewMode) + self.ModeLiveItem = checkable_action( + mainWindow, u'ModeLiveItem', True, UiStrings.ViewMode) self.ModeGroup = QtGui.QActionGroup(mainWindow) self.ModeGroup.addAction(self.ModeDefaultItem) self.ModeGroup.addAction(self.ModeSetupItem) self.ModeGroup.addAction(self.ModeLiveItem) self.ModeDefaultItem.setChecked(True) + action_list.add_category(UiStrings.Tools, CategoryOrder.standardMenu) self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem', - u':/tools/tools_add.png') - mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') + u':/tools/tools_add.png', category=UiStrings.Tools) self.ToolsOpenDataFolder = icon_action(mainWindow, - u'ToolsOpenDataFolder', u':/general/general_open.png') - mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools') - self.settingsPluginListItem = icon_action(mainWindow, - u'settingsPluginListItem', u':/system/settings_plugin_list.png') - mainWindow.actionList.add_action(self.settingsPluginListItem, - u'Settings') + u'ToolsOpenDataFolder', u':/general/general_open.png', + category=UiStrings.Tools) + action_list.add_category(UiStrings.Settings, CategoryOrder.standardMenu) + self.settingsPluginListItem = shortcut_action(mainWindow, + u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')], + self.onPluginItemClicked, u':/system/settings_plugin_list.png', + category=UiStrings.Settings) # i18n Language Items self.AutoLanguageItem = checkable_action(mainWindow, u'AutoLanguageItem', LanguageManager.auto_language) - mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') self.LanguageGroup = QtGui.QActionGroup(mainWindow) self.LanguageGroup.setExclusive(True) self.LanguageGroup.setObjectName(u'LanguageGroup') @@ -241,24 +254,26 @@ class Ui_MainWindow(object): add_actions(self.LanguageGroup, [languageItem]) self.SettingsShortcutsItem = icon_action(mainWindow, u'SettingsShortcutsItem', - u':/system/system_configure_shortcuts.png') + u':/system/system_configure_shortcuts.png', + category=UiStrings.Settings) self.DisplayTagItem = icon_action(mainWindow, - u'DisplayTagItem', u':/system/tag_editor.png') + u'DisplayTagItem', u':/system/tag_editor.png', + category=UiStrings.Settings) self.SettingsConfigureItem = icon_action(mainWindow, - u'SettingsConfigureItem', u':/system/system_settings.png') - mainWindow.actionList.add_action(self.SettingsShortcutsItem, - u'Settings') + u'SettingsConfigureItem', u':/system/system_settings.png', + category=UiStrings.Settings) + action_list.add_category(UiStrings.Help, CategoryOrder.standardMenu) self.HelpDocumentationItem = icon_action(mainWindow, - u'HelpDocumentationItem', u':/system/system_help_contents.png') + u'HelpDocumentationItem', u':/system/system_help_contents.png', + category=None)#UiStrings.Help) self.HelpDocumentationItem.setEnabled(False) - mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') - self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem', - u':/system/system_about.png') - mainWindow.actionList.add_action(self.HelpAboutItem, u'Help') - self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem') - mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') - self.helpWebSiteItem = base_action(mainWindow, u'helpWebSiteItem') - mainWindow.actionList.add_action(self.helpWebSiteItem, u'Help') + self.HelpAboutItem = shortcut_action(mainWindow, u'HelpAboutItem', + [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, + u':/system/system_about.png', category=UiStrings.Help) + self.HelpOnlineHelpItem = base_action( + mainWindow, u'HelpOnlineHelpItem', category=UiStrings.Help) + self.helpWebSiteItem = base_action( + mainWindow, u'helpWebSiteItem', category=UiStrings.Help) add_actions(self.FileImportMenu, (self.ImportThemeItem, self.ImportLanguageItem)) add_actions(self.FileExportMenu, @@ -294,14 +309,11 @@ class Ui_MainWindow(object): # Connect up some signals and slots QtCore.QObject.connect(self.FileMenu, QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu) - QtCore.QObject.connect(self.FileExitItem, - QtCore.SIGNAL(u'triggered()'), mainWindow.close) QtCore.QMetaObject.connectSlotsByName(mainWindow) # Hide the entry, as it does not have any functionality yet. self.ToolsAddToolItem.setVisible(False) self.ImportLanguageItem.setVisible(False) self.ExportLanguageItem.setVisible(False) - self.SettingsShortcutsItem.setVisible(False) self.HelpDocumentationItem.setVisible(False) def retranslateUi(self, mainWindow): @@ -329,36 +341,27 @@ class Ui_MainWindow(object): self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New')) self.FileNewItem.setToolTip(UiStrings.NewService) self.FileNewItem.setStatusTip(UiStrings.CreateService) - self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N')) self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open')) self.FileOpenItem.setToolTip(UiStrings.OpenService) self.FileOpenItem.setStatusTip( translate('OpenLP.MainWindow', 'Open an existing service.')) - self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O')) self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save')) self.FileSaveItem.setToolTip(UiStrings.SaveService) self.FileSaveItem.setStatusTip( translate('OpenLP.MainWindow', 'Save the current service to disk.')) - self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S')) self.FileSaveAsItem.setText( translate('OpenLP.MainWindow', 'Save &As...')) self.FileSaveAsItem.setToolTip( translate('OpenLP.MainWindow', 'Save Service As')) self.FileSaveAsItem.setStatusTip(translate('OpenLP.MainWindow', 'Save the current service under a new name.')) - self.FileSaveAsItem.setShortcut( - translate('OpenLP.MainWindow', 'Ctrl+Shift+S')) self.printServiceOrderItem.setText(UiStrings.PrintServiceOrder) self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow', 'Print the current Service Order.')) - self.printServiceOrderItem.setShortcut( - translate('OpenLP.MainWindow', 'Ctrl+P')) self.FileExitItem.setText( translate('OpenLP.MainWindow', 'E&xit')) self.FileExitItem.setStatusTip( translate('OpenLP.MainWindow', 'Quit OpenLP')) - self.FileExitItem.setShortcut( - translate('OpenLP.MainWindow', 'Alt+F4')) self.ImportThemeItem.setText( translate('OpenLP.MainWindow', '&Theme')) self.ImportLanguageItem.setText( @@ -379,53 +382,39 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', 'Toggle Media Manager')) self.ViewMediaManagerItem.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the media manager.')) - self.ViewMediaManagerItem.setShortcut( - translate('OpenLP.MainWindow', 'F8')) self.ViewThemeManagerItem.setText( translate('OpenLP.MainWindow', '&Theme Manager')) self.ViewThemeManagerItem.setToolTip( translate('OpenLP.MainWindow', 'Toggle Theme Manager')) self.ViewThemeManagerItem.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the theme manager.')) - self.ViewThemeManagerItem.setShortcut( - translate('OpenLP.MainWindow', 'F10')) self.ViewServiceManagerItem.setText( translate('OpenLP.MainWindow', '&Service Manager')) self.ViewServiceManagerItem.setToolTip( translate('OpenLP.MainWindow', 'Toggle Service Manager')) self.ViewServiceManagerItem.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the service manager.')) - self.ViewServiceManagerItem.setShortcut( - translate('OpenLP.MainWindow', 'F9')) self.ViewPreviewPanel.setText( translate('OpenLP.MainWindow', '&Preview Panel')) self.ViewPreviewPanel.setToolTip( translate('OpenLP.MainWindow', 'Toggle Preview Panel')) self.ViewPreviewPanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the preview panel.')) - self.ViewPreviewPanel.setShortcut( - translate('OpenLP.MainWindow', 'F11')) self.ViewLivePanel.setText( translate('OpenLP.MainWindow', '&Live Panel')) self.ViewLivePanel.setToolTip( translate('OpenLP.MainWindow', 'Toggle Live Panel')) self.ViewLivePanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) - self.ViewLivePanel.setShortcut( - translate('OpenLP.MainWindow', 'F12')) self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', '&Plugin List')) self.settingsPluginListItem.setStatusTip( translate('OpenLP.MainWindow', 'List the Plugins')) - self.settingsPluginListItem.setShortcut( - translate('OpenLP.MainWindow', 'Alt+F7')) self.HelpDocumentationItem.setText( translate('OpenLP.MainWindow', '&User Guide')) self.HelpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.HelpAboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) - self.HelpAboutItem.setShortcut( - translate('OpenLP.MainWindow', 'Ctrl+F1')) self.HelpOnlineHelpItem.setText( translate('OpenLP.MainWindow', '&Online Help')) # Uncomment after 1.9.5 beta string freeze @@ -467,8 +456,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ log.info(u'MainWindow loaded') - actionList = ActionList() - def __init__(self, screens, clipboard, arguments): """ This constructor sets up the interface, the various managers, and the @@ -485,7 +472,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.serviceSettingsSection = u'servicemanager' self.songsSettingsSection = u'songs' self.serviceNotSaved = False - self.actionList = ActionList() self.settingsmanager = SettingsManager(screens) self.aboutForm = AboutForm(self) self.settingsForm = SettingsForm(self.screens, self, self) @@ -510,16 +496,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(self.ExportThemeItem, QtCore.SIGNAL(u'triggered()'), self.themeManagerContents.onExportTheme) - QtCore.QObject.connect(self.ViewMediaManagerItem, - QtCore.SIGNAL(u'triggered(bool)'), self.toggleMediaManager) - QtCore.QObject.connect(self.ViewServiceManagerItem, - QtCore.SIGNAL(u'triggered(bool)'), self.toggleServiceManager) - QtCore.QObject.connect(self.ViewThemeManagerItem, - QtCore.SIGNAL(u'triggered(bool)'), self.toggleThemeManager) - QtCore.QObject.connect(self.ViewPreviewPanel, - QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility) - QtCore.QObject.connect(self.ViewLivePanel, - QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility) QtCore.QObject.connect(self.mediaManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'), self.ViewMediaManagerItem.setChecked) @@ -533,32 +509,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked) QtCore.QObject.connect(self.HelpOnlineHelpItem, QtCore.SIGNAL(u'triggered()'), self.onHelpOnLineHelpClicked) - QtCore.QObject.connect(self.HelpAboutItem, - QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked) QtCore.QObject.connect(self.ToolsOpenDataFolder, QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked) - QtCore.QObject.connect(self.settingsPluginListItem, - QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked) QtCore.QObject.connect(self.DisplayTagItem, QtCore.SIGNAL(u'triggered()'), self.onDisplayTagItemClicked) QtCore.QObject.connect(self.SettingsConfigureItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked) QtCore.QObject.connect(self.SettingsShortcutsItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked) - QtCore.QObject.connect(self.FileNewItem, QtCore.SIGNAL(u'triggered()'), - self.ServiceManagerContents.onNewServiceClicked) - QtCore.QObject.connect(self.FileOpenItem, - QtCore.SIGNAL(u'triggered()'), - self.ServiceManagerContents.onLoadServiceClicked) - QtCore.QObject.connect(self.FileSaveItem, - QtCore.SIGNAL(u'triggered()'), - self.ServiceManagerContents.saveFile) - QtCore.QObject.connect(self.FileSaveAsItem, - QtCore.SIGNAL(u'triggered()'), - self.ServiceManagerContents.saveFileAs) - QtCore.QObject.connect(self.printServiceOrderItem, - QtCore.SIGNAL(u'triggered()'), - self.ServiceManagerContents.printServiceOrder) # i18n set signals for languages self.LanguageGroup.triggered.connect(LanguageManager.set_language) QtCore.QObject.connect(self.ModeDefaultItem, @@ -781,7 +739,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Show the shortcuts dialog """ - self.shortcutForm.exec_(self.actionList) + if self.shortcutForm.exec_(): + self.shortcutForm.save() def onModeDefaultItemClicked(self): """ @@ -928,19 +887,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): unicode(translate('OpenLP.MainWindow', 'Default Theme: %s')) % theme) - def toggleMediaManager(self, visible): - if self.mediaManagerDock.isVisible() != visible: - self.mediaManagerDock.setVisible(visible) + def toggleMediaManager(self): + self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible()) - def toggleServiceManager(self, visible): - if self.serviceManagerDock.isVisible() != visible: - self.serviceManagerDock.setVisible(visible) + def toggleServiceManager(self): + self.serviceManagerDock.setVisible(not self.serviceManagerDock.isVisible()) - def toggleThemeManager(self, visible): - if self.themeManagerDock.isVisible() != visible: - self.themeManagerDock.setVisible(visible) + def toggleThemeManager(self): + self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible()) - def setPreviewPanelVisibility(self, visible): + def setPreviewPanelVisibility(self, visible=None): """ Sets the visibility of the preview panel including saving the setting and updating the menu. @@ -950,12 +906,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ + if visible is None: + visible = self.ViewPreviewPanel.isVisible() self.previewController.panel.setVisible(visible) QtCore.QSettings().setValue(u'user interface/preview panel', QtCore.QVariant(visible)) self.ViewPreviewPanel.setChecked(visible) - def setLivePanelVisibility(self, visible): + def setLivePanelVisibility(self, visible=None): """ Sets the visibility of the live panel including saving the setting and updating the menu. @@ -965,6 +923,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ + if visible is None: + visible = self.ViewLivePanel.isVisible() self.liveController.panel.setVisible(visible) QtCore.QSettings().setValue(u'user interface/live panel', QtCore.QVariant(visible)) @@ -1022,8 +982,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.FileMenu.addSeparator() for fileId, filename in enumerate(recentFilesToDisplay): log.debug('Recent file name: %s', filename) - action = QtGui.QAction(u'&%d %s' % (fileId + 1, - QtCore.QFileInfo(filename).fileName()), self) + action = base_action(self, u'') + action.setText(u'&%d %s' % + (fileId + 1, QtCore.QFileInfo(filename).fileName())) action.setData(QtCore.QVariant(filename)) self.connect(action, QtCore.SIGNAL(u'triggered()'), self.ServiceManagerContents.onRecentServiceClicked) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 4c4837676..ba9ca718a 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -32,15 +32,16 @@ log = logging.getLogger(__name__) from PyQt4 import QtCore, QtGui -from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ - Receiver, build_icon, ItemCapabilities, SettingsManager, translate +from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \ + ItemCapabilities, SettingsManager, translate from openlp.core.lib.theme import ThemeLevel from openlp.core.lib.ui import UiStrings, critical_error_message_box, \ - find_and_set_in_combo_box + context_menu_action, find_and_set_in_combo_box from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm from openlp.core.ui.printserviceform import PrintServiceForm from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ split_filename +from openlp.core.utils.actions import ActionList, CategoryOrder class ServiceManagerList(QtGui.QTreeWidget): """ @@ -165,38 +166,55 @@ class ServiceManager(QtGui.QWidget): u':/services/service_top.png', translate('OpenLP.ServiceManager', 'Move item to the top of the service.'), - self.onServiceTop, shortcut=QtCore.Qt.Key_Home) + self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home]) + self.serviceManagerList.moveTop.setObjectName(u'moveTop') + action_list = ActionList.get_instance() + action_list.add_category(UiStrings.Service, CategoryOrder.standardToolbar) + action_list.add_action( + self.serviceManagerList.moveTop, UiStrings.Service) self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Move &up'), u':/services/service_up.png', translate('OpenLP.ServiceManager', 'Move item up one position in the service.'), - self.onServiceUp, shortcut=QtCore.Qt.Key_PageUp) + self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp]) + self.serviceManagerList.moveUp.setObjectName(u'moveUp') + action_list.add_action(self.serviceManagerList.moveUp, UiStrings.Service) self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Move &down'), u':/services/service_down.png', translate('OpenLP.ServiceManager', 'Move item down one position in the service.'), - self.onServiceDown, shortcut=QtCore.Qt.Key_PageDown) + self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown]) + self.serviceManagerList.moveDown.setObjectName(u'moveDown') + action_list.add_action( + self.serviceManagerList.moveDown, UiStrings.Service) self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Move to &bottom'), u':/services/service_bottom.png', translate('OpenLP.ServiceManager', 'Move item to the end of the service.'), - self.onServiceEnd, shortcut=QtCore.Qt.Key_End) + self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End]) + self.serviceManagerList.moveBottom.setObjectName(u'moveBottom') + action_list.add_action( + self.serviceManagerList.moveBottom, UiStrings.Service) self.serviceManagerList.down = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Move &down'), None, translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), - self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Down) + self.onMoveSelectionDown, shortcuts=[QtCore.Qt.Key_Down]) + self.serviceManagerList.down.setObjectName(u'down') + action_list.add_action(self.serviceManagerList.down) self.serviceManagerList.down.setVisible(False) self.serviceManagerList.up = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Move up'), None, translate('OpenLP.ServiceManager', 'Moves the selection up the window.'), - self.onMoveSelectionUp, shortcut=QtCore.Qt.Key_Up) + self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up]) + self.serviceManagerList.up.setObjectName(u'up') + action_list.add_action(self.serviceManagerList.up) self.serviceManagerList.up.setVisible(False) self.orderToolbar.addSeparator() self.serviceManagerList.delete = self.orderToolbar.addToolbarButton( @@ -211,22 +229,28 @@ class ServiceManager(QtGui.QWidget): u':/services/service_expand_all.png', translate('OpenLP.ServiceManager', 'Expand all the service items.'), - self.onExpandAll, shortcut=QtCore.Qt.Key_Plus) + self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus]) + self.serviceManagerList.expand.setObjectName(u'expand') + action_list.add_action(self.serviceManagerList.expand, UiStrings.Service) self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', '&Collapse all'), u':/services/service_collapse_all.png', translate('OpenLP.ServiceManager', 'Collapse all the service items.'), - self.onCollapseAll, shortcut=QtCore.Qt.Key_Minus) + self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus]) + self.serviceManagerList.collapse.setObjectName(u'collapse') + action_list.add_action( + self.serviceManagerList.collapse, UiStrings.Service) self.orderToolbar.addSeparator() self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Go Live'), u':/general/general_live.png', translate('OpenLP.ServiceManager', - 'Send the selected item to Live.'), - self.makeLive, shortcut=QtCore.Qt.Key_Enter, - alternate=QtCore.Qt.Key_Return) - self.orderToolbar.setObjectName(u'orderToolbar') + 'Send the selected item to Live.'), self.makeLive, + shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]) + self.serviceManagerList.makeLive.setObjectName(u'orderToolbar') + action_list.add_action( + self.serviceManagerList.makeLive, UiStrings.Service) self.layout.addWidget(self.orderToolbar) # Connect up our signals and slots QtCore.QObject.connect(self.themeComboBox, @@ -301,7 +325,6 @@ class ServiceManager(QtGui.QWidget): self.themeMenu = QtGui.QMenu( translate('OpenLP.ServiceManager', '&Change Item Theme')) self.menu.addMenu(self.themeMenu) - self.setServiceHotkeys() self.serviceManagerList.addActions( [self.serviceManagerList.moveDown, self.serviceManagerList.moveUp, @@ -315,19 +338,6 @@ class ServiceManager(QtGui.QWidget): ]) self.configUpdated() - def setServiceHotkeys(self): - actionList = self.mainwindow.actionList - actionList.add_action(self.serviceManagerList.moveDown, u'Service') - actionList.add_action(self.serviceManagerList.moveUp, u'Service') - actionList.add_action(self.serviceManagerList.moveTop, u'Service') - actionList.add_action(self.serviceManagerList.moveBottom, u'Service') - actionList.add_action(self.serviceManagerList.makeLive, u'Service') - actionList.add_action(self.serviceManagerList.up, u'Service') - actionList.add_action(self.serviceManagerList.down, u'Service') - actionList.add_action(self.serviceManagerList.expand, u'Service') - actionList.add_action(self.serviceManagerList.collapse, u'Service') - - def setModified(self, modified=True): """ Setter for property "modified". Sets whether or not the current service @@ -692,9 +702,9 @@ class ServiceManager(QtGui.QWidget): Called by the SlideController to request a preview item be made live and allows the next preview to be updated if relevent. """ - id, row = message.split(u':') + uuid, row = message.split(u':') for sitem in self.serviceItems: - if sitem[u'service_item']._uuid == id: + if sitem[u'service_item']._uuid == uuid: item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1) self.serviceManagerList.setCurrentItem(item) self.makeLive(int(row)) @@ -1022,7 +1032,7 @@ class ServiceManager(QtGui.QWidget): editId, uuid = message.split(u':') for item in self.serviceItems: if item[u'service_item']._uuid == uuid: - item[u'service_item'].edit_id = editId + item[u'service_item'].edit_id = int(editId) self.setModified(True) def replaceServiceItem(self, newItem): @@ -1260,7 +1270,7 @@ class ServiceManager(QtGui.QWidget): for theme in theme_list: self.themeComboBox.addItem(theme) action = context_menu_action(self.serviceManagerList, None, theme, - self.onThemeChangeAction) + self.onThemeChangeAction, context=QtCore.Qt.WidgetShortcut) self.themeMenu.addAction(action) find_and_set_in_combo_box(self.themeComboBox, self.service_theme) self.mainwindow.renderManager.set_service_theme(self.service_theme) @@ -1301,4 +1311,4 @@ class ServiceManager(QtGui.QWidget): Print a Service Order Sheet. """ settingDialog = PrintServiceForm(self.mainwindow, self) - settingDialog.exec_() \ No newline at end of file + settingDialog.exec_() diff --git a/openlp/core/ui/shortcutlistdialog.py b/openlp/core/ui/shortcutlistdialog.py index 4e5b9e270..288086cba 100644 --- a/openlp/core/ui/shortcutlistdialog.py +++ b/openlp/core/ui/shortcutlistdialog.py @@ -31,41 +31,72 @@ from openlp.core.lib import translate, build_icon class Ui_ShortcutListDialog(object): def setupUi(self, shortcutListDialog): shortcutListDialog.setObjectName(u'shortcutListDialog') - self.dialogLayout = QtGui.QVBoxLayout(shortcutListDialog) - self.dialogLayout.setObjectName(u'dialogLayout') + shortcutListDialog.resize(500, 438) + self.shortcutListLayout = QtGui.QVBoxLayout(shortcutListDialog) + self.shortcutListLayout.setObjectName(u'shortcutListLayout') + self.descriptionLabel = QtGui.QLabel(shortcutListDialog) + self.descriptionLabel.setObjectName(u'descriptionLabel') + self.descriptionLabel.setWordWrap(True) + self.shortcutListLayout.addWidget(self.descriptionLabel) self.treeWidget = QtGui.QTreeWidget(shortcutListDialog) - self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setObjectName(u'treeWidget') + self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setColumnCount(3) - self.dialogLayout.addWidget(self.treeWidget) - self.defaultButton = QtGui.QRadioButton(shortcutListDialog) - self.defaultButton.setChecked(True) - self.defaultButton.setObjectName(u'defaultButton') - self.dialogLayout.addWidget(self.defaultButton) - self.customLayout = QtGui.QHBoxLayout() - self.customLayout.setObjectName(u'customLayout') - self.customButton = QtGui.QRadioButton(shortcutListDialog) - self.customButton.setObjectName(u'customButton') - self.customLayout.addWidget(self.customButton) - self.shortcutButton = QtGui.QPushButton(shortcutListDialog) - self.shortcutButton.setIcon( + self.treeWidget.setColumnWidth(0, 250) + self.shortcutListLayout.addWidget(self.treeWidget) + self.detailsLayout = QtGui.QGridLayout() + self.detailsLayout.setObjectName(u'detailsLayout') + self.detailsLayout.setContentsMargins(-1, 0, -1, -1) + self.defaultRadioButton = QtGui.QRadioButton(shortcutListDialog) + self.defaultRadioButton.setObjectName(u'defaultRadioButton') + self.defaultRadioButton.setChecked(True) + self.detailsLayout.addWidget(self.defaultRadioButton, 0, 0, 1, 1) + self.customRadioButton = QtGui.QRadioButton(shortcutListDialog) + self.customRadioButton.setObjectName(u'customRadioButton') + self.detailsLayout.addWidget(self.customRadioButton, 1, 0, 1, 1) + self.primaryLayout = QtGui.QHBoxLayout() + self.primaryLayout.setObjectName(u'primaryLayout') + self.primaryPushButton = QtGui.QPushButton(shortcutListDialog) + self.primaryPushButton.setObjectName(u'primaryPushButton') + self.primaryPushButton.setMinimumSize(QtCore.QSize(84, 0)) + self.primaryPushButton.setIcon( build_icon(u':/system/system_configure_shortcuts.png')) - self.shortcutButton.setCheckable(True) - self.shortcutButton.setObjectName(u'shortcutButton') - self.customLayout.addWidget(self.shortcutButton) - self.clearShortcutButton = QtGui.QToolButton(shortcutListDialog) - self.clearShortcutButton.setIcon( + self.primaryPushButton.setCheckable(True) + self.primaryLayout.addWidget(self.primaryPushButton) + self.clearPrimaryButton = QtGui.QToolButton(shortcutListDialog) + self.clearPrimaryButton.setObjectName(u'clearPrimaryButton') + self.clearPrimaryButton.setMinimumSize(QtCore.QSize(0, 16)) + self.clearPrimaryButton.setIcon( build_icon(u':/system/clear_shortcut.png')) - self.clearShortcutButton.setAutoRaise(True) - self.clearShortcutButton.setObjectName(u'clearShortcutButton') - self.customLayout.addWidget(self.clearShortcutButton) - self.customLayout.addStretch() - self.dialogLayout.addLayout(self.customLayout) + self.primaryLayout.addWidget(self.clearPrimaryButton) + self.detailsLayout.addLayout(self.primaryLayout, 1, 1, 1, 1) + self.alternateLayout = QtGui.QHBoxLayout() + self.alternateLayout.setObjectName(u'alternateLayout') + self.alternatePushButton = QtGui.QPushButton(shortcutListDialog) + self.alternatePushButton.setObjectName(u'alternatePushButton') + self.alternatePushButton.setCheckable(True) + self.alternatePushButton.setIcon( + build_icon(u':/system/system_configure_shortcuts.png')) + self.alternateLayout.addWidget(self.alternatePushButton) + self.clearAlternateButton = QtGui.QToolButton(shortcutListDialog) + self.clearAlternateButton.setObjectName(u'clearAlternateButton') + self.clearAlternateButton.setIcon( + build_icon(u':/system/clear_shortcut.png')) + self.alternateLayout.addWidget(self.clearAlternateButton) + self.detailsLayout.addLayout(self.alternateLayout, 1, 2, 1, 1) + self.primaryLabel = QtGui.QLabel(shortcutListDialog) + self.primaryLabel.setObjectName(u'primaryLabel') + self.detailsLayout.addWidget(self.primaryLabel, 0, 1, 1, 1) + self.alternateLabel = QtGui.QLabel(shortcutListDialog) + self.alternateLabel.setObjectName(u'alternateLabel') + self.detailsLayout.addWidget(self.alternateLabel, 0, 2, 1, 1) + self.shortcutListLayout.addLayout(self.detailsLayout) self.buttonBox = QtGui.QDialogButtonBox(shortcutListDialog) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | - QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Reset) self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | + QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.RestoreDefaults) + self.shortcutListLayout.addWidget(self.buttonBox) self.retranslateUi(shortcutListDialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), shortcutListDialog.accept) @@ -76,13 +107,24 @@ class Ui_ShortcutListDialog(object): def retranslateUi(self, shortcutListDialog): shortcutListDialog.setWindowTitle( translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts')) + self.descriptionLabel.setText(translate('OpenLP.ShortcutListDialog', + 'Select an action and click one of the buttons below to start ' + 'capturing a new primary or alternate shortcut, respectively.')) self.treeWidget.setHeaderLabels([ translate('OpenLP.ShortcutListDialog', 'Action'), translate('OpenLP.ShortcutListDialog', 'Shortcut'), translate('OpenLP.ShortcutListDialog', 'Alternate')]) - self.defaultButton.setText( - translate('OpenLP.ShortcutListDialog', 'Default: %s')) - self.customButton.setText( - translate('OpenLP.ShortcutListDialog', 'Custom:')) - self.shortcutButton.setText( - translate('OpenLP.ShortcutListDialog', 'None')) + self.defaultRadioButton.setText( + translate('OpenLP.ShortcutListDialog', 'Default')) + self.customRadioButton.setText( + translate('OpenLP.ShortcutListDialog', 'Custom')) + self.primaryPushButton.setToolTip( + translate('OpenLP.ShortcutListDialog', 'Capture shortcut.')) + self.alternatePushButton.setToolTip( + translate('OpenLP.ShortcutListDialog', 'Capture shortcut.')) + self.clearPrimaryButton.setToolTip( + translate('OpenLP.ShortcutListDialog', + 'Restore the default shortcut of this action.')) + self.clearAlternateButton.setToolTip( + translate('OpenLP.ShortcutListDialog', + 'Restore the default shortcut of this action.')) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index e87ba3ada..26bfddadd 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -30,6 +30,7 @@ import re from PyQt4 import QtCore, QtGui from openlp.core.utils import translate +from openlp.core.utils.actions import ActionList from shortcutlistdialog import Ui_ShortcutListDialog REMOVE_AMPERSAND = re.compile(r'&{1}') @@ -41,72 +42,391 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): The shortcut list dialog """ - def __init__(self, parent): - """ - Do some initialisation stuff - """ + def __init__(self, parent=None): QtGui.QDialog.__init__(self, parent) self.setupUi(self) - self.actionList = None - self.captureShortcut = False - QtCore.QObject.connect(self.shortcutButton, - QtCore.SIGNAL(u'toggled(bool)'), self.onShortcutButtonClicked) + self.changedActions = {} + self.action_list = ActionList.get_instance() + QtCore.QObject.connect(self.primaryPushButton, + QtCore.SIGNAL(u'toggled(bool)'), self.onPrimaryPushButtonClicked) + QtCore.QObject.connect(self.alternatePushButton, + QtCore.SIGNAL(u'toggled(bool)'), self.onAlternatePushButtonClicked) + QtCore.QObject.connect(self.treeWidget, QtCore.SIGNAL( + u'currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)'), + self.onCurrentItemChanged) + QtCore.QObject.connect(self.treeWidget, + QtCore.SIGNAL(u'itemDoubleClicked(QTreeWidgetItem*, int)'), + self.onItemDoubleClicked) + QtCore.QObject.connect(self.clearPrimaryButton, + QtCore.SIGNAL(u'clicked(bool)'), self.onClearPrimaryButtonClicked) + QtCore.QObject.connect(self.clearAlternateButton, + QtCore.SIGNAL(u'clicked(bool)'), self.onClearAlternateButtonClicked) + QtCore.QObject.connect(self.buttonBox, + QtCore.SIGNAL(u'clicked(QAbstractButton*)'), + self.onRestoreDefaultsClicked) + QtCore.QObject.connect(self.defaultRadioButton, + QtCore.SIGNAL(u'clicked(bool)'), self.onDefaultRadioButtonClicked) + QtCore.QObject.connect(self.customRadioButton, + QtCore.SIGNAL(u'clicked(bool)'), self.onCustomRadioButtonClicked) + + def keyPressEvent(self, event): + if self.primaryPushButton.isChecked() or \ + self.alternatePushButton.isChecked(): + event.ignore() + elif event.key() == QtCore.Qt.Key_Escape: + event.accept() + self.close() def keyReleaseEvent(self, event): - Qt = QtCore.Qt - if not self.captureShortcut: + if not self.primaryPushButton.isChecked() and \ + not self.alternatePushButton.isChecked(): return key = event.key() - if key == Qt.Key_Shift or key == Qt.Key_Control or \ - key == Qt.Key_Meta or key == Qt.Key_Alt: + if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \ + key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt: return key_string = QtGui.QKeySequence(key).toString() - if event.modifiers() & Qt.ControlModifier == Qt.ControlModifier: + if event.modifiers() & QtCore.Qt.ControlModifier == \ + QtCore.Qt.ControlModifier: key_string = u'Ctrl+' + key_string - if event.modifiers() & Qt.AltModifier == Qt.AltModifier: + if event.modifiers() & QtCore.Qt.AltModifier == QtCore.Qt.AltModifier: key_string = u'Alt+' + key_string - if event.modifiers() & Qt.ShiftModifier == Qt.ShiftModifier: + if event.modifiers() & QtCore.Qt.ShiftModifier == \ + QtCore.Qt.ShiftModifier: key_string = u'Shift+' + key_string key_sequence = QtGui.QKeySequence(key_string) - existing_key = QtGui.QKeySequence(u'Ctrl+Shift+F8') - if key_sequence == existing_key: - QtGui.QMessageBox.warning( - self, + # The action we are attempting to change. + changing_action = self._currentItemAction() + shortcut_valid = True + for category in self.action_list.categories: + for action in category.actions: + shortcuts = self._actionShortcuts(action) + if key_sequence not in shortcuts: + continue + if action is changing_action: + if self.primaryPushButton.isChecked() and \ + shortcuts.index(key_sequence) == 0: + continue + if self.alternatePushButton.isChecked() and \ + shortcuts.index(key_sequence) == 1: + continue + # Have the same parent, thus they cannot have the same shortcut. + if action.parent() is changing_action.parent(): + shortcut_valid = False + # The new shortcut is already assigned, but if both shortcuts + # are only valid in a different widget the new shortcut is + # vaild, because they will not interfere. + if action.shortcutContext() in [QtCore.Qt.WindowShortcut, + QtCore.Qt.ApplicationShortcut]: + shortcut_valid = False + if changing_action.shortcutContext() in \ + [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: + shortcut_valid = False + if not shortcut_valid: + QtGui.QMessageBox.warning(self, translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'), unicode(translate('OpenLP.ShortcutListDialog', 'The shortcut ' - '"%s" is already assigned to another action, please ' - 'use a different shortcut.')) % key_sequence.toString(), + '"%s" is already assigned to another action, please ' + 'use a different shortcut.')) % key_sequence.toString(), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok ) else: - self.shortcutButton.setText(key_sequence.toString()) - self.shortcutButton.setChecked(False) - self.captureShortcut = False + if self.primaryPushButton.isChecked(): + self._adjustButton(self.primaryPushButton, + False, text=key_sequence.toString()) + elif self.alternatePushButton.isChecked(): + self._adjustButton(self.alternatePushButton, + False, text=key_sequence.toString()) - def exec_(self, actionList): - self.actionList = actionList - self.refreshActions() + def exec_(self): + self.changedActions = {} + self.reloadShortcutList() + self._adjustButton(self.primaryPushButton, False, False, u'') + self._adjustButton(self.alternatePushButton, False, False, u'') return QtGui.QDialog.exec_(self) - def refreshActions(self): + def reloadShortcutList(self): + """ + Reload the ``treeWidget`` list to add new and remove old actions. + """ self.treeWidget.clear() - for category in self.actionList.categories: + for category in self.action_list.categories: + # Check if the category is for internal use only. + if category.name is None: + continue item = QtGui.QTreeWidgetItem([category.name]) for action in category.actions: actionText = REMOVE_AMPERSAND.sub('', unicode(action.text())) - if (len(action.shortcuts()) == 2): - shortcutText = action.shortcuts()[0].toString() - alternateText = action.shortcuts()[1].toString() - else: - shortcutText = action.shortcut().toString() - alternateText = u'' - actionItem = QtGui.QTreeWidgetItem( - [actionText, shortcutText, alternateText]) + actionItem = QtGui.QTreeWidgetItem([actionText]) actionItem.setIcon(0, action.icon()) + actionItem.setData(0, + QtCore.Qt.UserRole, QtCore.QVariant(action)) item.addChild(actionItem) - item.setExpanded(True) self.treeWidget.addTopLevelItem(item) + item.setExpanded(True) + self.refreshShortcutList() - def onShortcutButtonClicked(self, toggled): - self.captureShortcut = toggled + def refreshShortcutList(self): + """ + This refreshes the item's shortcuts shown in the list. Note, this + neither adds new actions nor removes old actions. + """ + iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget) + while iterator.value(): + item = iterator.value() + iterator += 1 + action = self._currentItemAction(item) + if action is None: + continue + shortcuts = self._actionShortcuts(action) + if len(shortcuts) == 0: + item.setText(1, u'') + item.setText(2, u'') + elif len(shortcuts) == 1: + item.setText(1, shortcuts[0].toString()) + item.setText(2, u'') + else: + item.setText(1, shortcuts[0].toString()) + item.setText(2, shortcuts[1].toString()) + self.onCurrentItemChanged() + + def onPrimaryPushButtonClicked(self, toggled): + """ + Save the new primary shortcut. + """ + self.customRadioButton.setChecked(True) + if toggled: + self.alternatePushButton.setChecked(False) + return + action = self._currentItemAction() + if action is None: + return + shortcuts = self._actionShortcuts(action) + new_shortcuts = [QtGui.QKeySequence(self.primaryPushButton.text())] + if len(shortcuts) == 2: + new_shortcuts.append(shortcuts[1]) + self.changedActions[action] = new_shortcuts + self.refreshShortcutList() + + def onAlternatePushButtonClicked(self, toggled): + """ + Save the new alternate shortcut. + """ + self.customRadioButton.setChecked(True) + if toggled: + self.primaryPushButton.setChecked(False) + return + action = self._currentItemAction() + if action is None: + return + shortcuts = self._actionShortcuts(action) + new_shortcuts = [] + if len(shortcuts) != 0: + new_shortcuts.append(shortcuts[0]) + new_shortcuts.append( + QtGui.QKeySequence(self.alternatePushButton.text())) + self.changedActions[action] = new_shortcuts + self.refreshShortcutList() + + def onItemDoubleClicked(self, item, column): + """ + A item has been double clicked. The ``primaryPushButton`` will be + checked and the item's shortcut will be displayed. + """ + action = self._currentItemAction(item) + if action is None: + return + self.primaryPushButton.setChecked(column in [0, 1]) + self.alternatePushButton.setChecked(column not in [0, 1]) + if column in [0, 1]: + self.primaryPushButton.setFocus(QtCore.Qt.OtherFocusReason) + else: + self.alternatePushButton.setFocus(QtCore.Qt.OtherFocusReason) + self.onCurrentItemChanged(item) + + def onCurrentItemChanged(self, item=None, previousItem=None): + """ + A item has been pressed. We adjust the button's text to the action's + shortcut which is encapsulate in the item. + """ + action = self._currentItemAction(item) + self.primaryPushButton.setEnabled(action is not None) + self.alternatePushButton.setEnabled(action is not None) + primary_text = u'' + alternate_text = u'' + primary_label_text = u'' + alternate_label_text = u'' + if action is None: + self.primaryPushButton.setChecked(False) + self.alternatePushButton.setChecked(False) + else: + if len(action.defaultShortcuts) != 0: + primary_label_text = action.defaultShortcuts[0].toString() + if len(action.defaultShortcuts) == 2: + alternate_label_text = action.defaultShortcuts[1].toString() + shortcuts = self._actionShortcuts(action) + # We do not want to loose pending changes, that is why we have to + # keep the text when, this function has not been triggered by a signal. + if item is None: + primary_text = self.primaryPushButton.text() + alternate_text = self.alternatePushButton.text() + elif len(shortcuts) == 1: + primary_text = shortcuts[0].toString() + elif len(shortcuts) == 2: + primary_text = shortcuts[0].toString() + alternate_text = shortcuts[1].toString() + self.primaryPushButton.setText(primary_text) + self.alternatePushButton.setText(alternate_text) + self.primaryLabel.setText(primary_label_text) + self.alternateLabel.setText(alternate_label_text) + # We do not want to toggle and radio button, as the function has not + # been triggered by a signal. + if item is None: + return + if primary_label_text == primary_text and \ + alternate_label_text == alternate_text: + self.defaultRadioButton.toggle() + else: + self.customRadioButton.toggle() + + def onRestoreDefaultsClicked(self, button): + """ + Restores all default shortcuts. + """ + if self.buttonBox.buttonRole(button) != QtGui.QDialogButtonBox.ResetRole: + return + if QtGui.QMessageBox.question(self, + translate('OpenLP.ShortcutListDialog', 'Restore Default Shortcuts'), + translate('OpenLP.ShortcutListDialog', 'Do you want to restore all ' + 'shortcuts to their defaults?'), QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No)) == QtGui.QMessageBox.No: + return + self._adjustButton(self.primaryPushButton, False, text=u'') + self._adjustButton(self.alternatePushButton, False, text=u'') + for category in self.action_list.categories: + for action in category.actions: + self.changedActions[action] = action.defaultShortcuts + self.refreshShortcutList() + + def onDefaultRadioButtonClicked(self, toggled): + """ + The default radio button has been clicked, which means we have to make + sure, that we use the default shortcuts for the action. + """ + if not toggled: + return + action = self._currentItemAction() + if action is None: + return + temp_shortcuts = self._actionShortcuts(action) + self.changedActions[action] = action.defaultShortcuts + self.refreshShortcutList() + primary_button_text = u'' + alternate_button_text = u'' + if len(temp_shortcuts) != 0: + primary_button_text = temp_shortcuts[0].toString() + if len(temp_shortcuts) == 2: + alternate_button_text = temp_shortcuts[1].toString() + self.primaryPushButton.setText(primary_button_text) + self.alternatePushButton.setText(alternate_button_text) + + def onCustomRadioButtonClicked(self, toggled): + """ + The custom shortcut radio button was clicked, thus we have to restore + the custom shortcuts by calling those functions triggered by button + clicks. + """ + if not toggled: + return + self.onPrimaryPushButtonClicked(False) + self.onAlternatePushButtonClicked(False) + self.refreshShortcutList() + + def save(self): + """ + Save the shortcuts. **Note**, that we do not have to load the shortcuts, + as they are loaded in :class:`~openlp.core.utils.ActionList`. + """ + settings = QtCore.QSettings() + settings.beginGroup(u'shortcuts') + for category in self.action_list.categories: + # Check if the category is for internal use only. + if category.name is None: + continue + for action in category.actions: + if self.changedActions .has_key(action): + action.setShortcuts(self.changedActions[action]) + settings.setValue( + action.objectName(), QtCore.QVariant(action.shortcuts())) + settings.endGroup() + + def onClearPrimaryButtonClicked(self, toggled): + """ + Restore the defaults of this action. + """ + self.primaryPushButton.setChecked(False) + action = self._currentItemAction() + if action is None: + return + shortcuts = self._actionShortcuts(action) + new_shortcuts = [] + if len(action.defaultShortcuts) != 0: + new_shortcuts.append(action.defaultShortcuts[0]) + if len(shortcuts) == 2: + new_shortcuts.append(shortcuts[1]) + self.changedActions[action] = new_shortcuts + self.refreshShortcutList() + self.onCurrentItemChanged(self.treeWidget.currentItem()) + + def onClearAlternateButtonClicked(self, toggled): + """ + Restore the defaults of this action. + """ + self.alternatePushButton.setChecked(False) + action = self._currentItemAction() + if action is None: + return + shortcuts = self._actionShortcuts(action) + new_shortcuts = [] + if len(shortcuts) != 0: + new_shortcuts.append(shortcuts[0]) + if len(action.defaultShortcuts) == 2: + new_shortcuts.append(action.defaultShortcuts[1]) + self.changedActions[action] = new_shortcuts + self.refreshShortcutList() + self.onCurrentItemChanged(self.treeWidget.currentItem()) + + def _actionShortcuts(self, action): + """ + This returns the shortcuts for the given ``action``, which also includes + those shortcuts which are not saved yet but already assigned (as changes + are applied when closing the dialog). + """ + if self.changedActions.has_key(action): + return self.changedActions[action] + return action.shortcuts() + + def _currentItemAction(self, item=None): + """ + Returns the action of the given ``item``. If no item is given, we return + the action of the current item of the ``treeWidget``. + """ + if item is None: + item = self.treeWidget.currentItem() + if item is None: + return + return item.data(0, QtCore.Qt.UserRole).toPyObject() + + def _adjustButton(self, button, checked=None, enabled=None, text=None): + """ + Can be called to adjust more properties of the given ``button`` at once. + """ + # Set the text before checking the button, because this emits a signal. + if text is not None: + button.setText(text) + if checked is not None: + button.setChecked(checked) + if enabled is not None: + button.setEnabled(enabled) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 232653326..4f5ed1ea7 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -32,8 +32,9 @@ from PyQt4.phonon import Phonon from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ ItemCapabilities, translate -from openlp.core.lib.ui import icon_action, UiStrings, shortcut_action +from openlp.core.lib.ui import UiStrings, shortcut_action from openlp.core.ui import HideMode, MainDisplay +from openlp.core.utils.actions import ActionList, CategoryOrder log = logging.getLogger(__name__) @@ -140,12 +141,16 @@ class SlideController(QtGui.QWidget): translate('OpenLP.SlideController', 'Previous Slide'), u':/slides/slide_previous.png', translate('OpenLP.SlideController', 'Move to previous'), - self.onSlideSelectedPrevious) + self.onSlideSelectedPrevious, + shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], + context=QtCore.Qt.WidgetWithChildrenShortcut) self.nextItem = self.toolbar.addToolbarButton( translate('OpenLP.SlideController', 'Next Slide'), u':/slides/slide_next.png', translate('OpenLP.SlideController', 'Move to next'), - self.onSlideSelectedNext) + self.onSlideSelectedNext, + shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown], + context=QtCore.Qt.WidgetWithChildrenShortcut) self.toolbar.addToolbarSeparator(u'Close Separator') if self.isLive: self.hideMenu = QtGui.QToolButton(self.toolbar) @@ -154,16 +159,20 @@ class SlideController(QtGui.QWidget): self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu) self.hideMenu.setMenu(QtGui.QMenu( translate('OpenLP.SlideController', 'Hide'), self.toolbar)) - self.blankScreen = icon_action(self.hideMenu, u'Blank Screen', - u':/slides/slide_blank.png', False) + self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen', + [QtCore.Qt.Key_Period], self.onBlankDisplay, + u':/slides/slide_blank.png', False, UiStrings.LiveToolbar) self.blankScreen.setText( translate('OpenLP.SlideController', 'Blank Screen')) - self.themeScreen = icon_action(self.hideMenu, u'Blank Theme', - u':/slides/slide_theme.png', False) + self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen', + [QtGui.QKeySequence(u'T')], self.onThemeDisplay, + u':/slides/slide_theme.png', False, UiStrings.LiveToolbar) self.themeScreen.setText( translate('OpenLP.SlideController', 'Blank to Theme')) - self.desktopScreen = icon_action(self.hideMenu, u'Desktop Screen', - u':/slides/slide_desktop.png', False) + self.desktopScreen = shortcut_action(self.hideMenu, + u'desktopScreen', [QtGui.QKeySequence(u'D')], + self.onHideDisplay, u':/slides/slide_desktop.png', False, + UiStrings.LiveToolbar) self.desktopScreen.setText( translate('OpenLP.SlideController', 'Show Desktop')) self.hideMenu.setDefaultAction(self.blankScreen) @@ -291,12 +300,6 @@ class SlideController(QtGui.QWidget): QtCore.QObject.connect(self.previewListWidget, QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) if self.isLive: - QtCore.QObject.connect(self.blankScreen, - QtCore.SIGNAL(u'triggered(bool)'), self.onBlankDisplay) - QtCore.QObject.connect(self.themeScreen, - QtCore.SIGNAL(u'triggered(bool)'), self.onThemeDisplay) - QtCore.QObject.connect(self.desktopScreen, - QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay) QtCore.QObject.connect(self.volumeSlider, QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume) QtCore.QObject.connect(Receiver.get_receiver(), @@ -362,33 +365,37 @@ class SlideController(QtGui.QWidget): QtCore.SIGNAL(u'config_screen_changed'), self.screenSizeChanged) def setPreviewHotkeys(self, parent=None): - actionList = self.parent.actionList - self.previousItem.setShortcuts([QtCore.Qt.Key_Up, 0]) - actionList.add_action(self.previousItem, u'Preview') - self.nextItem.setShortcuts([QtCore.Qt.Key_Down, 0]) - actionList.add_action(self.nextItem, u'Preview') + self.previousItem.setObjectName(u'previousItemPreview') + self.nextItem.setObjectName(u'nextItemPreview') + action_list = ActionList.get_instance() + action_list.add_category( + UiStrings.PreviewToolbar, CategoryOrder.standardToolbar) + action_list.add_action(self.previousItem, UiStrings.PreviewToolbar) + action_list.add_action(self.nextItem, UiStrings.PreviewToolbar) def setLiveHotkeys(self, parent=None): - actionList = self.parent.actionList - self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp]) - self.previousItem.setShortcutContext( - QtCore.Qt.WidgetWithChildrenShortcut) - actionList.add_action(self.previousItem, u'Live') - self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown]) - self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) - actionList.add_action(self.nextItem, u'Live') - self.previousService = shortcut_action(parent, - translate('OpenLP.SlideController', 'Previous Service'), - [QtCore.Qt.Key_Left, 0], self.servicePrevious) - actionList.add_action(self.previousService, u'Live') - self.nextService = shortcut_action(parent, - translate('OpenLP.SlideController', 'Next Service'), - [QtCore.Qt.Key_Right, 0], self.serviceNext) - actionList.add_action(self.nextService, u'Live') - self.escapeItem = shortcut_action(parent, - translate('OpenLP.SlideController', 'Escape Item'), - [QtCore.Qt.Key_Escape, 0], self.liveEscape) - actionList.add_action(self.escapeItem, u'Live') + self.previousItem.setObjectName(u'previousItemLive') + self.nextItem.setObjectName(u'nextItemLive') + action_list = ActionList.get_instance() + action_list.add_category( + UiStrings.LiveToolbar, CategoryOrder.standardToolbar) + action_list.add_action(self.previousItem, UiStrings.LiveToolbar) + action_list.add_action(self.nextItem, UiStrings.LiveToolbar) + self.previousService = shortcut_action(parent, u'previousService', + [QtCore.Qt.Key_Left], self.servicePrevious, UiStrings.LiveToolbar) + self.previousService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) + self.previousService.setText( + translate('OpenLP.SlideController', 'Previous Service')) + self.nextService = shortcut_action(parent, 'nextService', + [QtCore.Qt.Key_Right], self.serviceNext, UiStrings.LiveToolbar) + self.nextService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) + self.nextService.setText( + translate('OpenLP.SlideController', 'Next Service')) + self.escapeItem = shortcut_action(parent, 'escapeItem', + [QtCore.Qt.Key_Escape], self.liveEscape, UiStrings.LiveToolbar) + self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) + self.escapeItem.setText( + translate('OpenLP.SlideController', 'Escape Item')) def liveEscape(self): self.display.setVisible(False) @@ -741,10 +748,12 @@ class SlideController(QtGui.QWidget): """ self.onBlankDisplay(False) - def onBlankDisplay(self, checked): + def onBlankDisplay(self, checked=None): """ Handle the blank screen button actions """ + if checked is None: + checked = self.blankScreen.isChecked() log.debug(u'onBlankDisplay %s' % checked) self.hideMenu.setDefaultAction(self.blankScreen) self.blankScreen.setChecked(checked) @@ -762,10 +771,12 @@ class SlideController(QtGui.QWidget): self.blankPlugin(checked) self.updatePreview() - def onThemeDisplay(self, checked): + def onThemeDisplay(self, checked=None): """ Handle the Theme screen button """ + if checked is None: + checked = self.themeScreen.isChecked() log.debug(u'onThemeDisplay %s' % checked) self.hideMenu.setDefaultAction(self.themeScreen) self.blankScreen.setChecked(False) @@ -783,10 +794,12 @@ class SlideController(QtGui.QWidget): self.blankPlugin(checked) self.updatePreview() - def onHideDisplay(self, checked): + def onHideDisplay(self, checked=None): """ Handle the Hide screen button """ + if checked is None: + checked = self.desktopScreen.isChecked() log.debug(u'onHideDisplay %s' % checked) self.hideMenu.setDefaultAction(self.desktopScreen) self.blankScreen.setChecked(False) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 3c639297e..1bc7037ae 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -495,7 +495,7 @@ def get_uno_instance(resolver): from languagemanager import LanguageManager from actions import ActionList -__all__ = [u'AppLocation', u'check_latest_version', u'add_actions', - u'get_filesystem_encoding', u'LanguageManager', u'ActionList', - u'get_web_page', u'file_is_unicode', u'string_is_unicode', +__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version', + u'add_actions', u'get_filesystem_encoding', u'LanguageManager', + u'ActionList', u'get_web_page', u'file_is_unicode', u'string_is_unicode', u'get_uno_command', u'get_uno_instance', u'delete_file'] diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 41ae41f4b..0c4eee655 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -27,6 +27,8 @@ The :mod:`~openlp.core.utils.actions` module provides action list classes used by the shortcuts system. """ +from PyQt4 import QtCore, QtGui + class ActionCategory(object): """ The :class:`~openlp.core.utils.ActionCategory` class encapsulates a @@ -67,6 +69,7 @@ class CategoryActionList(object): Python 3 "next" method. """ if self.index >= len(self.actions): + self.index = 0 raise StopIteration else: self.index += 1 @@ -94,6 +97,12 @@ class CategoryActionList(object): self.actions.append((weight, action)) self.actions.sort(key=lambda act: act[0]) + def remove(self, remove_action): + for action in self.actions: + if action[1] == remove_action: + self.actions.remove(action) + return + class CategoryList(object): """ @@ -126,6 +135,7 @@ class CategoryList(object): Python 3 "next" method for iterator. """ if self.index >= len(self.categories): + self.index = 0 raise StopIteration else: self.index += 1 @@ -163,6 +173,11 @@ class CategoryList(object): self.categories.append(category) self.categories.sort(key=lambda cat: cat.weight) + def remove(self, name): + for category in self.categories: + if category.name == name: + self.categories.remove(category) + class ActionList(object): """ @@ -171,13 +186,101 @@ class ActionList(object): has a weight by which it is sorted when iterating through the list of actions or categories. """ + instance = None + def __init__(self): self.categories = CategoryList() - def add_action(self, action, category=u'Default', weight=None): + @staticmethod + def get_instance(): + if ActionList.instance is None: + ActionList.instance = ActionList() + return ActionList.instance + + def add_action(self, action, category=None, weight=None): + """ + Add an action to the list of actions. + + ``action`` + The action to add (QAction). + + ``category`` + The category this action belongs to. The category can be a QString + or python unicode string. **Note**, if the category is ``None``, the + category and its actions are being hidden in the shortcut dialog. + However, if they are added, it is possible to avoid assigning + shortcuts twice, which is important. + + ``weight`` + The weight specifies how important a category is. However, this only + has an impact on the order the categories are displayed. + """ + if category is not None: + category = unicode(category) if category not in self.categories: self.categories.append(category) + action.defaultShortcuts = action.shortcuts() if weight is None: self.categories[category].actions.append(action) else: self.categories[category].actions.add(action, weight) + if category is None: + # Stop here, as this action is not configurable. + return + # Load the shortcut from the config. + settings = QtCore.QSettings() + settings.beginGroup(u'shortcuts') + shortcuts = settings.value(action.objectName(), + QtCore.QVariant(action.shortcuts())).toStringList() + action.setShortcuts( + [QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) + settings.endGroup() + + def remove_action(self, action, category=None): + """ + This removes an action from its category. Empty categories are + automatically removed. + + ``action`` + The QAction object to be removed. + + ``category`` + The name (unicode string) of the category, which contains the + action. Defaults to None. + """ + if category is not None: + category = unicode(category) + if category not in self.categories: + return + self.categories[category].actions.remove(action) + # Remove empty categories. + if len(self.categories[category].actions) == 0: + self.categories.remove(category) + + def add_category(self, name, weight): + """ + Add an empty category to the list of categories. This is ony convenient + for categories with a given weight. + + ``name`` + The category's name. + + ``weight`` + The category's weight (int). + """ + if name in self.categories: + # Only change the weight and resort the categories again. + for category in self.categories: + if category.name == name: + category.weight = weight + self.categories.categories.sort(key=lambda cat: cat.weight) + return + self.categories.add(name, weight) + + +class CategoryOrder(object): + """ + An enumeration class for category weights. + """ + standardMenu = -20 + standardToolbar = -10 diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index df7823ed5..c5714c914 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -30,6 +30,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib.db import Manager +from openlp.core.lib.ui import icon_action, UiStrings +from openlp.core.utils.actions import ActionList from openlp.plugins.alerts.lib import AlertsManager, AlertsTab from openlp.plugins.alerts.lib.db import init_schema from openlp.plugins.alerts.forms import AlertForm @@ -59,9 +61,8 @@ class AlertsPlugin(Plugin): use it as their parent. """ log.info(u'add tools menu') - self.toolsAlertItem = QtGui.QAction(tools_menu) - self.toolsAlertItem.setIcon(build_icon(u':/plugins/plugin_alerts.png')) - self.toolsAlertItem.setObjectName(u'toolsAlertItem') + self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem', + u':/plugins/plugin_alerts.png') self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert')) self.toolsAlertItem.setStatusTip( translate('AlertsPlugin', 'Show an alert message.')) @@ -75,6 +76,8 @@ class AlertsPlugin(Plugin): log.info(u'Alerts Initialising') Plugin.initialise(self) self.toolsAlertItem.setVisible(True) + action_list = ActionList.get_instance() + action_list.add_action(self.toolsAlertItem, UiStrings.Tools) self.liveController.alertTab = self.settings_tab def finalise(self): @@ -85,6 +88,8 @@ class AlertsPlugin(Plugin): self.manager.finalise() Plugin.finalise(self) self.toolsAlertItem.setVisible(False) + action_list = ActionList.get_instance() + action_list.remove_action(self.toolsAlertItem, u'Tools') def toggleAlertsState(self): self.alertsActive = not self.alertsActive diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 4f677f211..aea732688 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -29,6 +29,8 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate +from openlp.core.lib.ui import base_action, UiStrings +from openlp.core.utils.actions import ActionList from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem log = logging.getLogger(__name__) @@ -50,6 +52,10 @@ class BiblePlugin(Plugin): self.manager = BibleManager(self) Plugin.initialise(self) self.importBibleItem.setVisible(True) + action_list = ActionList.get_instance() + action_list.add_action(self.importBibleItem, UiStrings.Import) + # Do not add the action to the list yet. + #action_list.add_action(self.exportBibleItem, UiStrings.Export) # Set to invisible until we can export bibles self.exportBibleItem.setVisible(False) @@ -60,25 +66,25 @@ class BiblePlugin(Plugin): log.info(u'Plugin Finalise') self.manager.finalise() Plugin.finalise(self) + action_list = ActionList.get_instance() + action_list.remove_action(self.importBibleItem, UiStrings.Import) self.importBibleItem.setVisible(False) + #action_list.remove_action(self.exportBibleItem, UiStrings.Export) self.exportBibleItem.setVisible(False) def addImportMenuItem(self, import_menu): - self.importBibleItem = QtGui.QAction(import_menu) - self.importBibleItem.setObjectName(u'importBibleItem') + self.importBibleItem = base_action(import_menu, u'importBibleItem') + self.importBibleItem.setText(translate('BiblesPlugin', '&Bible')) import_menu.addAction(self.importBibleItem) - self.importBibleItem.setText( - translate('BiblesPlugin', '&Bible')) # signals and slots QtCore.QObject.connect(self.importBibleItem, QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick) self.importBibleItem.setVisible(False) def addExportMenuItem(self, export_menu): - self.exportBibleItem = QtGui.QAction(export_menu) - self.exportBibleItem.setObjectName(u'exportBibleItem') - export_menu.addAction(self.exportBibleItem) + self.exportBibleItem = base_action(export_menu, u'exportBibleItem') self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible')) + export_menu.addAction(self.exportBibleItem) self.exportBibleItem.setVisible(False) def onBibleImportClick(self): diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index 117ffaf4c..35cd17c4b 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -85,8 +85,18 @@ class BibleImportForm(OpenLPWizard): """ OpenLPWizard.setupUi(self, image) QtCore.QObject.connect(self.formatComboBox, - QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack, - QtCore.SLOT(u'setCurrentIndex(int)')) + QtCore.SIGNAL(u'currentIndexChanged(int)'), + self.onCurrentIndexChanged) + + def onCurrentIndexChanged(self, index): + """ + Called when the format combo box's index changed. We have to check if + the import is available and accordingly to disable or enable the next + button. + """ + self.selectStack.setCurrentIndex(index) + next_button = self.button(QtGui.QWizard.NextButton) + next_button.setEnabled(BibleFormat.get_availability(index)) def customInit(self): """ diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 89ca69e33..7d6bc405e 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -322,11 +322,12 @@ class BibleMediaItem(MediaManagerItem): self.advancedVersionComboBox.addItem(bible) self.advancedSecondComboBox.addItem(bible) # set the default value - book = QtCore.QSettings().value( + bible = QtCore.QSettings().value( self.settingsSection + u'/advanced bible', QtCore.QVariant(u'')).toString() - find_and_set_in_combo_box(self.advancedVersionComboBox, book) - self.initialiseAdvancedBible(unicode(book)) + if bible in bibles: + find_and_set_in_combo_box(self.advancedVersionComboBox, bible) + self.initialiseAdvancedBible(unicode(bible)) def reloadBibles(self): log.debug(u'Reloading Bibles') diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 6d20c8f41..468d2f341 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -66,7 +66,17 @@ class SongImportForm(OpenLPWizard): self.formatStack.setCurrentIndex(0) QtCore.QObject.connect(self.formatComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'), - self.formatStack.setCurrentIndex) + self.onCurrentIndexChanged) + + def onCurrentIndexChanged(self, index): + """ + Called when the format combo box's index changed. We have to check if + the import is available and accordingly to disable or enable the next + button. + """ + self.formatStack.setCurrentIndex(index) + next_button = self.button(QtGui.QWizard.NextButton) + next_button.setEnabled(SongFormat.get_availability(index)) def customInit(self): """ diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index f4803d653..e2882ed29 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -283,19 +283,20 @@ class SongMediaItem(MediaManagerItem): self.remoteTriggered = None self.remoteSong = -1 - def onRemoteEdit(self, songid): + def onRemoteEdit(self, message): """ Called by ServiceManager or SlideController by event passing the Song Id in the payload along with an indicator to say which type of display is required. """ - log.debug(u'onRemoteEdit %s' % songid) - fields = songid.split(u':') - valid = self.parent.manager.get_object(Song, fields[1]) + log.debug(u'onRemoteEdit %s' % message) + remote_type, song_id = message.split(u':') + song_id = int(song_id) + valid = self.parent.manager.get_object(Song, song_id) if valid: - self.remoteSong = fields[1] - self.remoteTriggered = fields[0] - self.edit_song_form.loadSong(fields[1], (fields[0] == u'P')) + self.remoteSong = song_id + self.remoteTriggered = remote_type + self.edit_song_form.loadSong(song_id, (remote_type == u'P')) self.edit_song_form.exec_() def onEditClick(self): diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index c9c05907e..2ab66820c 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -39,12 +39,8 @@ if os.name == u'nt': PAGE_AFTER = 5 PAGE_BOTH = 6 else: - try: - import uno - from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \ - PAGE_BOTH - except ImportError: - pass + import uno + from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH class OooImport(SongImport): """ diff --git a/openlp/plugins/songs/lib/openlyricsexport.py b/openlp/plugins/songs/lib/openlyricsexport.py index d3367bfa9..59b720d3e 100644 --- a/openlp/plugins/songs/lib/openlyricsexport.py +++ b/openlp/plugins/songs/lib/openlyricsexport.py @@ -73,6 +73,8 @@ class OpenLyricsExport(object): u', '.join([author.display_name for author in song.authors])) filename = re.sub( r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_') - tree.write(os.path.join(self.save_path, filename), + # Pass a file object, because lxml does not cope with some special + # characters in the path (see lp:757673 and lp:744337). + tree.write(open(os.path.join(self.save_path, filename), u'w'), encoding=u'utf-8', xml_declaration=True, pretty_print=True) return True diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index 208ef3e52..c29abc0b5 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -63,7 +63,9 @@ class OpenLyricsImport(SongImport): self.import_wizard.incrementProgressBar( WizardStrings.ImportingType % os.path.basename(file_path)) try: - parsed_file = etree.parse(file_path, parser) + # Pass a file object, because lxml does not cope with some + # special characters in the path (see lp:757673 and lp:744337). + parsed_file = etree.parse(open(file_path, u'r'), parser) xml = unicode(etree.tostring(parsed_file)) if self.openLyrics.xml_to_song(xml) is None: log.debug(u'File could not be imported: %s' % file_path) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 1260a832b..af50f3f94 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -33,7 +33,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ Receiver from openlp.core.lib.db import Manager -from openlp.core.lib.ui import UiStrings +from openlp.core.lib.ui import UiStrings, base_action, icon_action +from openlp.core.utils.actions import ActionList from openlp.plugins.songs.lib import clean_song, SongMediaItem, SongsTab from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.importer import SongFormat @@ -65,6 +66,10 @@ class SongsPlugin(Plugin): log.info(u'Songs Initialising') Plugin.initialise(self) self.toolsReindexItem.setVisible(True) + action_list = ActionList.get_instance() + action_list.add_action(self.SongImportItem, UiStrings.Import) + action_list.add_action(self.SongExportItem, UiStrings.Export) + action_list.add_action(self.toolsReindexItem, UiStrings.Tools) self.mediaItem.displayResultsSong( self.manager.get_all_objects(Song, order_by_ref=Song.search_title)) @@ -78,10 +83,8 @@ class SongsPlugin(Plugin): use it as their parent. """ # Main song import menu item - will eventually be the only one - self.SongImportItem = QtGui.QAction(import_menu) - self.SongImportItem.setObjectName(u'SongImportItem') - self.SongImportItem.setText(translate( - 'SongsPlugin', '&Song')) + self.SongImportItem = base_action(import_menu, u'SongImportItem') + self.SongImportItem.setText(translate('SongsPlugin', '&Song')) self.SongImportItem.setToolTip(translate('SongsPlugin', 'Import songs using the import wizard.')) import_menu.addAction(self.SongImportItem) @@ -99,10 +102,8 @@ class SongsPlugin(Plugin): use it as their parent. """ # Main song import menu item - will eventually be the only one - self.SongExportItem = QtGui.QAction(export_menu) - self.SongExportItem.setObjectName(u'SongExportItem') - self.SongExportItem.setText(translate( - 'SongsPlugin', '&Song')) + self.SongExportItem = base_action(export_menu, u'SongExportItem') + self.SongExportItem.setText(translate('SongsPlugin', '&Song')) self.SongExportItem.setToolTip(translate('SongsPlugin', 'Exports songs using the export wizard.')) export_menu.addAction(self.SongExportItem) @@ -120,9 +121,8 @@ class SongsPlugin(Plugin): use it as their parent. """ log.info(u'add tools menu') - self.toolsReindexItem = QtGui.QAction(tools_menu) - self.toolsReindexItem.setIcon(build_icon(u':/plugins/plugin_songs.png')) - self.toolsReindexItem.setObjectName(u'toolsReindexItem') + self.toolsReindexItem = icon_action(tools_menu, u'toolsReindexItem', + u':/plugins/plugin_songs.png') self.toolsReindexItem.setText( translate('SongsPlugin', '&Re-index Songs')) self.toolsReindexItem.setStatusTip( @@ -259,4 +259,8 @@ class SongsPlugin(Plugin): log.info(u'Songs Finalising') self.manager.finalise() self.toolsReindexItem.setVisible(False) + action_list = ActionList.get_instance() + action_list.remove_action(self.SongImportItem, UiStrings.Import) + action_list.remove_action(self.SongExportItem, UiStrings.Export) + action_list.remove_action(self.toolsReindexItem, UiStrings.Tools) Plugin.finalise(self) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 8ff40373a..5f21451b6 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -32,6 +32,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \ translate from openlp.core.lib.db import Manager +from openlp.core.lib.ui import base_action, shortcut_action, UiStrings +from openlp.core.utils.actions import ActionList from openlp.plugins.songusage.forms import SongUsageDetailForm, \ SongUsageDeleteForm from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem @@ -63,30 +65,25 @@ class SongUsagePlugin(Plugin): self.SongUsageMenu.setObjectName(u'SongUsageMenu') self.SongUsageMenu.setTitle(translate( 'SongUsagePlugin', '&Song Usage Tracking')) - #SongUsage Delete - self.SongUsageDelete = QtGui.QAction(tools_menu) + # SongUsage Delete + self.SongUsageDelete = base_action(tools_menu, u'SongUsageDelete') self.SongUsageDelete.setText(translate('SongUsagePlugin', '&Delete Tracking Data')) self.SongUsageDelete.setStatusTip(translate('SongUsagePlugin', 'Delete song usage data up to a specified date.')) - self.SongUsageDelete.setObjectName(u'SongUsageDelete') - #SongUsage Report - self.SongUsageReport = QtGui.QAction(tools_menu) + # SongUsage Report + self.SongUsageReport = base_action(tools_menu, u'SongUsageReport') self.SongUsageReport.setText( translate('SongUsagePlugin', '&Extract Tracking Data')) self.SongUsageReport.setStatusTip( translate('SongUsagePlugin', 'Generate a report on song usage.')) - self.SongUsageReport.setObjectName(u'SongUsageReport') - #SongUsage activation - self.SongUsageStatus = QtGui.QAction(tools_menu) - self.SongUsageStatus.setCheckable(True) - self.SongUsageStatus.setChecked(False) + # SongUsage activation + self.SongUsageStatus = shortcut_action(tools_menu, u'SongUsageStatus', + [QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False) self.SongUsageStatus.setText(translate( 'SongUsagePlugin', 'Toggle Tracking')) self.SongUsageStatus.setStatusTip(translate('SongUsagePlugin', 'Toggle the tracking of song usage.')) - self.SongUsageStatus.setShortcut(u'F4') - self.SongUsageStatus.setObjectName(u'SongUsageStatus') #Add Menus together self.toolsMenu.addAction(self.SongUsageMenu.menuAction()) self.SongUsageMenu.addAction(self.SongUsageStatus) @@ -97,9 +94,6 @@ class SongUsagePlugin(Plugin): QtCore.QObject.connect(self.SongUsageStatus, QtCore.SIGNAL(u'visibilityChanged(bool)'), self.SongUsageStatus.setChecked) - QtCore.QObject.connect(self.SongUsageStatus, - QtCore.SIGNAL(u'triggered(bool)'), - self.toggleSongUsageState) QtCore.QObject.connect(self.SongUsageDelete, QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete) QtCore.QObject.connect(self.SongUsageReport, @@ -116,6 +110,13 @@ class SongUsagePlugin(Plugin): self.settingsSection + u'/active', QtCore.QVariant(False)).toBool() self.SongUsageStatus.setChecked(self.SongUsageActive) + action_list = ActionList.get_instance() + action_list.add_action(self.SongUsageDelete, + translate('SongUsagePlugin', 'Song Usage')) + action_list.add_action(self.SongUsageReport, + translate('SongUsagePlugin', 'Song Usage')) + action_list.add_action(self.SongUsageStatus, + translate('SongUsagePlugin', 'Song Usage')) if self.manager is None: self.manager = Manager(u'songusage', init_schema) self.SongUsagedeleteform = SongUsageDeleteForm(self.manager, @@ -131,6 +132,13 @@ class SongUsagePlugin(Plugin): self.manager.finalise() Plugin.finalise(self) self.SongUsageMenu.menuAction().setVisible(False) + action_list = ActionList.get_instance() + action_list.remove_action(self.SongUsageDelete, + translate('SongUsagePlugin', 'Song Usage')) + action_list.remove_action(self.SongUsageReport, + translate('SongUsagePlugin', 'Song Usage')) + action_list.remove_action(self.SongUsageStatus, + translate('SongUsagePlugin', 'Song Usage')) #stop any events being processed self.SongUsageActive = False diff --git a/resources/forms/shortcutlistdialog.ui b/resources/forms/shortcutlistdialog.ui index 519925560..9a5c599d1 100644 --- a/resources/forms/shortcutlistdialog.ui +++ b/resources/forms/shortcutlistdialog.ui @@ -41,35 +41,35 @@ - + + + 0 + 8 - - 0 - - + - Default: None + Default: true - - + + + + Custom: + + + + + 8 - - - - Custom: - - - @@ -83,7 +83,7 @@ - :/system/system_settings.png:/system/system_settings.png + :/system/system_configure_shortcuts.png:/system/system_configure_shortcuts.png true @@ -110,21 +110,51 @@ + + + + + + 8 + - - - Qt::Horizontal + + + None - - - 40 - 20 - + + + :/system/system_configure_shortcuts.png:/system/system_configure_shortcuts.png - + + + + + + + + + + :/system/clear_shortcut.png:/system/clear_shortcut.png + + + + + + Ctrl+V + + + + + + + Shift+Ins + + +