diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index c1a9f8b35..6aa06bfcc 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__) @@ -265,6 +266,7 @@ def icon_action(parent, name, icon, checked=None): else: action = base_action(parent, name) action.setIcon(build_icon(icon)) + #actionList.add_action(action, name) return action def shortcut_action(parent, text, shortcuts, function): diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 594c6cc91..98144bfa3 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -38,7 +38,8 @@ 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 log = logging.getLogger(__name__) @@ -163,53 +164,52 @@ class Ui_MainWindow(object): # Create the menu items self.FileNewItem = icon_action(mainWindow, u'FileNewItem', u':/general/general_new.png') - mainWindow.actionList.add_action(self.FileNewItem, u'File') + 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') + 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') + actionList.add_action(self.FileSaveItem, u'File') self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem') - mainWindow.actionList.add_action(self.FileSaveAsItem, u'File') + actionList.add_action(self.FileSaveAsItem, u'File') self.printServiceOrderItem = base_action( mainWindow, u'printServiceItem') - mainWindow.actionList.add_action( - self.printServiceOrderItem, u'Print Service Order') + actionList.add_action(self.printServiceOrderItem, u'File') self.FileExitItem = icon_action(mainWindow, u'FileExitItem', u':/system/system_exit.png') - mainWindow.actionList.add_action(self.FileExitItem, u'File') + actionList.add_action(self.FileExitItem, u'File') self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem') - mainWindow.actionList.add_action(self.ImportThemeItem, u'Import') + actionList.add_action(self.ImportThemeItem, u'Import') self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem') - mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') + actionList.add_action(self.ImportLanguageItem, u'Import') self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem') - mainWindow.actionList.add_action(self.ExportThemeItem, u'Export') + actionList.add_action(self.ExportThemeItem, u'Export') self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem') - mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') + 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') + 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') + actionList.add_action(self.ViewServiceManagerItem, u'View') self.ViewPreviewPanel = checkable_action(mainWindow, u'ViewPreviewPanel', previewVisible) - mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') + actionList.add_action(self.ViewPreviewPanel, u'View') self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel', liveVisible) - mainWindow.actionList.add_action(self.ViewLivePanel, u'View') + actionList.add_action(self.ViewLivePanel, u'View') self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem') - mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') + actionList.add_action(self.ModeDefaultItem, u'View Mode') self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem') - mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') + 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') + actionList.add_action(self.ModeLiveItem, u'View Mode') self.ModeGroup = QtGui.QActionGroup(mainWindow) self.ModeGroup.addAction(self.ModeDefaultItem) self.ModeGroup.addAction(self.ModeSetupItem) @@ -217,18 +217,18 @@ class Ui_MainWindow(object): self.ModeDefaultItem.setChecked(True) self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem', u':/tools/tools_add.png') - mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') + actionList.add_action(self.ToolsAddToolItem, u'Tools') self.ToolsOpenDataFolder = icon_action(mainWindow, u'ToolsOpenDataFolder', u':/general/general_open.png') - mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools') + 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, + actionList.add_action(self.settingsPluginListItem, u'Settings') # i18n Language Items self.AutoLanguageItem = checkable_action(mainWindow, u'AutoLanguageItem', LanguageManager.auto_language) - mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') + actionList.add_action(self.AutoLanguageItem, u'Settings') self.LanguageGroup = QtGui.QActionGroup(mainWindow) self.LanguageGroup.setExclusive(True) self.LanguageGroup.setObjectName(u'LanguageGroup') @@ -246,19 +246,19 @@ class Ui_MainWindow(object): u'DisplayTagItem', u':/system/tag_editor.png') self.SettingsConfigureItem = icon_action(mainWindow, u'SettingsConfigureItem', u':/system/system_settings.png') - mainWindow.actionList.add_action(self.SettingsShortcutsItem, + actionList.add_action(self.SettingsShortcutsItem, u'Settings') self.HelpDocumentationItem = icon_action(mainWindow, u'HelpDocumentationItem', u':/system/system_help_contents.png') self.HelpDocumentationItem.setEnabled(False) - mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') + 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') + actionList.add_action(self.HelpAboutItem, u'Help') self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem') - mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') + actionList.add_action(self.HelpOnlineHelpItem, u'Help') self.helpWebSiteItem = base_action(mainWindow, u'helpWebSiteItem') - mainWindow.actionList.add_action(self.helpWebSiteItem, u'Help') + actionList.add_action(self.helpWebSiteItem, u'Help') add_actions(self.FileImportMenu, (self.ImportThemeItem, self.ImportLanguageItem)) add_actions(self.FileExportMenu, @@ -301,7 +301,6 @@ class Ui_MainWindow(object): self.ToolsAddToolItem.setVisible(False) self.ImportLanguageItem.setVisible(False) self.ExportLanguageItem.setVisible(False) - self.SettingsShortcutsItem.setVisible(False) self.HelpDocumentationItem.setVisible(False) def retranslateUi(self, mainWindow): @@ -467,8 +466,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ log.info(u'MainWindow loaded') - actionList = ActionList() - def __init__(self, screens, application): """ This constructor sets up the interface, the various managers, and the @@ -476,7 +473,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ QtGui.QMainWindow.__init__(self) self.screens = screens - self.application = application # Set up settings sections for the main application # (not for use by plugins) @@ -485,7 +481,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) @@ -777,7 +772,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Show the shortcuts dialog """ - self.shortcutForm.exec_(self.actionList) + self.shortcutForm.exec_() def onModeDefaultItemClicked(self): """ diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 168ad8a8c..1d5321e01 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -40,6 +40,7 @@ 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 class ServiceManagerList(QtGui.QTreeWidget): """ @@ -315,7 +316,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') diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index e87ba3ada..a61dd41ed 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}') @@ -40,21 +41,24 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): """ The shortcut list dialog """ - - def __init__(self, parent): - """ - Do some initialisation stuff - """ +#TODO: do not close on ESC +#TODO: ability to remove actions +#TODO: Save shortcuts +#TODO: doc + def __init__(self, parent=None): QtGui.QDialog.__init__(self, parent) self.setupUi(self) - self.actionList = None - self.captureShortcut = False + self.assingedShortcuts = [] + self.shortcutButton.setText(u'') QtCore.QObject.connect(self.shortcutButton, QtCore.SIGNAL(u'toggled(bool)'), self.onShortcutButtonClicked) + QtCore.QObject.connect(self.treeWidget, + QtCore.SIGNAL(u'itemPressed(QTreeWidgetItem*, int)'), + self.onItemPressed) def keyReleaseEvent(self, event): Qt = QtCore.Qt - if not self.captureShortcut: + if not self.shortcutButton.isChecked(): return key = event.key() if key == Qt.Key_Shift or key == Qt.Key_Control or \ @@ -68,45 +72,80 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if event.modifiers() & Qt.ShiftModifier == 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, + if key_sequence in self.assingedShortcuts: + 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 + self.shortcutButton.setChecked(False) - def exec_(self, actionList): - self.actionList = actionList - self.refreshActions() + def exec_(self): + # The dialog is opened the first time + if self.treeWidget.topLevelItemCount() == 0: + QtCore.QObject.connect(actionList.signal, + QtCore.SIGNAL(u'addedAction()'), self.initialiseActionList) + self.initialiseActionList() + self.refreshActionList() return QtGui.QDialog.exec_(self) - def refreshActions(self): - self.treeWidget.clear() - for category in self.actionList.categories: - item = QtGui.QTreeWidgetItem([category.name]) - for action in category.actions: + def refreshActionList(self): + self.assingedShortcuts = [] + iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget) + while iterator.value(): + treewidgetItem = iterator.value() + action = treewidgetItem.data(0, QtCore.Qt.UserRole).toPyObject() + if action is not None: actionText = REMOVE_AMPERSAND.sub('', unicode(action.text())) - if (len(action.shortcuts()) == 2): + 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]) + self.assingedShortcuts.extend(action.shortcuts()) + treewidgetItem.setText(0, actionText) + treewidgetItem.setText(1, shortcutText) + treewidgetItem.setText(2, alternateText) + iterator += 1 + + def initialiseActionList(self): + for category in actionList.categories: + item = QtGui.QTreeWidgetItem([category.name]) + for action in category.actions: + actionItem = QtGui.QTreeWidgetItem() actionItem.setIcon(0, action.icon()) + actionItem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(action)) item.addChild(actionItem) item.setExpanded(True) self.treeWidget.addTopLevelItem(item) def onShortcutButtonClicked(self, toggled): - self.captureShortcut = toggled + if toggled: + return + item = self.treeWidget.currentItem() + action = item.data(0, QtCore.Qt.UserRole).toPyObject() + if action is None: + return + # TODO: Sort out which shortcuts should be kept. + action.setShortcuts(QtGui.QKeySequence(self.shortcutButton.text())) + self.refreshActionList() + + def onItemPressed(self, item, column): + item = self.treeWidget.currentItem() + action = item.data(0, QtCore.Qt.UserRole).toPyObject() + if action is None: + text = u'' + else: + if len(action.shortcuts()) == 0: + text = u'' + elif len(action.shortcuts()) == 2 and column == 2: + text = action.shortcuts()[1].toString() + else: + text = action.shortcuts()[0].toString() + self.shortcutButton.setText(text) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 232653326..1ae84e950 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -34,6 +34,7 @@ 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.ui import HideMode, MainDisplay +from openlp.core.utils.actions import actionList log = logging.getLogger(__name__) @@ -362,14 +363,12 @@ 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') 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) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 41ae41f4b..ba4a7b40d 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 + class ActionCategory(object): """ The :class:`~openlp.core.utils.ActionCategory` class encapsulates a @@ -173,6 +175,7 @@ class ActionList(object): """ def __init__(self): self.categories = CategoryList() + self.signal = Emit() def add_action(self, action, category=u'Default', weight=None): if category not in self.categories: @@ -181,3 +184,11 @@ class ActionList(object): self.categories[category].actions.append(action) else: self.categories[category].actions.add(action, weight) + self.signal.emit(QtCore.SIGNAL(u'addedAction()')) + + +class Emit(QtCore.QObject): + def __init__(self): + QtCore.QObject.__init__(self) + +actionList = ActionList() diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index db0ba3b7e..2d22d2d5a 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 +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 @@ -58,9 +60,9 @@ 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') + actionList.add_action(self.toolsAlertItem, u'Extra') self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert')) self.toolsAlertItem.setStatusTip( translate('AlertsPlugin', 'Show an alert message.'))