diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index fa704752e..37265f3d1 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -51,6 +51,7 @@ from advancedtab import AdvancedTab from aboutform import AboutForm from pluginform import PluginForm from settingsform import SettingsForm +from shortcutlistform import ShortcutListForm from mediadockmanager import MediaDockManager from servicemanager import ServiceManager from thememanager import ThemeManager diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index a8f3547d9..365e123d7 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -29,10 +29,12 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ - ThemeManager, SlideController, PluginForm, MediaDockManager + ThemeManager, SlideController, PluginForm, MediaDockManager, \ + ShortcutListForm from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \ SettingsManager, PluginManager, Receiver, translate -from openlp.core.utils import AppLocation, add_actions, LanguageManager +from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ + ActionList log = logging.getLogger(__name__) @@ -99,6 +101,12 @@ class Ui_MainWindow(object): self.screens) self.LiveController = SlideController(self, self.settingsmanager, self.screens, True) + previewVisible = QtCore.QSettings().value( + u'user interface/preview panel', QtCore.QVariant(True)).toBool() + self.PreviewController.Panel.setVisible(previewVisible) + liveVisible = QtCore.QSettings().value(u'user interface/live panel', + QtCore.QVariant(True)).toBool() + self.LiveController.Panel.setVisible(liveVisible) # Create menu self.MenuBar = QtGui.QMenuBar(MainWindow) self.MenuBar.setGeometry(QtCore.QRect(0, 0, 1087, 27)) @@ -178,29 +186,34 @@ class Ui_MainWindow(object): self.FileNewItem = QtGui.QAction(MainWindow) self.FileNewItem.setIcon(build_icon(u':/general/general_new.png')) self.FileNewItem.setObjectName(u'FileNewItem') + MainWindow.actionList.add_action(self.FileNewItem, u'File') self.FileOpenItem = QtGui.QAction(MainWindow) self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png')) self.FileOpenItem.setObjectName(u'FileOpenItem') + MainWindow.actionList.add_action(self.FileOpenItem, u'File') self.FileSaveItem = QtGui.QAction(MainWindow) self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png')) self.FileSaveItem.setObjectName(u'FileSaveItem') + MainWindow.actionList.add_action(self.FileSaveItem, u'File') self.FileSaveAsItem = QtGui.QAction(MainWindow) self.FileSaveAsItem.setObjectName(u'FileSaveAsItem') + MainWindow.actionList.add_action(self.FileSaveAsItem, u'File') self.FileExitItem = QtGui.QAction(MainWindow) self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png')) self.FileExitItem.setObjectName(u'FileExitItem') + MainWindow.actionList.add_action(self.FileExitItem, u'File') self.ImportThemeItem = QtGui.QAction(MainWindow) self.ImportThemeItem.setObjectName(u'ImportThemeItem') + MainWindow.actionList.add_action(self.ImportThemeItem, u'Import') self.ImportLanguageItem = QtGui.QAction(MainWindow) self.ImportLanguageItem.setObjectName(u'ImportLanguageItem') + MainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') self.ExportThemeItem = QtGui.QAction(MainWindow) self.ExportThemeItem.setObjectName(u'ExportThemeItem') + MainWindow.actionList.add_action(self.ExportThemeItem, u'Export') self.ExportLanguageItem = QtGui.QAction(MainWindow) self.ExportLanguageItem.setObjectName(u'ExportLanguageItem') - self.SettingsConfigureItem = QtGui.QAction(MainWindow) - self.SettingsConfigureItem.setIcon( - build_icon(u':/system/system_settings.png')) - self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem') + MainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') self.ViewMediaManagerItem = QtGui.QAction(MainWindow) self.ViewMediaManagerItem.setCheckable(True) self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible()) @@ -213,6 +226,7 @@ class Ui_MainWindow(object): self.ViewThemeManagerItem.setIcon( build_icon(u':/system/system_thememanager.png')) self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem') + MainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') self.ViewServiceManagerItem = QtGui.QAction(MainWindow) self.ViewServiceManagerItem.setCheckable(True) self.ViewServiceManagerItem.setChecked( @@ -220,28 +234,48 @@ class Ui_MainWindow(object): self.ViewServiceManagerItem.setIcon( build_icon(u':/system/system_servicemanager.png')) self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem') + MainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') + self.ViewPreviewPanel = QtGui.QAction(MainWindow) + self.ViewPreviewPanel.setCheckable(True) + self.ViewPreviewPanel.setChecked(previewVisible) + self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel') + MainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') + self.ViewLivePanel = QtGui.QAction(MainWindow) + self.ViewLivePanel.setCheckable(True) + self.ViewLivePanel.setChecked(liveVisible) + self.ViewLivePanel.setObjectName(u'ViewLivePanel') + MainWindow.actionList.add_action(self.ViewLivePanel, u'View') + self.ModeDefaultItem = QtGui.QAction(MainWindow) + self.ModeDefaultItem.setCheckable(True) + self.ModeDefaultItem.setObjectName(u'ModeDefaultItem') + MainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') + self.ModeSetupItem = QtGui.QAction(MainWindow) + self.ModeSetupItem.setCheckable(True) + self.ModeSetupItem.setObjectName(u'ModeLiveItem') + MainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') + self.ModeLiveItem = QtGui.QAction(MainWindow) + self.ModeLiveItem.setCheckable(True) + self.ModeLiveItem.setObjectName(u'ModeLiveItem') + MainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode') + self.ModeGroup = QtGui.QActionGroup(MainWindow) + self.ModeGroup.addAction(self.ModeDefaultItem) + self.ModeGroup.addAction(self.ModeSetupItem) + self.ModeGroup.addAction(self.ModeLiveItem) + self.ModeDefaultItem.setChecked(True) + self.ToolsAddToolItem = QtGui.QAction(MainWindow) + self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) + self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') + MainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') self.SettingsPluginListItem = QtGui.QAction(MainWindow) self.SettingsPluginListItem.setIcon( build_icon(u':/system/settings_plugin_list.png')) self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem') - self.HelpDocumentationItem = QtGui.QAction(MainWindow) - self.HelpDocumentationItem.setIcon( - build_icon(u':/system/system_help_contents.png')) - self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem') - self.HelpDocumentationItem.setEnabled(False) - self.HelpAboutItem = QtGui.QAction(MainWindow) - self.HelpAboutItem.setIcon( - build_icon(u':/system/system_about.png')) - self.HelpAboutItem.setObjectName(u'HelpAboutItem') - self.HelpOnlineHelpItem = QtGui.QAction(MainWindow) - self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem') - self.HelpOnlineHelpItem.setEnabled(False) - self.HelpWebSiteItem = QtGui.QAction(MainWindow) - self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem') + MainWindow.actionList.add_action(self.SettingsPluginListItem, u'Settings') #i18n Language Items self.AutoLanguageItem = QtGui.QAction(MainWindow) self.AutoLanguageItem.setObjectName(u'AutoLanguageItem') self.AutoLanguageItem.setCheckable(True) + MainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') self.LanguageGroup = QtGui.QActionGroup(MainWindow) qmList = LanguageManager.get_qm_list() savedLanguage = LanguageManager.get_language() @@ -254,37 +288,33 @@ class Ui_MainWindow(object): languageItem.setChecked(True) add_actions(self.LanguageGroup, [languageItem]) self.LanguageGroup.setDisabled(LanguageManager.auto_language) - self.ToolsAddToolItem = QtGui.QAction(MainWindow) - self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) - self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') - self.ViewPreviewPanel = QtGui.QAction(MainWindow) - self.ViewPreviewPanel.setCheckable(True) - previewVisible = QtCore.QSettings().value( - u'user interface/preview panel', QtCore.QVariant(True)).toBool() - self.ViewPreviewPanel.setChecked(previewVisible) - self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel') - self.PreviewController.Panel.setVisible(previewVisible) - self.ViewLivePanel = QtGui.QAction(MainWindow) - self.ViewLivePanel.setCheckable(True) - liveVisible = QtCore.QSettings().value(u'user interface/live panel', - QtCore.QVariant(True)).toBool() - self.ViewLivePanel.setChecked(liveVisible) - self.ViewLivePanel.setObjectName(u'ViewLivePanel') - self.LiveController.Panel.setVisible(liveVisible) - self.ModeDefaultItem = QtGui.QAction(MainWindow) - self.ModeDefaultItem.setCheckable(True) - self.ModeDefaultItem.setObjectName(u'ModeDefaultItem') - self.ModeSetupItem = QtGui.QAction(MainWindow) - self.ModeSetupItem.setCheckable(True) - self.ModeSetupItem.setObjectName(u'ModeLiveItem') - self.ModeLiveItem = QtGui.QAction(MainWindow) - self.ModeLiveItem.setCheckable(True) - self.ModeLiveItem.setObjectName(u'ModeLiveItem') - self.ModeGroup = QtGui.QActionGroup(MainWindow) - self.ModeGroup.addAction(self.ModeDefaultItem) - self.ModeGroup.addAction(self.ModeSetupItem) - self.ModeGroup.addAction(self.ModeLiveItem) - self.ModeDefaultItem.setChecked(True) + self.SettingsShortcutsItem = QtGui.QAction(MainWindow) + self.SettingsShortcutsItem.setIcon( + build_icon(u':/system/system_configure_shortcuts.png')) + self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem') + self.SettingsConfigureItem = QtGui.QAction(MainWindow) + self.SettingsConfigureItem.setIcon( + build_icon(u':/system/system_settings.png')) + self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem') + MainWindow.actionList.add_action(self.SettingsShortcutsItem, u'Settings') + self.HelpDocumentationItem = QtGui.QAction(MainWindow) + self.HelpDocumentationItem.setIcon( + build_icon(u':/system/system_help_contents.png')) + self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem') + self.HelpDocumentationItem.setEnabled(False) + MainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') + self.HelpAboutItem = QtGui.QAction(MainWindow) + self.HelpAboutItem.setIcon( + build_icon(u':/system/system_about.png')) + self.HelpAboutItem.setObjectName(u'HelpAboutItem') + MainWindow.actionList.add_action(self.HelpAboutItem, u'Help') + self.HelpOnlineHelpItem = QtGui.QAction(MainWindow) + self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem') + self.HelpOnlineHelpItem.setEnabled(False) + MainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') + self.HelpWebSiteItem = QtGui.QAction(MainWindow) + self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem') + MainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help') add_actions(self.FileImportMenu, (self.ImportThemeItem, self.ImportLanguageItem)) add_actions(self.FileExportMenu, @@ -304,7 +334,7 @@ class Ui_MainWindow(object): add_actions(self.SettingsLanguageMenu, self.LanguageGroup.actions()) add_actions(self.SettingsMenu, (self.SettingsPluginListItem, self.SettingsLanguageMenu.menuAction(), None, - self.SettingsConfigureItem)) + self.SettingsShortcutsItem, self.SettingsConfigureItem)) add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None)) add_actions(self.HelpMenu, @@ -395,6 +425,8 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', '&Theme')) self.ExportLanguageItem.setText( translate('OpenLP.MainWindow', '&Language')) + self.SettingsShortcutsItem.setText( + translate('OpenLP.MainWindow', 'Configure &Shortcuts...')) self.SettingsConfigureItem.setText( translate('OpenLP.MainWindow', '&Configure OpenLP...')) self.ViewMediaManagerItem.setText( @@ -489,6 +521,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ log.info(u'MainWindow loaded') + actionList = ActionList() + def __init__(self, screens, applicationVersion): """ This constructor sets up the interface, the various managers, and the @@ -496,6 +530,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ QtGui.QMainWindow.__init__(self) self.screens = screens + self.actionList = ActionList() self.applicationVersion = applicationVersion # Set up settings sections for the main application # (not for use by plugins) @@ -507,6 +542,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.settingsmanager = SettingsManager(screens) self.aboutForm = AboutForm(self, applicationVersion) self.settingsForm = SettingsForm(self.screens, self, self) + self.shortcutForm = ShortcutListForm(self) self.recentFiles = QtCore.QStringList() # Set up the path with plugins pluginpath = AppLocation.get_directory(AppLocation.PluginsDir) @@ -552,7 +588,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(self.SettingsPluginListItem, QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked) QtCore.QObject.connect(self.SettingsConfigureItem, - QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked) + 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.onNewService) QtCore.QObject.connect(self.FileOpenItem, @@ -713,12 +751,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.pluginForm.load() self.pluginForm.exec_() - def onOptionsSettingsItemClicked(self): + def onSettingsConfigureItemClicked(self): """ Show the Settings dialog """ self.settingsForm.exec_() + def onSettingsShortcutsItemClicked(self): + """ + Show the shortcuts dialog + """ + self.shortcutForm.exec_(self.actionList) + def onModeDefaultItemClicked(self): """ Put OpenLP into "Default" view mode. diff --git a/openlp/core/ui/shortcutlistdialog.py b/openlp/core/ui/shortcutlistdialog.py new file mode 100644 index 000000000..d64f4e2fc --- /dev/null +++ b/openlp/core/ui/shortcutlistdialog.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import translate, build_icon + +class Ui_ShortcutListDialog(object): + def setupUi(self, shortcutListDialog): + shortcutListDialog.setObjectName(u'shortcutListDialog') + shortcutListDialog.resize(500, 438) + self.shortcutListLayout = QtGui.QVBoxLayout(shortcutListDialog) + self.shortcutListLayout.setSpacing(8) + self.shortcutListLayout.setMargin(8) + self.shortcutListLayout.setObjectName(u'shortcutListLayout') + self.shortcutListTreeWidget = QtGui.QTreeWidget(shortcutListDialog) + self.shortcutListTreeWidget.setAlternatingRowColors(True) + self.shortcutListTreeWidget.setObjectName(u'shortcutListTreeWidget') + self.shortcutListTreeWidget.setColumnCount(2) + self.shortcutListTreeWidget.setSelectionBehavior( + QtGui.QAbstractItemView.SelectRows) + self.shortcutListLayout.addWidget(self.shortcutListTreeWidget) + self.shortcutLayout = QtGui.QVBoxLayout() + self.shortcutLayout.setSpacing(8) + self.shortcutLayout.setContentsMargins(0, -1, -1, -1) + self.shortcutLayout.setObjectName(u'shortcutLayout') + self.defaultRadioButton = QtGui.QRadioButton(shortcutListDialog) + self.defaultRadioButton.setChecked(True) + self.defaultRadioButton.setObjectName(u'defaultRadioButton') + self.shortcutLayout.addWidget(self.defaultRadioButton) + self.customShortcutLayout = QtGui.QHBoxLayout() + self.customShortcutLayout.setSpacing(8) + self.customShortcutLayout.setObjectName(u'customShortcutLayout') + self.customRadioButton = QtGui.QRadioButton(shortcutListDialog) + self.customRadioButton.setObjectName(u'customRadioButton') + self.customShortcutLayout.addWidget(self.customRadioButton) + self.shortcutPushButton = QtGui.QPushButton(shortcutListDialog) + self.shortcutPushButton.setMinimumSize(QtCore.QSize(84, 0)) + self.shortcutPushButton.setIcon( + build_icon(u':/system/system_configure_shortcuts.png')) + self.shortcutPushButton.setCheckable(True) + self.shortcutPushButton.setChecked(False) + self.shortcutPushButton.setObjectName(u'shortcutPushButton') + self.customShortcutLayout.addWidget(self.shortcutPushButton) + self.clearShortcutToolButton = QtGui.QToolButton(shortcutListDialog) + self.clearShortcutToolButton.setMinimumSize(QtCore.QSize(0, 16)) + self.clearShortcutToolButton.setText(u'') + self.clearShortcutToolButton.setIcon( + build_icon(u':/system/clear_shortcut.png')) + self.clearShortcutToolButton.setObjectName(u'clearShortcutToolButton') + self.customShortcutLayout.addWidget(self.clearShortcutToolButton) + self.customShortcutSpacer = QtGui.QSpacerItem(40, 20, + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.customShortcutLayout.addItem(self.customShortcutSpacer) + self.shortcutLayout.addLayout(self.customShortcutLayout) + self.shortcutListLayout.addLayout(self.shortcutLayout) + self.shortcutListButtonBox = QtGui.QDialogButtonBox(shortcutListDialog) + self.shortcutListButtonBox.setOrientation(QtCore.Qt.Horizontal) + self.shortcutListButtonBox.setStandardButtons( + QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok | + QtGui.QDialogButtonBox.Reset) + self.shortcutListButtonBox.setObjectName(u'shortcutListButtonBox') + self.shortcutListLayout.addWidget(self.shortcutListButtonBox) + + self.retranslateUi(shortcutListDialog) + QtCore.QObject.connect( + self.shortcutListButtonBox, + QtCore.SIGNAL(u'accepted()'), + shortcutListDialog.accept + ) + QtCore.QObject.connect( + self.shortcutListButtonBox, + QtCore.SIGNAL(u'rejected()'), + shortcutListDialog.reject + ) + QtCore.QMetaObject.connectSlotsByName(shortcutListDialog) + + def retranslateUi(self, shortcutListDialog): + shortcutListDialog.setWindowTitle( + translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts')) + self.shortcutListTreeWidget.setHeaderLabels([ + translate('OpenLP.ShortcutListDialog', 'Action'), + translate('OpenLP.ShortcutListDialog', 'Shortcut') + ]) + self.defaultRadioButton.setText( + translate('OpenLP.ShortcutListDialog', 'Default: %s')) + self.customRadioButton.setText( + translate('OpenLP.ShortcutListDialog', 'Custom:')) + self.shortcutPushButton.setText( + translate('OpenLP.ShortcutListDialog', 'None')) + diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py new file mode 100644 index 000000000..0316b0ee0 --- /dev/null +++ b/openlp/core/ui/shortcutlistform.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +import logging +import re + +from PyQt4 import QtCore, QtGui + +from openlp.core.utils import translate +from shortcutlistdialog import Ui_ShortcutListDialog + +REMOVE_AMPERSAND = re.compile(r'&{1}') + +log = logging.getLogger(__name__) + +class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): + """ + The shortcut list dialog + """ + + def __init__(self, parent): + """ + Do some initialisation stuff + """ + QtGui.QDialog.__init__(self, parent) + self.setupUi(self) + self.actionList = None + self.captureShortcut = False + QtCore.QObject.connect( + self.shortcutPushButton, + QtCore.SIGNAL(u'toggled(bool)'), + self.onShortcutPushButtonClicked + ) + + def keyReleaseEvent(self, event): + Qt = QtCore.Qt + if not self.captureShortcut: + return + key = event.key() + if key == Qt.Key_Shift or key == Qt.Key_Control or \ + key == Qt.Key_Meta or key == Qt.Key_Alt: + return + key_string = QtGui.QKeySequence(key).toString() + if event.modifiers() & Qt.ControlModifier == Qt.ControlModifier: + key_string = u'Ctrl+' + key_string + if event.modifiers() & Qt.AltModifier == Qt.AltModifier: + key_string = u'Alt+' + key_string + if event.modifiers() & Qt.ShiftModifier == Qt.ShiftModifier: + key_string = u'Shift+' + key_string; + key_sequence = QtGui.QKeySequence(key_string) + existing_key = QtGui.QKeySequence("Ctrl+Shift+F8") + if key_sequence == existing_key: + 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(), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), + QtGui.QMessageBox.Ok + ) + else: + self.shortcutPushButton.setText(key_sequence.toString()) + self.shortcutPushButton.setChecked(False) + self.captureShortcut = False + + def exec_(self, actionList): + self.actionList = actionList + self.refreshActions() + return QtGui.QDialog.exec_(self) + + def refreshActions(self): + self.shortcutListTreeWidget.clear() + for category in self.actionList.categories: + item = QtGui.QTreeWidgetItem([category.name]) + for action in category.actions: + actionText = REMOVE_AMPERSAND.sub('', unicode(action.text())) + shortcutText = action.shortcut().toString() + actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText]) + actionItem.setIcon(0, action.icon()) + item.addChild(actionItem) + item.setExpanded(True) + self.shortcutListTreeWidget.addTopLevelItem(item) + + def onShortcutPushButtonClicked(self, toggled): + self.captureShortcut = toggled + diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 119bf6b55..23f77291c 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -276,6 +276,7 @@ def get_images_filter(): return images_filter 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'get_filesystem_encoding', u'LanguageManager', u'ActionList'] diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py new file mode 100644 index 000000000..893e4adba --- /dev/null +++ b/openlp/core/utils/actions.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`~openlp.core.utils.actions` module provides action list classes used +by the shortcuts system. +""" + +class ActionCategory(object): + """ + The :class:`~openlp.core.utils.ActionCategory` class encapsulates a + category for the :class:`~openlp.core.utils.CategoryList` class. + """ + def __init__(self, name, weight=0): + self.name = name + self.weight = weight + self.actions = CategoryActionList() + + +class CategoryActionList(object): + """ + The :class:`~openlp.core.utils.CategoryActionList` class provides a sorted + list of actions within a category. + """ + def __init__(self): + self.index = 0 + self.actions = [] + + def __getitem__(self, key): + for weight, action in self.actions: + if action.text() == key: + return action + raise KeyError(u'Action "%s" does not exist.' % key) + + def __contains__(self, item): + return self.has_key(item) + + def __len__(self): + return len(self.actions) + + def __iter__(self): + return self + + def __next__(self): + """ + Python 3 "next" method. + """ + if self.index >= len(self.actions): + raise StopIteration + else: + self.index += 1 + return self.actions[self.index - 1][1] + + def next(self): + """ + Python 2 "next" method. + """ + return self.__next__() + + def has_key(key): + for weight, action in self.actions: + if action.text() == key: + return True + return False + + def append(self, name): + weight = 0 + if len(self.actions) > 0: + weight = self.actions[-1][0] + 1 + self.add(name, weight) + + def add(self, action, weight=0): + self.actions.append((weight, action)) + self.actions.sort(key=lambda act: act[0]) + + +class CategoryList(object): + """ + The :class:`~openlp.core.utils.CategoryList` class encapsulates a category + list for the :class:`~openlp.core.utils.ActionList` class and provides an + iterator interface for walking through the list of actions in this category. + """ + + def __init__(self): + self.index = 0 + self.categories = [] + + def __getitem__(self, key): + for category in self.categories: + if category.name == key: + return category + raise KeyError(u'Category "%s" does not exist.' % key) + + def __contains__(self, item): + return self.has_key(item) + + def __len__(self): + return len(self.categories) + + def __iter__(self): + return self + + def __next__(self): + """ + Python 3 "next" method for iterator. + """ + if self.index >= len(self.categories): + raise StopIteration + else: + self.index += 1 + return self.categories[self.index - 1] + + def next(self): + """ + Python 2 "next" method for iterator. + """ + return self.__next__() + + def has_key(self, key): + for category in self.categories: + if category.name == key: + return True + return False + + def append(self, name, actions=[]): + weight = 0 + if len(self.categories) > 0: + weight = self.categories[-1].weight + 1 + if actions: + self.add(name, weight, actions) + else: + self.add(name, weight) + + def add(self, name, weight=0, actions=[]): + category = ActionCategory(name, weight) + if actions: + for action in actions: + if isinstance(action, tuple): + category.actions.add(action[0], action[1]) + else: + category.actions.append(action) + self.categories.append(category) + self.categories.sort(key=lambda cat: cat.weight) + + +class ActionList(object): + """ + The :class:`~openlp.core.utils.ActionList` class contains a list of menu + actions and categories associated with those actions. Each category also + has a weight by which it is sorted when iterating through the list of + actions or categories. + """ + def __init__(self): + self.categories = CategoryList() + + def add_action(self, action, category=u'Default', weight=None): + if category not in self.categories: + self.categories.append(category) + if weight is None: + self.categories[category].actions.append(action) + else: + self.categories[category].actions.add(action, weight) diff --git a/resources/forms/shortcutlistdialog.ui b/resources/forms/shortcutlistdialog.ui new file mode 100644 index 000000000..519925560 --- /dev/null +++ b/resources/forms/shortcutlistdialog.ui @@ -0,0 +1,179 @@ + + + ShortcutListDialog + + + + 0 + 0 + 500 + 438 + + + + Dialog + + + + 8 + + + 8 + + + + + true + + + false + + + + Action + + + + + Shortcut + + + + + + + + 8 + + + 0 + + + + + Default: None + + + true + + + + + + + 8 + + + + + Custom: + + + + + + + + 84 + 0 + + + + None + + + + :/system/system_settings.png:/system/system_settings.png + + + true + + + false + + + + + + + + 0 + 16 + + + + + + + + :/system/clear_shortcut.png:/system/clear_shortcut.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset + + + + + + + + + + + shortcutListButtonBox + accepted() + ShortcutListDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + shortcutListButtonBox + rejected() + ShortcutListDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/resources/images/clear_shortcut.png b/resources/images/clear_shortcut.png new file mode 100644 index 000000000..6c4b83b7a Binary files /dev/null and b/resources/images/clear_shortcut.png differ diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index 78d74cf7e..7e8645441 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -92,6 +92,7 @@ system_close.png + clear_shortcut.png system_about.png system_help_contents.png system_mediamanager.png @@ -101,6 +102,7 @@ system_exit.png settings_plugin_list.png system_settings.png + system_configure_shortcuts.png media_time.png diff --git a/resources/images/system_configure_shortcuts.png b/resources/images/system_configure_shortcuts.png new file mode 100644 index 000000000..6d9ef70af Binary files /dev/null and b/resources/images/system_configure_shortcuts.png differ