[kde-doc-english] [calligra] krita: Make the canvas input configurable
Arjen Hiemstra
ahiemstra at heimr.nl
Fri Jul 5 17:32:01 UTC 2013
Git commit 122d35ffb499f89429efb96f38a03961132bb7d4 by Arjen Hiemstra.
Committed on 05/07/2013 at 14:41.
Pushed by ahiemstra into branch 'master'.
Make the canvas input configurable
This adds a page to the preferences dialog that allows you to select a
profile and configure the input for that profile.
BUG: 298714
BUG: 298462
BUG: 302478
BUG: 317201
FIXED-IN: 2.8
REVIEW: 111391
GUI: Added a new "Canvas Input Settings" page.
DIGEST: Krita's canva input is now configurable.
M +1 -0 krita/data/CMakeLists.txt
A +4 -0 krita/data/input/CMakeLists.txt
A +45 -0 krita/data/input/kritadefault.profile
M +21 -0 krita/ui/CMakeLists.txt
M +10 -0 krita/ui/dialogs/kis_dlg_preferences.cc
M +2 -0 krita/ui/dialogs/kis_dlg_preferences.h
A +334 -0 krita/ui/input/config/kis_action_shortcuts_model.cpp [License: GPL (v2+)]
A +122 -0 krita/ui/input/config/kis_action_shortcuts_model.h [License: GPL (v2+)]
A +88 -0 krita/ui/input/config/kis_edit_profiles_dialog.cpp [License: GPL (v2+)]
A +48 -0 krita/ui/input/config/kis_edit_profiles_dialog.h [License: GPL (v2+)]
A +88 -0 krita/ui/input/config/kis_edit_profiles_dialog.ui
A +230 -0 krita/ui/input/config/kis_input_button.cpp [License: GPL (v2+)]
A +143 -0 krita/ui/input/config/kis_input_button.h [License: GPL (v2+)]
A +92 -0 krita/ui/input/config/kis_input_configuration_page.cpp [License: GPL (v2+)]
A +54 -0 krita/ui/input/config/kis_input_configuration_page.h [License: GPL (v2+)]
A +100 -0 krita/ui/input/config/kis_input_configuration_page.ui
A +86 -0 krita/ui/input/config/kis_input_configuration_page_item.cpp [License: GPL (v2+)]
A +60 -0 krita/ui/input/config/kis_input_configuration_page_item.h [License: GPL (v2+)]
A +94 -0 krita/ui/input/config/kis_input_configuration_page_item.ui
A +146 -0 krita/ui/input/config/kis_input_editor_delegate.cpp [License: GPL (v2+)]
A +46 -0 krita/ui/input/config/kis_input_editor_delegate.h [License: GPL (v2+)]
A +80 -0 krita/ui/input/config/kis_input_mode_delegate.cpp [License: GPL (v2+)]
A +48 -0 krita/ui/input/config/kis_input_mode_delegate.h [License: GPL (v2+)]
A +64 -0 krita/ui/input/config/kis_input_profile_model.cpp [License: GPL (v2+)]
A +44 -0 krita/ui/input/config/kis_input_profile_model.h [License: GPL (v2+)]
A +75 -0 krita/ui/input/config/kis_input_type_delegate.cpp [License: GPL (v2+)]
A +45 -0 krita/ui/input/config/kis_input_type_delegate.h [License: GPL (v2+)]
A +77 -0 krita/ui/input/config/kis_key_input_editor.cpp [License: GPL (v2+)]
A +54 -0 krita/ui/input/config/kis_key_input_editor.h [License: GPL (v2+)]
A +95 -0 krita/ui/input/config/kis_key_input_editor.ui
A +100 -0 krita/ui/input/config/kis_mouse_input_editor.cpp [License: GPL (v2+)]
A +54 -0 krita/ui/input/config/kis_mouse_input_editor.h [License: GPL (v2+)]
A +138 -0 krita/ui/input/config/kis_mouse_input_editor.ui
A +99 -0 krita/ui/input/config/kis_wheel_input_editor.cpp [License: GPL (v2+)]
A +56 -0 krita/ui/input/config/kis_wheel_input_editor.h [License: GPL (v2+)]
A +138 -0 krita/ui/input/config/kis_wheel_input_editor.ui
M +11 -5 krita/ui/input/kis_abstract_input_action.cpp
M +4 -1 krita/ui/input/kis_abstract_input_action.h
M +2 -3 krita/ui/input/kis_alternate_invocation_action.cpp
M +1 -1 krita/ui/input/kis_alternate_invocation_action.h
M +3 -4 krita/ui/input/kis_change_primary_setting_action.cpp
M +1 -1 krita/ui/input/kis_change_primary_setting_action.h
M +104 -89 krita/ui/input/kis_input_manager.cpp
M +1 -0 krita/ui/input/kis_input_manager.h
A +86 -0 krita/ui/input/kis_input_profile.cpp [License: GPL (v2+)]
A +95 -0 krita/ui/input/kis_input_profile.h [License: GPL (v2+)]
A +287 -0 krita/ui/input/kis_input_profile_manager.cpp [License: GPL (v2+)]
A +141 -0 krita/ui/input/kis_input_profile_manager.h [License: GPL (v2+)]
M +3 -2 krita/ui/input/kis_pan_action.cpp
M +1 -1 krita/ui/input/kis_pan_action.h
M +4 -2 krita/ui/input/kis_rotate_canvas_action.cpp
M +1 -1 krita/ui/input/kis_rotate_canvas_action.h
A +349 -0 krita/ui/input/kis_shortcut_configuration.cpp [License: GPL (v2+)]
A +261 -0 krita/ui/input/kis_shortcut_configuration.h [License: GPL (v2+)]
M +8 -0 krita/ui/input/kis_shortcut_matcher.cpp
M +5 -0 krita/ui/input/kis_shortcut_matcher.h
M +2 -2 krita/ui/input/kis_show_palette_action.cpp
M +1 -1 krita/ui/input/kis_show_palette_action.h
M +3 -1 krita/ui/input/kis_single_action_shortcut.h
M +10 -4 krita/ui/input/kis_tool_invocation_action.cpp
M +1 -1 krita/ui/input/kis_tool_invocation_action.h
M +3 -2 krita/ui/input/kis_zoom_action.cpp
M +1 -1 krita/ui/input/kis_zoom_action.h
M +9 -0 krita/ui/kis_config.cc
M +3 -0 krita/ui/kis_config.h
M +3 -0 krita/ui/kis_view2.cpp
M +1 -1 krita/ui/tests/kis_input_manager_test.cpp
http://commits.kde.org/calligra/122d35ffb499f89429efb96f38a03961132bb7d4
diff --git a/krita/data/CMakeLists.txt b/krita/data/CMakeLists.txt
index 7b73e52..2b85ff4 100644
--- a/krita/data/CMakeLists.txt
+++ b/krita/data/CMakeLists.txt
@@ -9,6 +9,7 @@ add_subdirectory( cursors )
add_subdirectory( workspaces )
add_subdirectory( themes )
add_subdirectory( predefined_image_sizes )
+add_subdirectory( input )
########### install files ###############
install( FILES
diff --git a/krita/data/input/CMakeLists.txt b/krita/data/input/CMakeLists.txt
new file mode 100644
index 0000000..65bbaad
--- /dev/null
+++ b/krita/data/input/CMakeLists.txt
@@ -0,0 +1,4 @@
+install(FILES
+ kritadefault.profile
+ DESTINATION ${DATA_INSTALL_DIR}/krita/input
+)
diff --git a/krita/data/input/kritadefault.profile b/krita/data/input/kritadefault.profile
new file mode 100644
index 0000000..e81013c
--- /dev/null
+++ b/krita/data/input/kritadefault.profile
@@ -0,0 +1,45 @@
+[Alternate Invocation]
+0={1;2;[1000021,1000023];1;0;0}
+1={0;2;[1000021];1;0;0}
+
+[Change Primary Setting]
+0={0;2;[1000020];1;0;0}
+
+[General]
+name=Krita Default
+
+[Pan Canvas]
+0={4;1;[1000015];0;0;0}
+1={3;1;[1000013];0;0;0}
+2={2;1;[1000014];0;0;0}
+3={1;1;[1000012];0;0;0}
+4={0;2;[];4;0;0}
+5={0;2;[20];1;0;0}
+
+[Rotate Canvas]
+0={3;1;[36];0;0;0}
+1={4;1;[35];0;0;0}
+2={2;1;[34];0;0;0}
+3={0;2;[1000020];4;0;0}
+4={0;2;[1000020,1000023,20];1;0;0}
+5={0;2;[1000020,20];1;0;0}
+
+[Show Popup Palette]
+0={0;2;[];2;0;0}
+
+[Tool Invocation]
+0={0;2;[];1;0;0}
+1={1;1;[1000004];0;0;0}
+2={2;1;[1000000];0;0;0}
+
+[Zoom Canvas]
+0={6;1;[33];0;0;0}
+1={5;1;[32];0;0;0}
+2={4;1;[31];0;0;0}
+3={3;1;[2d];0;0;0}
+4={2;1;[3d];0;0;0}
+5={3;3;[];0;2;0}
+6={2;3;[];0;1;0}
+7={0;2;[1000021];4;0;0}
+8={1;2;[1000021,1000023,20];1;0;0}
+9={0;2;[1000021,20];1;0;0}
diff --git a/krita/ui/CMakeLists.txt b/krita/ui/CMakeLists.txt
index 6040839..f1a1bf3 100644
--- a/krita/ui/CMakeLists.txt
+++ b/krita/ui/CMakeLists.txt
@@ -222,6 +222,21 @@ set(kritaui_LIB_SRCS
actions/kis_selection_action_factories.cpp
kis_document_undo_store.cpp
kis_transaction_based_command.cpp
+ input/kis_input_profile_manager.cpp
+ input/kis_input_profile.cpp
+ input/kis_shortcut_configuration.cpp
+ input/config/kis_input_configuration_page.cpp
+ input/config/kis_edit_profiles_dialog.cpp
+ input/config/kis_input_profile_model.cpp
+ input/config/kis_input_configuration_page_item.cpp
+ input/config/kis_action_shortcuts_model.cpp
+ input/config/kis_input_type_delegate.cpp
+ input/config/kis_input_mode_delegate.cpp
+ input/config/kis_input_button.cpp
+ input/config/kis_input_editor_delegate.cpp
+ input/config/kis_mouse_input_editor.cpp
+ input/config/kis_wheel_input_editor.cpp
+ input/config/kis_key_input_editor.cpp
)
if(HAVE_OPENGL)
@@ -282,6 +297,12 @@ kde4_add_ui_files(kritaui_LIB_SRCS
forms/wdgpresetselectorstrip.ui
forms/wdgdlgblacklistcleanup.ui
forms/wdgflipbookselector.ui
+ input/config/kis_input_configuration_page.ui
+ input/config/kis_edit_profiles_dialog.ui
+ input/config/kis_input_configuration_page_item.ui
+ input/config/kis_mouse_input_editor.ui
+ input/config/kis_wheel_input_editor.ui
+ input/config/kis_key_input_editor.ui
)
kde4_add_library(kritaui SHARED ${kritaui_LIB_SRCS} )
diff --git a/krita/ui/dialogs/kis_dlg_preferences.cc b/krita/ui/dialogs/kis_dlg_preferences.cc
index a0bb001..ffa46dd 100644
--- a/krita/ui/dialogs/kis_dlg_preferences.cc
+++ b/krita/ui/dialogs/kis_dlg_preferences.cc
@@ -87,6 +87,8 @@
#include <kis_cubic_curve.h>
#include <config-ocio.h>
+#include "input/config/kis_input_configuration_page.h"
+
GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
: WdgGeneralSettings(_parent, _name)
@@ -677,6 +679,14 @@ KisDlgPreferences::KisDlgPreferences(QWidget* parent, const char* name)
page->setHeader(i18n("Author"));
page->setIcon(koIcon("user-identity"));
+ m_inputConfiguration = new KisInputConfigurationPage();
+ page = addPage(m_inputConfiguration, i18n("Canvas Input Settings"));
+ page->setHeader(i18n("Canvas Input"));
+ page->setIcon(koIcon("input-tablet"));
+ connect(this, SIGNAL(okClicked()), m_inputConfiguration, SLOT(saveChanges()));
+ connect(this, SIGNAL(applyClicked()), m_inputConfiguration, SLOT(saveChanges()));
+ connect(this, SIGNAL(cancelClicked()), m_inputConfiguration, SLOT(revertChanges()));
+ connect(this, SIGNAL(defaultClicked()), m_inputConfiguration, SLOT(setDefaults()));
KisPreferenceSetRegistry *preferenceSetRegistry = KisPreferenceSetRegistry::instance();
foreach (KisAbstractPreferenceSetFactory *preferenceSetFactory, preferenceSetRegistry->values()) {
diff --git a/krita/ui/dialogs/kis_dlg_preferences.h b/krita/ui/dialogs/kis_dlg_preferences.h
index ade1912..7a85260 100644
--- a/krita/ui/dialogs/kis_dlg_preferences.h
+++ b/krita/ui/dialogs/kis_dlg_preferences.h
@@ -38,6 +38,7 @@
class KoID;
class KoConfigAuthorPage;
+class KisInputConfigurationPage;
/**
* "General"-tab for preferences dialog
@@ -278,6 +279,7 @@ protected:
TabletSettingsTab *m_tabletSettings;
FullscreenSettingsTab *m_fullscreenSettings;
KoConfigAuthorPage *m_authorSettings;
+ KisInputConfigurationPage *m_inputConfiguration;
protected slots:
diff --git a/krita/ui/input/config/kis_action_shortcuts_model.cpp b/krita/ui/input/config/kis_action_shortcuts_model.cpp
new file mode 100644
index 0000000..8de11e8
--- /dev/null
+++ b/krita/ui/input/config/kis_action_shortcuts_model.cpp
@@ -0,0 +1,334 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_action_shortcuts_model.h"
+
+#include <KLocalizedString>
+#include <QMetaClassInfo>
+#include <QKeySequence>
+
+#include "KoIcon.h"
+
+#include "input/kis_abstract_input_action.h"
+#include "input/kis_input_profile.h"
+#include "input/kis_input_profile_manager.h"
+#include "input/kis_shortcut_configuration.h"
+
+class KisActionShortcutsModel::Private
+{
+public:
+ Private() : action(0), profile(0), temporaryShortcut(0) { }
+
+ KisAbstractInputAction *action;
+ KisInputProfile *profile;
+ QList<KisShortcutConfiguration *> shortcuts;
+
+ KisShortcutConfiguration *temporaryShortcut;
+};
+
+KisActionShortcutsModel::KisActionShortcutsModel(QObject *parent)
+ : QAbstractListModel(parent), d(new Private)
+{
+ connect(KisInputProfileManager::instance(), SIGNAL(currentProfileChanged()), SLOT(currentProfileChanged()));
+}
+
+KisActionShortcutsModel::~KisActionShortcutsModel()
+{
+}
+
+QVariant KisActionShortcutsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (index.row() == d->shortcuts.count() && role == Qt::DisplayRole) {
+ if (index.column() == 0) {
+ return i18n("Add shortcut...");
+ }
+ else {
+ return QVariant();
+ }
+ }
+
+ if (role == Qt::DisplayRole) {
+ switch (index.column()) {
+ case 0:
+ switch (d->shortcuts.at(index.row())->type()) {
+ case KisShortcutConfiguration::KeyCombinationType:
+ return i18nc("Shortcut type", "Key Combination");
+
+ case KisShortcutConfiguration::MouseButtonType:
+ return i18nc("Shortcut type", "Mouse Button");
+
+ case KisShortcutConfiguration::MouseWheelType:
+ return i18nc("Shortcut type", "Mouse Wheel");
+
+ case KisShortcutConfiguration::GestureType:
+ return i18nc("Shortcut type", "Gesture");
+
+ default:
+ return i18n("Unknown Input");
+ }
+
+ break;
+
+ case 1: {
+ KisShortcutConfiguration *s = d->shortcuts.at(index.row());
+ QString output;
+
+ switch (s->type()) {
+ case KisShortcutConfiguration::KeyCombinationType:
+ output = KisShortcutConfiguration::keysToText(s->keys());
+ break;
+
+ case KisShortcutConfiguration::MouseButtonType:
+ if (s->keys().size() > 0) {
+ output.append(KisShortcutConfiguration::keysToText(s->keys()));
+ output.append(" + ");
+ }
+
+ output.append(KisShortcutConfiguration::buttonsToText(s->buttons()));
+ break;
+
+ case KisShortcutConfiguration::MouseWheelType:
+ if (s->keys().size() > 0) {
+ output.append(KisShortcutConfiguration::keysToText(s->keys()));
+ output.append(" + ");
+ }
+
+ output.append(KisShortcutConfiguration::wheelToText(s->wheel()));
+ break;
+
+ default:
+ break;
+ }
+
+ return output;
+ }
+
+ case 2:
+ return d->action->shortcutIndexes().key(d->shortcuts.at(index.row())->mode());
+
+ case 3:
+ return koIcon("edit-delete");
+
+ default:
+ break;
+ }
+ }
+ else if (role == Qt::EditRole) {
+ KisShortcutConfiguration *s;
+
+ if (index.row() == d->shortcuts.count()) {
+ if (!d->temporaryShortcut) {
+ d->temporaryShortcut = new KisShortcutConfiguration;
+ }
+
+ s = d->temporaryShortcut;
+ }
+ else {
+ s = d->shortcuts.at(index.row());
+ }
+
+ switch (index.column()) {
+ case 0:
+ return s->type();
+
+ case 1:
+ return QVariant::fromValue(s);
+
+ case 2:
+ return s->mode();
+
+ default:
+ break;
+ }
+ }
+
+ return QVariant();
+}
+
+int KisActionShortcutsModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid()) {
+ return 0;
+ }
+
+ return d->shortcuts.count() + 1;
+}
+
+int KisActionShortcutsModel::columnCount(const QModelIndex & /*parent*/) const
+{
+ return 3;
+}
+
+QVariant KisActionShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation != Qt::Horizontal || role != Qt::DisplayRole) {
+ return QVariant();
+ }
+
+ switch (section) {
+ case 0:
+ return i18nc("Type of shortcut", "Type");
+
+ case 1:
+ return i18nc("Input for shortcut", "Input");
+
+ case 2:
+ return i18nc("Action to trigger with shortcut", "Action");
+
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+Qt::ItemFlags KisActionShortcutsModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid()) {
+ return Qt::ItemIsEnabled;
+ }
+
+ if (index.row() == d->shortcuts.count() && index.column() != 0) {
+ return Qt::ItemIsEnabled;
+ }
+
+ return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
+}
+
+bool KisActionShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid() || role != Qt::EditRole) {
+ return false;
+ }
+
+ if (index.row() == d->shortcuts.count()) {
+ if (!d->temporaryShortcut || (index.column() == 0 && value.toUInt() == 0)) {
+ return false;
+ }
+
+ beginInsertRows(QModelIndex(), d->shortcuts.count(), d->shortcuts.count());
+ d->temporaryShortcut->setAction(d->action);
+ d->profile->addShortcut(d->temporaryShortcut);
+ d->shortcuts.append(d->temporaryShortcut);
+ d->temporaryShortcut = 0;
+ endInsertRows();
+ }
+
+ switch (index.column()) {
+ case 0:
+ d->shortcuts.at(index.row())->setType(static_cast<KisShortcutConfiguration::ShortcutType>(value.toUInt()));
+ break;
+
+ case 1: {
+ KisShortcutConfiguration *newData = value.value<KisShortcutConfiguration *>();
+ KisShortcutConfiguration *oldData = d->shortcuts.at(index.row());
+
+ if (newData == oldData)
+ return true;
+
+ oldData->setKeys(newData->keys());
+ oldData->setButtons(newData->buttons());
+ oldData->setWheel(newData->wheel());
+ oldData->setGesture(newData->gesture());
+
+ break;
+ }
+
+ case 2:
+ d->shortcuts.at(index.row())->setMode(value.toUInt());
+ break;
+ }
+
+ return true;
+}
+
+KisAbstractInputAction *KisActionShortcutsModel::action() const
+{
+ return d->action;
+}
+
+void KisActionShortcutsModel::setAction(KisAbstractInputAction *action)
+{
+ if (action != d->action) {
+ if (d->action) {
+ beginRemoveRows(QModelIndex(), 0, d->shortcuts.count() - 1);
+ endRemoveRows();
+ }
+
+ d->action = action;
+
+ if (d->action && d->profile) {
+ d->shortcuts = d->profile->shortcutsForAction(d->action);
+ beginInsertRows(QModelIndex(), 0, d->shortcuts.count() - 1);
+ endInsertRows();
+ }
+ }
+}
+
+KisInputProfile *KisActionShortcutsModel::profile() const
+{
+ return d->profile;
+}
+
+void KisActionShortcutsModel::setProfile(KisInputProfile *profile)
+{
+ if (profile != d->profile) {
+ if (d->profile) {
+ beginRemoveRows(QModelIndex(), 0, d->shortcuts.count() - 1);
+ endRemoveRows();
+ }
+
+ d->profile = profile;
+
+ if (d->action && d->profile) {
+ d->shortcuts = d->profile->shortcutsForAction(d->action);
+ beginInsertRows(QModelIndex(), 0, d->shortcuts.count() - 1);
+ endInsertRows();
+ }
+ }
+}
+
+void KisActionShortcutsModel::currentProfileChanged()
+{
+ setProfile(KisInputProfileManager::instance()->currentProfile());
+}
+
+bool KisActionShortcutsModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ if (row < 0 || row >= d->shortcuts.count() || count == 0) {
+ return false;
+ }
+
+ beginRemoveRows(parent, row, row + count - 1);
+
+ for (int i = row; i < d->shortcuts.count() && count > 0; ++i, count--) {
+ KisShortcutConfiguration *s = d->shortcuts.at(i);
+ d->profile->removeShortcut(s);
+ d->shortcuts.removeOne(s);
+ delete s;
+ }
+
+ endRemoveRows();
+
+ return true;
+}
diff --git a/krita/ui/input/config/kis_action_shortcuts_model.h b/krita/ui/input/config/kis_action_shortcuts_model.h
new file mode 100644
index 0000000..546cd3b
--- /dev/null
+++ b/krita/ui/input/config/kis_action_shortcuts_model.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISACTIONSHORTCUTSMODEL_H
+#define KISACTIONSHORTCUTSMODEL_H
+
+#include <QAbstractListModel>
+
+class KisAbstractInputAction;
+class KisInputProfile;
+
+/**
+ * \brief A QAbstractListModel subclass that lists shortcuts associated with an action from a profile.
+ *
+ * This class lists all shortcuts from the set profile that correspond to a specific action. This is
+ * used to allow editing of shortcuts from the ui.
+ *
+ * It defines the following columns:
+ * - Type: The type of shortcut, can be one of Key Combination, Mouse Button, Mouse Wheel, Gesture
+ * - Input: What input is used to activate the shortcut. Depends on the type.
+ * - Action: What mode of the action will be activated by the shortcut.
+ *
+ * \note Before this model will provide any data you should call setAction and setProfile.
+ * \note This model is editable and provides an implementation of removeRows.
+ */
+class KisActionShortcutsModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructor.
+ */
+ explicit KisActionShortcutsModel(QObject *parent = 0);
+ /**
+ * Destructor.
+ */
+ ~KisActionShortcutsModel();
+
+ /**
+ * Reimplemented from QAbstractItemModel::data()
+ */
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ /**
+ * Reimplemented from QAbstractItemModel::rowCount()
+ */
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ /**
+ * Reimplemented from QAbstractItemModel::columnCount()
+ */
+ virtual int columnCount(const QModelIndex &) const;
+ /**
+ * Reimplemented from QAbstractItemModel::headerData()
+ */
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role =
+ Qt::DisplayRole) const;
+ /**
+ * Reimplemented from QAbstractItemModel::flags()
+ */
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ /**
+ * Reimplemented from QAbstractItemModel::setData()
+ */
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ /**
+ * Reimplemented from QAbstractItemModel::removeRows.
+ *
+ * Removes `count` rows starting at `row`.
+ *
+ * \note The associated shortcuts will also be removed from the profile and completely
+ * deleted.
+ */
+ virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ /**
+ * \return The action used as data constraint for this model.
+ */
+ KisAbstractInputAction *action() const;
+ /**
+ * \return The profile used as data source for this model.
+ */
+ KisInputProfile *profile() const;
+
+public Q_SLOTS:
+ /**
+ * Set the action used as data constraint for this model.
+ *
+ * \param action The action to use.
+ */
+ void setAction(KisAbstractInputAction *action);
+ /**
+ * Set the profile used as data source for this model.
+ *
+ * \param profile The profile to get the data from.
+ */
+ void setProfile(KisInputProfile *profile);
+
+private Q_SLOTS:
+ void currentProfileChanged();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISACTIONSHORTCUTSMODEL_H
diff --git a/krita/ui/input/config/kis_edit_profiles_dialog.cpp b/krita/ui/input/config/kis_edit_profiles_dialog.cpp
new file mode 100644
index 0000000..4982185
--- /dev/null
+++ b/krita/ui/input/config/kis_edit_profiles_dialog.cpp
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_edit_profiles_dialog.h"
+
+#include <QPushButton>
+#include <QStringListModel>
+#include <KLocalizedString>
+
+#include "KoIcon.h"
+#include "input/kis_input_profile_manager.h"
+#include "kis_input_profile_model.h"
+
+#include "ui_kis_edit_profiles_dialog.h"
+
+class KisEditProfilesDialog::Private
+{
+public:
+ Private() { }
+
+ Ui::KisEditProfilesDialog *ui;
+ KisInputProfileModel *profileModel;
+};
+
+KisEditProfilesDialog::KisEditProfilesDialog(QWidget *parent, Qt::WindowFlags flags)
+ : KDialog(parent, flags), d(new Private())
+{
+ QWidget *mainWidget = new QWidget(this);
+ d->ui = new Ui::KisEditProfilesDialog();
+ d->ui->setupUi(mainWidget);
+ setMainWidget(mainWidget);
+
+ d->profileModel = new KisInputProfileModel(this);
+ d->ui->profileList->setModel(d->profileModel);
+
+ connect(d->ui->addButton, SIGNAL(clicked(bool)), SLOT(addButtonClicked()));
+ connect(d->ui->removeButton, SIGNAL(clicked(bool)), SLOT(removeButtonClicked()));
+ connect(d->ui->duplicateButton, SIGNAL(clicked(bool)), SLOT(duplicateButtonClicked()));
+ connect(d->ui->renameButton, SIGNAL(clicked(bool)), SLOT(renameButtonClicked()));
+
+ setButtons(Close | Default);
+ setWindowTitle(i18n("Edit Profiles"));
+}
+
+KisEditProfilesDialog::~KisEditProfilesDialog()
+{
+ delete d;
+}
+
+void KisEditProfilesDialog::addButtonClicked()
+{
+ QString newProfileName = i18n("New Profile");
+ KisInputProfileManager::instance()->addProfile(newProfileName);
+ d->ui->profileList->edit(d->profileModel->find(newProfileName));
+}
+
+void KisEditProfilesDialog::removeButtonClicked()
+{
+ KisInputProfileManager::instance()->removeProfile(d->profileModel->profileName(d->ui->profileList->currentIndex()));
+}
+
+void KisEditProfilesDialog::duplicateButtonClicked()
+{
+ QString currentName = d->profileModel->profileName(d->ui->profileList->currentIndex());
+ QString newName = i18n("Copy of %1").arg(currentName);
+ KisInputProfileManager::instance()->duplicateProfile(currentName, newName);
+}
+
+void KisEditProfilesDialog::renameButtonClicked()
+{
+ d->ui->profileList->edit(d->ui->profileList->currentIndex());
+}
diff --git a/krita/ui/input/config/kis_edit_profiles_dialog.h b/krita/ui/input/config/kis_edit_profiles_dialog.h
new file mode 100644
index 0000000..a11f0d5
--- /dev/null
+++ b/krita/ui/input/config/kis_edit_profiles_dialog.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISEDITPROFILESDIALOG_H
+#define KISEDITPROFILESDIALOG_H
+
+#include <KDialog>
+
+class QListWidgetItem;
+/**
+ * \brief A dialog that provides facilities to edit all the available profiles.
+ *
+ */
+class KisEditProfilesDialog : public KDialog
+{
+ Q_OBJECT
+public:
+ KisEditProfilesDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~KisEditProfilesDialog();
+
+private Q_SLOTS:
+ void addButtonClicked();
+ void removeButtonClicked();
+ void duplicateButtonClicked();
+ void renameButtonClicked();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISEDITPROFILESDIALOG_H
diff --git a/krita/ui/input/config/kis_edit_profiles_dialog.ui b/krita/ui/input/config/kis_edit_profiles_dialog.ui
new file mode 100644
index 0000000..a831bf9
--- /dev/null
+++ b/krita/ui/input/config/kis_edit_profiles_dialog.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisEditProfilesDialog</class>
+ <widget class="QWidget" name="KisEditProfilesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>667</width>
+ <height>682</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="KPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="icon">
+ <iconset theme="list-remove">
+ <normaloff/>
+ </iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="KPushButton" name="renameButton">
+ <property name="text">
+ <string>Rename</string>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-rename">
+ <normaloff/>
+ </iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="KPushButton" name="addButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="icon">
+ <iconset theme="list-add">
+ <normaloff/>
+ </iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="KPushButton" name="duplicateButton">
+ <property name="text">
+ <string>Duplicate</string>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-copy">
+ <normaloff/>
+ </iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4">
+ <widget class="QListView" name="profileList"/>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KPushButton</class>
+ <extends>QPushButton</extends>
+ <header>kpushbutton.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/config/kis_input_button.cpp b/krita/ui/input/config/kis_input_button.cpp
new file mode 100644
index 0000000..a31b04a
--- /dev/null
+++ b/krita/ui/input/config/kis_input_button.cpp
@@ -0,0 +1,230 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_button.h"
+
+#include <QTimer>
+#include <QMouseEvent>
+#include <QKeyEvent>
+#include <KLocalizedString>
+
+#include "KoIcon.h"
+
+#include "input/kis_shortcut_configuration.h"
+
+class KisInputButton::Private
+{
+public:
+ Private(KisInputButton *qq) : q(qq), type(KeyType), newInput(false), resetTimer(0) { }
+ void updateLabel();
+
+ KisInputButton *q;
+
+ ButtonType type;
+
+ QList<Qt::Key> keys;
+ Qt::MouseButtons buttons;
+ KisShortcutConfiguration::MouseWheelMovement wheel;
+ bool newInput;
+
+ QTimer *resetTimer;
+};
+
+KisInputButton::KisInputButton(QWidget *parent)
+ : KPushButton(parent), d(new Private(this))
+{
+ setIcon(koIcon("configure-shortcuts"));
+ setText(i18nc("No input for this button", "None"));
+ setCheckable(true);
+
+ d->resetTimer = new QTimer(this);
+ d->resetTimer->setInterval(5000);
+ d->resetTimer->setSingleShot(true);
+ connect(d->resetTimer, SIGNAL(timeout()), SLOT(reset()));
+}
+
+KisInputButton::~KisInputButton()
+{
+ delete d;
+}
+
+KisInputButton::ButtonType KisInputButton::type() const
+{
+ return d->type;
+}
+
+void KisInputButton::setType(KisInputButton::ButtonType newType)
+{
+ d->type = newType;
+}
+
+void KisInputButton::clear()
+{
+ d->keys.clear();
+ d->buttons = 0;
+ d->wheel = KisShortcutConfiguration::NoMovement;
+ d->updateLabel();
+}
+
+QList< Qt::Key > KisInputButton::keys() const
+{
+ return d->keys;
+}
+
+void KisInputButton::setKeys(const QList< Qt::Key > &newKeys)
+{
+ if (newKeys != d->keys) {
+ d->keys = newKeys;
+ d->updateLabel();
+ }
+}
+
+Qt::MouseButtons KisInputButton::buttons() const
+{
+ return d->buttons;
+}
+
+void KisInputButton::setButtons(Qt::MouseButtons newButtons)
+{
+ if (newButtons != d->buttons) {
+ d->buttons = newButtons;
+ d->updateLabel();
+ }
+}
+
+KisShortcutConfiguration::MouseWheelMovement KisInputButton::wheel() const
+{
+ return d->wheel;
+}
+
+void KisInputButton::setWheel(KisShortcutConfiguration::MouseWheelMovement newWheel)
+{
+ if (newWheel != d->wheel) {
+ d->wheel = newWheel;
+ d->updateLabel();
+ }
+}
+
+void KisInputButton::mousePressEvent(QMouseEvent *event)
+{
+ if (isChecked() && d->type == KisInputButton::MouseType) {
+ d->buttons = event->buttons();
+ d->updateLabel();
+ d->resetTimer->start();
+ }
+}
+
+void KisInputButton::mouseReleaseEvent(QMouseEvent *)
+{
+ if (isChecked()) {
+ reset();
+ }
+ else {
+ setChecked(true);
+ setText(i18nc("Waiting for user input", "Input ..."));
+ d->resetTimer->start();
+ d->newInput = true;
+ }
+}
+
+void KisInputButton::wheelEvent(QWheelEvent *event)
+{
+ if (isChecked() && event->delta() != 0) {
+ switch (event->orientation()) {
+ case Qt::Horizontal:
+ if (event->delta() < 0) {
+ d->wheel = KisShortcutConfiguration::WheelRight;
+ }
+ else {
+ d->wheel = KisShortcutConfiguration::WheelLeft;
+ }
+
+ break;
+
+ case Qt::Vertical:
+ if (event->delta() > 0) {
+ d->wheel = KisShortcutConfiguration::WheelUp;
+ }
+ else {
+ d->wheel = KisShortcutConfiguration::WheelDown;
+ }
+
+ break;
+ }
+
+ d->updateLabel();
+ }
+}
+
+void KisInputButton::keyPressEvent(QKeyEvent *event)
+{
+ if (isChecked()) {
+ if (d->newInput) {
+ d->keys.clear();
+ d->newInput = false;
+ }
+
+ Qt::Key key = static_cast<Qt::Key>(event->key());
+
+ if (key == Qt::Key_Meta && event->modifiers().testFlag(Qt::ShiftModifier)) {
+ key = Qt::Key_Alt;
+ }
+
+ d->keys.append(key);
+ d->updateLabel();
+ d->resetTimer->start();
+ }
+}
+
+void KisInputButton::keyReleaseEvent(QKeyEvent *event)
+{
+ if (isChecked()) {
+ reset();
+ }
+ else if (event->key() == Qt::Key_Space || event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ setChecked(true);
+ setText(i18nc("Waiting for user input", "Input ..."));
+ d->resetTimer->start();
+ d->newInput = true;
+ }
+}
+
+void KisInputButton::reset()
+{
+ setChecked(false);
+ d->updateLabel();
+ emit dataChanged();
+}
+
+void KisInputButton::Private::updateLabel()
+{
+ switch (type) {
+ case MouseType:
+ q->setText(KisShortcutConfiguration::buttonsToText(buttons));
+ break;
+
+ case KeyType:
+ q->setText(KisShortcutConfiguration::keysToText(keys));
+ break;
+
+ case WheelType:
+ q->setText(KisShortcutConfiguration::wheelToText(wheel));
+ break;
+ }
+}
diff --git a/krita/ui/input/config/kis_input_button.h b/krita/ui/input/config/kis_input_button.h
new file mode 100644
index 0000000..19db3a5
--- /dev/null
+++ b/krita/ui/input/config/kis_input_button.h
@@ -0,0 +1,143 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTBUTTON_H
+#define KISINPUTBUTTON_H
+
+#include <KPushButton>
+
+#include "input/kis_shortcut_configuration.h"
+
+/**
+ * \brief A button that can detect input and will store its value.
+ *
+ * This button, when pressed, will detect input based on what type has been set.
+ * It is mainly intended for shortcut configuration, that is, picking some input that is
+ * later reused for shortcuts or similar.
+ *
+ */
+class KisInputButton : public KPushButton
+{
+ Q_OBJECT
+public:
+ /**
+ * The type of button.
+ */
+ enum ButtonType {
+ MouseType, ///< Detect and store any combination of pressed mouse buttons.
+ KeyType, ///< Detect and store any combination of key presses.
+ WheelType, ///< Detect and store mouse wheel movement.
+ };
+
+ /**
+ * Constructor.
+ */
+ explicit KisInputButton(QWidget *parent = 0);
+ /**
+ * Destructor.
+ */
+ virtual ~KisInputButton();
+
+ /**
+ * \return The type of input this button detects.
+ */
+ ButtonType type() const;
+ /**
+ * Set the type of input this button should detect.
+ *
+ * \param newType The type of input to detect.
+ */
+ void setType(ButtonType newType);
+
+ /**
+ * \return The list of keys that was detected. Only applicable when type is `KeyType`.
+ */
+ QList<Qt::Key> keys() const;
+ /**
+ * Set the list of keys to display.
+ *
+ * This is mostly intended to make sure the button displays the right keys when viewed
+ * in a dialog or similar UI.
+ *
+ * Only applicable when type is `KeyType`.
+ *
+ * \param newKeys The list of keys to display.
+ */
+ void setKeys(const QList<Qt::Key> &newKeys);
+
+ /**
+ * \return The mouse buttons that were detected. Only applicable when type is `MouseType`.
+ */
+ Qt::MouseButtons buttons() const;
+ /**
+ * Set the mouse buttons to display.
+ *
+ * This is mostly intended to make sure the button displays the right buttons when viewed
+ * in a dialog or similar UI.
+ *
+ * Only applicable when type is `MouseType`.
+ *
+ * \param newButtons The mouse buttons to display.
+ */
+ void setButtons(Qt::MouseButtons newButtons);
+
+ /**
+ * \return The mouse wheel movement that was detected. Only applicable when type is `WheelType`.
+ */
+ KisShortcutConfiguration::MouseWheelMovement wheel() const;
+ /**
+ * Set the mouse wheel movement to display.
+ *
+ * This is mostly intended to make sure the button displays the right wheel movement when
+ * viewed in a dialog or similar UI.
+ *
+ * Only applicable when type is `WheelType`.
+ *
+ * \param newButtons The wheel movement to display.
+ */
+ void setWheel(KisShortcutConfiguration::MouseWheelMovement wheel);
+
+public Q_SLOTS:
+ /**
+ * Clear all detected input and reset the button to an empty state.
+ */
+ void clear();
+
+Q_SIGNALS:
+ /**
+ * Emitted whenever one of the values (keys, buttons, wheel) changes.
+ */
+ void dataChanged();
+
+protected:
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void wheelEvent(QWheelEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+
+private Q_SLOTS:
+ void reset();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTBUTTON_H
diff --git a/krita/ui/input/config/kis_input_configuration_page.cpp b/krita/ui/input/config/kis_input_configuration_page.cpp
new file mode 100644
index 0000000..b440056
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page.cpp
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_configuration_page.h"
+#include "ui_kis_input_configuration_page.h"
+
+#include "input/kis_input_profile_manager.h"
+#include "input/kis_input_profile.h"
+#include "kis_edit_profiles_dialog.h"
+#include "kis_input_profile_model.h"
+#include "kis_input_configuration_page_item.h"
+#include <QDir>
+#include <KStandardDirs>
+
+KisInputConfigurationPage::KisInputConfigurationPage(QWidget *parent, Qt::WindowFlags f)
+ : QWidget(parent, f)
+{
+ ui = new Ui::KisInputConfigurationPage;
+ ui->setupUi(this);
+
+ ui->profileComboBox->setModel(new KisInputProfileModel(ui->profileComboBox));
+ updateSelectedProfile();
+ connect(ui->profileComboBox, SIGNAL(currentIndexChanged(QString)), SLOT(changeCurrentProfile(QString)));
+
+ connect(ui->editProfilesButton, SIGNAL(clicked(bool)), SLOT(editProfilesButtonClicked()));
+ connect(KisInputProfileManager::instance(), SIGNAL(profilesChanged()), SLOT(updateSelectedProfile()));
+
+ QList<KisAbstractInputAction *> actions = KisInputProfileManager::instance()->actions();
+ Q_FOREACH(KisAbstractInputAction * action, actions) {
+ KisInputConfigurationPageItem *item = new KisInputConfigurationPageItem(this);
+ item->setAction(action);
+ ui->configurationItemsArea->addWidget(item);
+ }
+}
+
+void KisInputConfigurationPage::saveChanges()
+{
+ KisInputProfileManager::instance()->saveProfiles();
+}
+
+void KisInputConfigurationPage::revertChanges()
+{
+ KisInputProfileManager::instance()->loadProfiles();
+}
+
+void KisInputConfigurationPage::setDefaults()
+{
+ QDir profileDir(KGlobal::dirs()->saveLocation("appdata", "input/", false));
+
+ if (profileDir.exists()) {
+ QStringList entries = profileDir.entryList(QStringList() << "*.profile", QDir::NoDot | QDir::NoDotDot);
+ Q_FOREACH(const QString & file, entries) {
+ profileDir.remove(file);
+ }
+
+ KisInputProfileManager::instance()->loadProfiles();
+ }
+}
+
+void KisInputConfigurationPage::editProfilesButtonClicked()
+{
+ KisEditProfilesDialog dialog;
+ dialog.exec();
+}
+
+void KisInputConfigurationPage::updateSelectedProfile()
+{
+ if (KisInputProfileManager::instance()->currentProfile()) {
+ ui->profileComboBox->setCurrentItem(KisInputProfileManager::instance()->currentProfile()->name());
+ }
+}
+
+void KisInputConfigurationPage::changeCurrentProfile(const QString &newProfile)
+{
+ KisInputProfileManager::instance()->setCurrentProfile(KisInputProfileManager::instance()->profile(newProfile));
+}
diff --git a/krita/ui/input/config/kis_input_configuration_page.h b/krita/ui/input/config/kis_input_configuration_page.h
new file mode 100644
index 0000000..45339fd
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTCONFIGURATIONPAGE_H
+#define KISINPUTCONFIGURATIONPAGE_H
+
+#include <QWidget>
+
+namespace Ui
+{
+class KisInputConfigurationPage;
+}
+
+/**
+ * \brief A Configuration Dialog Page to configure the canvas input.
+ */
+class KisInputConfigurationPage : public QWidget
+{
+ Q_OBJECT
+public:
+ KisInputConfigurationPage(QWidget *parent = 0, Qt::WindowFlags f = 0);
+
+public Q_SLOTS:
+ void saveChanges();
+ void revertChanges();
+ void setDefaults();
+
+private Q_SLOTS:
+ void editProfilesButtonClicked();
+ void updateSelectedProfile();
+ void changeCurrentProfile(const QString &newProfile);
+
+private:
+ Ui::KisInputConfigurationPage *ui;
+
+};
+
+#endif // KISINPUTCONFIGURATIONPAGE_H
diff --git a/krita/ui/input/config/kis_input_configuration_page.ui b/krita/ui/input/config/kis_input_configuration_page.ui
new file mode 100644
index 0000000..d5a9cb3
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page.ui
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisInputConfigurationPage</class>
+ <widget class="QWidget" name="KisInputConfigurationPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1016</width>
+ <height>979</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Profile</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KComboBox" name="profileComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KPushButton" name="editProfilesButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Duplicate current profile</string>
+ </property>
+ <property name="text">
+ <string>Edit Profiles</string>
+ </property>
+ <property name="icon">
+ <iconset theme="document-edit">
+ <normaloff/>
+ </iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>18</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="configurationItemsArea"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KComboBox</class>
+ <extends>QComboBox</extends>
+ <header>kcombobox.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KPushButton</class>
+ <extends>QPushButton</extends>
+ <header>kpushbutton.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/config/kis_input_configuration_page_item.cpp b/krita/ui/input/config/kis_input_configuration_page_item.cpp
new file mode 100644
index 0000000..e3c03e3
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page_item.cpp
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_configuration_page_item.h"
+
+#include "KoIcon.h"
+
+#include "input/kis_abstract_input_action.h"
+#include "input/kis_input_profile_manager.h"
+#include "kis_action_shortcuts_model.h"
+#include "kis_input_type_delegate.h"
+#include "kis_input_mode_delegate.h"
+#include "kis_input_editor_delegate.h"
+#include "ui_kis_input_configuration_page_item.h"
+
+KisInputConfigurationPageItem::KisInputConfigurationPageItem(QWidget *parent, Qt::WindowFlags f)
+ : QWidget(parent, f)
+{
+ ui = new Ui::KisInputConfigurationPageItem;
+ ui->setupUi(this);
+
+ m_shortcutsModel = new KisActionShortcutsModel(this);
+ ui->shortcutsView->setModel(m_shortcutsModel);
+ ui->shortcutsView->setItemDelegateForColumn(0, new KisInputTypeDelegate(ui->shortcutsView));
+ ui->shortcutsView->setItemDelegateForColumn(1, new KisInputEditorDelegate(ui->shortcutsView));
+ ui->shortcutsView->setItemDelegateForColumn(2, new KisInputModeDelegate(ui->shortcutsView));
+ ui->shortcutsView->header()->setResizeMode(QHeaderView::Stretch);
+ setExpanded(false);
+
+ QAction *deleteAction = new QAction(koIcon("edit-delete"), i18n("Delete Shortcut"), ui->shortcutsView);
+ connect(deleteAction, SIGNAL(triggered(bool)), SLOT(deleteShortcut()));
+ ui->shortcutsView->addAction(deleteAction);
+ ui->shortcutsView->setContextMenuPolicy(Qt::ActionsContextMenu);
+
+ connect(ui->collapseButton, SIGNAL(clicked(bool)), SLOT(setExpanded(bool)));
+}
+
+KisInputConfigurationPageItem::~KisInputConfigurationPageItem()
+{
+ delete ui;
+}
+
+void KisInputConfigurationPageItem::setAction(KisAbstractInputAction *action)
+{
+ m_action = action;
+ ui->collapseButton->setText(action->name());
+ ui->descriptionLabel->setText(action->description());
+ m_shortcutsModel->setProfile(KisInputProfileManager::instance()->currentProfile());
+ m_shortcutsModel->setAction(action);
+ qobject_cast<KisInputModeDelegate *>(ui->shortcutsView->itemDelegateForColumn(2))->setAction(action);
+}
+
+void KisInputConfigurationPageItem::setExpanded(bool expand)
+{
+ if (expand) {
+ ui->descriptionLabel->setVisible(true);
+ ui->shortcutsView->setVisible(true);
+ ui->collapseButton->setArrowType(Qt::DownArrow);
+ }
+ else {
+ ui->descriptionLabel->setVisible(false);
+ ui->shortcutsView->setVisible(false);
+ ui->collapseButton->setArrowType(Qt::RightArrow);
+ }
+}
+
+void KisInputConfigurationPageItem::deleteShortcut()
+{
+ m_shortcutsModel->removeRow(ui->shortcutsView->selectionModel()->currentIndex().row(), QModelIndex());
+}
diff --git a/krita/ui/input/config/kis_input_configuration_page_item.h b/krita/ui/input/config/kis_input_configuration_page_item.h
new file mode 100644
index 0000000..25f2f1e
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page_item.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTCONFIGURATIONPAGEITEM_H
+#define KISINPUTCONFIGURATIONPAGEITEM_H
+
+#include <QWidget>
+
+namespace Ui
+{
+class KisInputConfigurationPageItem;
+}
+
+class KisActionShortcutsModel;
+class QModelIndex;
+class KisAbstractInputAction;
+/**
+ * \brief A collapsible widget displaying an action, its description and associated shortcuts.
+ *
+ * This is used in KisInputConfigurationPage to display a list of actions and the associated
+ * shortcuts, depending on the current profile.
+ */
+class KisInputConfigurationPageItem : public QWidget
+{
+ Q_OBJECT
+public:
+ KisInputConfigurationPageItem(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ ~KisInputConfigurationPageItem();
+
+ void setAction(KisAbstractInputAction *action);
+
+public Q_SLOTS:
+ void setExpanded(bool expand);
+
+private Q_SLOTS:
+ void deleteShortcut();
+
+private:
+ Ui::KisInputConfigurationPageItem *ui;
+ KisAbstractInputAction *m_action;
+ KisActionShortcutsModel *m_shortcutsModel;
+};
+
+#endif // KISINPUTCONFIGURATIONPAGEITEM_H
diff --git a/krita/ui/input/config/kis_input_configuration_page_item.ui b/krita/ui/input/config/kis_input_configuration_page_item.ui
new file mode 100644
index 0000000..e9a41fb
--- /dev/null
+++ b/krita/ui/input/config/kis_input_configuration_page_item.ui
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisInputConfigurationPageItem</class>
+ <widget class="QWidget" name="KisInputConfigurationPageItem">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>605</width>
+ <height>330</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1" colspan="2">
+ <widget class="QLabel" name="descriptionLabel">
+ <property name="text">
+ <string><html><head/><body><p>Action Description</p></body></html></string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QToolButton" name="collapseButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Action Name</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::RightArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QTreeView" name="shortcutsView">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/config/kis_input_editor_delegate.cpp b/krita/ui/input/config/kis_input_editor_delegate.cpp
new file mode 100644
index 0000000..b5bd3df
--- /dev/null
+++ b/krita/ui/input/config/kis_input_editor_delegate.cpp
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_editor_delegate.h"
+
+#include <QApplication>
+
+#include <KLocalizedString>
+
+#include "input/kis_input_profile.h"
+#include "input/kis_shortcut_configuration.h"
+#include "kis_input_button.h"
+#include "kis_mouse_input_editor.h"
+#include "kis_wheel_input_editor.h"
+#include "kis_key_input_editor.h"
+
+class KisInputEditorDelegate::Private
+{
+public:
+ Private() { }
+};
+
+KisInputEditorDelegate::KisInputEditorDelegate(QObject *parent)
+ : QStyledItemDelegate(parent), d(new Private())
+{
+}
+
+KisInputEditorDelegate::~KisInputEditorDelegate()
+{
+ delete d;
+
+}
+
+QWidget *KisInputEditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
+{
+ KPushButton *editor = 0;
+ KisShortcutConfiguration *s = index.data(Qt::EditRole).value<KisShortcutConfiguration *>();
+
+ switch (s->type()) {
+ case KisShortcutConfiguration::KeyCombinationType:
+ editor = new KisKeyInputEditor(parent);
+ break;
+
+ case KisShortcutConfiguration::MouseButtonType:
+ editor = new KisMouseInputEditor(parent);
+ break;
+
+ case KisShortcutConfiguration::MouseWheelType:
+ editor = new KisWheelInputEditor(parent);
+ break;
+
+ default:
+ break;
+ }
+
+ return editor;
+}
+
+void KisInputEditorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ KisShortcutConfiguration *s = index.model()->data(index, Qt::EditRole).value<KisShortcutConfiguration *>();
+
+ switch (s->type()) {
+ case KisShortcutConfiguration::KeyCombinationType: {
+ KisKeyInputEditor *e = qobject_cast<KisKeyInputEditor *>(editor);
+ e->setKeys(s->keys());
+ break;
+ }
+
+ case KisShortcutConfiguration::MouseButtonType: {
+ KisMouseInputEditor *e = qobject_cast<KisMouseInputEditor *>(editor);
+ e->setKeys(s->keys());
+ e->setButtons(s->buttons());
+ break;
+ }
+
+ case KisShortcutConfiguration::MouseWheelType: {
+ KisWheelInputEditor *e = qobject_cast<KisWheelInputEditor *>(editor);
+ e->setKeys(s->keys());
+ e->setWheel(s->wheel());
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void KisInputEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ KisShortcutConfiguration *s = model->data(index, Qt::EditRole).value<KisShortcutConfiguration *>();
+
+ switch (s->type()) {
+ case KisShortcutConfiguration::KeyCombinationType: {
+ KisKeyInputEditor *e = qobject_cast<KisKeyInputEditor *>(editor);
+ s->setKeys(e->keys());
+ break;
+ }
+
+ case KisShortcutConfiguration::MouseButtonType: {
+ KisMouseInputEditor *e = qobject_cast<KisMouseInputEditor *>(editor);
+ s->setKeys(e->keys());
+ s->setButtons(e->buttons());
+ break;
+ }
+
+ case KisShortcutConfiguration::MouseWheelType: {
+ KisWheelInputEditor *e = qobject_cast<KisWheelInputEditor *>(editor);
+ s->setKeys(e->keys());
+ s->setWheel(e->wheel());
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ model->setData(index, QVariant::fromValue(s), Qt::EditRole);
+}
+
+void KisInputEditorDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
+{
+ editor->setGeometry(option.rect);
+}
+
+QSize KisInputEditorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ return QStyledItemDelegate::sizeHint(option, index) + QSize(6, 6);
+}
diff --git a/krita/ui/input/config/kis_input_editor_delegate.h b/krita/ui/input/config/kis_input_editor_delegate.h
new file mode 100644
index 0000000..fbc38a8
--- /dev/null
+++ b/krita/ui/input/config/kis_input_editor_delegate.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTEDITORDELEGATE_H
+#define KISINPUTEDITORDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+/**
+ * \brief A delegate providing editors for the keys/buttons/etc. of KisShortcutConfiguration.
+ */
+class KisInputEditorDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ KisInputEditorDelegate(QObject *parent = 0);
+ ~KisInputEditorDelegate();
+
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const;
+ virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+ virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTEDITORDELEGATE_H
diff --git a/krita/ui/input/config/kis_input_mode_delegate.cpp b/krita/ui/input/config/kis_input_mode_delegate.cpp
new file mode 100644
index 0000000..2e161f1
--- /dev/null
+++ b/krita/ui/input/config/kis_input_mode_delegate.cpp
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_mode_delegate.h"
+#include "../kis_abstract_input_action.h"
+
+#include <KComboBox>
+#include <KLocalizedString>
+
+class KisInputModeDelegate::Private
+{
+public:
+ Private() { }
+
+ KisAbstractInputAction *action;
+};
+
+KisInputModeDelegate::KisInputModeDelegate(QObject *parent)
+ : QStyledItemDelegate(parent), d(new Private)
+{
+}
+
+KisInputModeDelegate::~KisInputModeDelegate()
+{
+ delete d;
+
+}
+
+QWidget *KisInputModeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
+{
+ KComboBox *combo = new KComboBox(parent);
+ QStringList sorted = d->action->shortcutIndexes().keys();
+ qSort(sorted);
+ combo->addItems(sorted);
+ return combo;
+}
+
+void KisInputModeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ KComboBox *combo = qobject_cast<KComboBox *>(editor);
+ Q_ASSERT(combo);
+
+ int i = combo->findText(d->action->shortcutIndexes().key(index.data(Qt::EditRole).toUInt()));
+ combo->setCurrentIndex(i);
+}
+
+void KisInputModeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ KComboBox *combo = qobject_cast<KComboBox *>(editor);
+ Q_ASSERT(combo);
+
+ int i = d->action->shortcutIndexes().value(combo->currentText());
+ model->setData(index, i, Qt::EditRole);
+}
+
+void KisInputModeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
+{
+ editor->setGeometry(option.rect);
+}
+
+void KisInputModeDelegate::setAction(KisAbstractInputAction *action)
+{
+ d->action = action;
+}
diff --git a/krita/ui/input/config/kis_input_mode_delegate.h b/krita/ui/input/config/kis_input_mode_delegate.h
new file mode 100644
index 0000000..c25908d
--- /dev/null
+++ b/krita/ui/input/config/kis_input_mode_delegate.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTMODEDELEGATE_H
+#define KISINPUTMODEDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+class KisAbstractInputAction;
+/**
+ * \brief A delegate providing editors for the mode property of KisShortcutConfiguration.
+ */
+class KisInputModeDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit KisInputModeDelegate(QObject *parent = 0);
+ ~KisInputModeDelegate();
+
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const;
+ virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+ virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const;
+
+ void setAction(KisAbstractInputAction *action);
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTMODEDELEGATE_H
diff --git a/krita/ui/input/config/kis_input_profile_model.cpp b/krita/ui/input/config/kis_input_profile_model.cpp
new file mode 100644
index 0000000..d7ea00f
--- /dev/null
+++ b/krita/ui/input/config/kis_input_profile_model.cpp
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_profile_model.h"
+
+#include "input/kis_input_profile_manager.h"
+
+KisInputProfileModel::KisInputProfileModel(QObject *parent)
+ : QStringListModel(parent)
+{
+ setStringList(KisInputProfileManager::instance()->profileNames());
+ connect(KisInputProfileManager::instance(), SIGNAL(profilesChanged()), SLOT(profileNamesChanged()));
+}
+
+KisInputProfileModel::~KisInputProfileModel()
+{
+
+}
+
+void KisInputProfileModel::profileNamesChanged()
+{
+ setStringList(KisInputProfileManager::instance()->profileNames());
+}
+
+bool KisInputProfileModel::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
+{
+ QString oldName = profileName(index);
+ return KisInputProfileManager::instance()->renameProfile(oldName, value.toString());
+}
+
+QString KisInputProfileModel::profileName(const QModelIndex &index)
+{
+ return data(index, Qt::DisplayRole).toString();
+}
+
+QModelIndex KisInputProfileModel::find(const QString &name)
+{
+ for (int i = 0; i < rowCount(); ++i) {
+ QModelIndex ind = index(i, 0);
+
+ if (profileName(ind) == name) {
+ return ind;
+ }
+ }
+
+ return QModelIndex();
+}
+
diff --git a/krita/ui/input/config/kis_input_profile_model.h b/krita/ui/input/config/kis_input_profile_model.h
new file mode 100644
index 0000000..58f208a
--- /dev/null
+++ b/krita/ui/input/config/kis_input_profile_model.h
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTPROFILEMODEL_H
+#define KISINPUTPROFILEMODEL_H
+
+#include <QStringListModel>
+
+/**
+ * \brief A model providing a list of profiles available.
+ */
+class KisInputProfileModel : public QStringListModel
+{
+ Q_OBJECT
+public:
+ KisInputProfileModel(QObject *parent = 0);
+ ~KisInputProfileModel();
+
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int = Qt::EditRole);
+
+ QString profileName(const QModelIndex &index);
+ QModelIndex find(const QString &name);
+
+private Q_SLOTS:
+ void profileNamesChanged();
+};
+
+#endif // KISINPUTPROFILEMODEL_H
diff --git a/krita/ui/input/config/kis_input_type_delegate.cpp b/krita/ui/input/config/kis_input_type_delegate.cpp
new file mode 100644
index 0000000..15307e3
--- /dev/null
+++ b/krita/ui/input/config/kis_input_type_delegate.cpp
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_type_delegate.h"
+
+#include <KComboBox>
+#include <KLocalizedString>
+
+class KisInputTypeDelegate::Private
+{
+public:
+ Private() { }
+};
+
+KisInputTypeDelegate::KisInputTypeDelegate(QObject *parent)
+ : QStyledItemDelegate(parent), d(new Private)
+{
+
+}
+
+KisInputTypeDelegate::~KisInputTypeDelegate()
+{
+ delete d;
+
+}
+
+QWidget *KisInputTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
+{
+ KComboBox *combo = new KComboBox(parent);
+ combo->addItems(QStringList()
+ << i18n("Key Combination")
+ << i18n("Mouse Button")
+ << i18n("Mouse Wheel")
+ //<< i18n("Gesture")
+ );
+ combo->setCurrentIndex(0);
+
+ return combo;
+}
+
+void KisInputTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ KComboBox *combo = qobject_cast<KComboBox *>(editor);
+ Q_ASSERT(combo);
+
+ combo->setCurrentIndex(index.data(Qt::EditRole).toUInt() - 1);
+}
+
+void KisInputTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ KComboBox *combo = qobject_cast<KComboBox *>(editor);
+ Q_ASSERT(combo);
+ model->setData(index, combo->currentIndex() + 1, Qt::EditRole);
+}
+
+void KisInputTypeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
+{
+ editor->setGeometry(option.rect);
+}
diff --git a/krita/ui/input/config/kis_input_type_delegate.h b/krita/ui/input/config/kis_input_type_delegate.h
new file mode 100644
index 0000000..d3594dd
--- /dev/null
+++ b/krita/ui/input/config/kis_input_type_delegate.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTTYPEDELEGATE_H
+#define KISINPUTTYPEDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+/**
+ * \brief A delegate providing editors for the type property of KisShortcutConfiguration.
+ */
+class KisInputTypeDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit KisInputTypeDelegate(QObject *parent = 0);
+ ~KisInputTypeDelegate();
+
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const;
+ virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+ virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const;
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTTYPEDELEGATE_H
diff --git a/krita/ui/input/config/kis_key_input_editor.cpp b/krita/ui/input/config/kis_key_input_editor.cpp
new file mode 100644
index 0000000..4179f94
--- /dev/null
+++ b/krita/ui/input/config/kis_key_input_editor.cpp
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_key_input_editor.h"
+
+#include <QWidgetAction>
+#include <QMenu>
+#include <QTimer>
+
+#include "ui_kis_key_input_editor.h"
+
+class KisKeyInputEditor::Private
+{
+public:
+ Private() { }
+
+ Ui::KisKeyInputEditor *ui;
+};
+
+KisKeyInputEditor::KisKeyInputEditor(QWidget *parent)
+ : KPushButton(parent), d(new Private)
+{
+ QWidget *popup = new QWidget();
+
+ d->ui = new Ui::KisKeyInputEditor;
+ d->ui->setupUi(popup);
+
+ QWidgetAction *action = new QWidgetAction(this);
+ action->setDefaultWidget(popup);
+
+ QMenu *menu = new QMenu(this);
+ menu->addAction(action);
+ setMenu(menu);
+
+ QTimer::singleShot(0, this, SLOT(showMenu()));
+
+ connect(d->ui->keysButton, SIGNAL(dataChanged()), SLOT(updateLabel()));
+ connect(d->ui->clearKeysButton, SIGNAL(clicked(bool)), d->ui->keysButton, SLOT(clear()));
+}
+
+KisKeyInputEditor::~KisKeyInputEditor()
+{
+ delete d->ui;
+ delete d;
+}
+
+QList< Qt::Key > KisKeyInputEditor::keys() const
+{
+ return d->ui->keysButton->keys();
+}
+
+void KisKeyInputEditor::setKeys(const QList< Qt::Key > &newKeys)
+{
+ d->ui->keysButton->setKeys(newKeys);
+ updateLabel();
+}
+
+void KisKeyInputEditor::updateLabel()
+{
+ setText(KisShortcutConfiguration::keysToText(d->ui->keysButton->keys()));
+}
diff --git a/krita/ui/input/config/kis_key_input_editor.h b/krita/ui/input/config/kis_key_input_editor.h
new file mode 100644
index 0000000..d37af9a
--- /dev/null
+++ b/krita/ui/input/config/kis_key_input_editor.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISKEYINPUTEDITOR_H
+#define KISKEYINPUTEDITOR_H
+
+#include <KPushButton>
+
+namespace Ui
+{
+class KisKeyInputEditor;
+}
+
+/**
+ * \brief An editor widget for a list of keys.
+ */
+class KisKeyInputEditor : public KPushButton
+{
+ Q_OBJECT
+public:
+ KisKeyInputEditor(QWidget *parent = 0);
+ ~KisKeyInputEditor();
+
+ QList<Qt::Key> keys() const;
+ void setKeys(const QList<Qt::Key> &newKeys);
+
+ Qt::MouseButtons buttons() const;
+ void setButtons(Qt::MouseButtons newButtons);
+
+private Q_SLOTS:
+ void updateLabel();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISKEYINPUTEDITOR_H
diff --git a/krita/ui/input/config/kis_key_input_editor.ui b/krita/ui/input/config/kis_key_input_editor.ui
new file mode 100644
index 0000000..efee21b
--- /dev/null
+++ b/krita/ui/input/config/kis_key_input_editor.ui
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisKeyInputEditor</class>
+ <widget class="QWidget" name="KisKeyInputEditor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>65</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Edit Key Combination</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="KPushButton" name="clearKeysButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-clear-locationbar-rtl">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="keysLabel">
+ <property name="styleSheet">
+ <string notr="true">background: none;</string>
+ </property>
+ <property name="text">
+ <string>Keys</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="KisInputButton" name="keysButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="configure">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KPushButton</class>
+ <extends>QPushButton</extends>
+ <header>kpushbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KisInputButton</class>
+ <extends>QPushButton</extends>
+ <header>input/config/kis_input_button.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/config/kis_mouse_input_editor.cpp b/krita/ui/input/config/kis_mouse_input_editor.cpp
new file mode 100644
index 0000000..9e6bdcb
--- /dev/null
+++ b/krita/ui/input/config/kis_mouse_input_editor.cpp
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_mouse_input_editor.h"
+
+#include <QWidgetAction>
+#include <QMenu>
+#include <QTimer>
+
+#include "ui_kis_mouse_input_editor.h"
+
+class KisMouseInputEditor::Private
+{
+public:
+ Private() { }
+
+ Ui::KisMouseInputEditor *ui;
+};
+
+KisMouseInputEditor::KisMouseInputEditor(QWidget *parent)
+ : KPushButton(parent), d(new Private)
+{
+ QWidget *popup = new QWidget();
+
+ d->ui = new Ui::KisMouseInputEditor;
+ d->ui->setupUi(popup);
+ d->ui->mouseButton->setType(KisInputButton::MouseType);
+
+ QWidgetAction *action = new QWidgetAction(this);
+ action->setDefaultWidget(popup);
+
+ QMenu *menu = new QMenu(this);
+ menu->addAction(action);
+ setMenu(menu);
+
+ QTimer::singleShot(0, this, SLOT(showMenu()));
+
+ connect(d->ui->mouseButton, SIGNAL(dataChanged()), SLOT(updateLabel()));
+ connect(d->ui->modifiersButton, SIGNAL(dataChanged()), SLOT(updateLabel()));
+ connect(d->ui->clearMouseButton, SIGNAL(clicked(bool)), d->ui->mouseButton, SLOT(clear()));
+ connect(d->ui->clearModifiersButton, SIGNAL(clicked(bool)), d->ui->modifiersButton, SLOT(clear()));
+}
+
+KisMouseInputEditor::~KisMouseInputEditor()
+{
+ delete d->ui;
+ delete d;
+}
+
+QList< Qt::Key > KisMouseInputEditor::keys() const
+{
+ return d->ui->modifiersButton->keys();
+}
+
+void KisMouseInputEditor::setKeys(const QList< Qt::Key > &newKeys)
+{
+ d->ui->modifiersButton->setKeys(newKeys);
+ updateLabel();
+}
+
+Qt::MouseButtons KisMouseInputEditor::buttons() const
+{
+ return d->ui->mouseButton->buttons();
+}
+
+void KisMouseInputEditor::setButtons(Qt::MouseButtons newButtons)
+{
+ d->ui->mouseButton->setButtons(newButtons);
+ updateLabel();
+}
+
+void KisMouseInputEditor::updateLabel()
+{
+ QString text;
+
+ if (d->ui->modifiersButton->keys().size() > 0) {
+ text.append(KisShortcutConfiguration::keysToText(d->ui->modifiersButton->keys()));
+ text.append(" + ");
+ }
+
+ text.append(KisShortcutConfiguration::buttonsToText(d->ui->mouseButton->buttons()));
+
+ setText(text);
+}
diff --git a/krita/ui/input/config/kis_mouse_input_editor.h b/krita/ui/input/config/kis_mouse_input_editor.h
new file mode 100644
index 0000000..351ca2e
--- /dev/null
+++ b/krita/ui/input/config/kis_mouse_input_editor.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISMOUSEINPUTEDITOR_H
+#define KISMOUSEINPUTEDITOR_H
+
+#include <KPushButton>
+
+namespace Ui
+{
+class KisMouseInputEditor;
+}
+
+/**
+ * \brief An editor widget for mouse buttons with modifiers.
+ */
+class KisMouseInputEditor : public KPushButton
+{
+ Q_OBJECT
+public:
+ KisMouseInputEditor(QWidget *parent = 0);
+ ~KisMouseInputEditor();
+
+ QList<Qt::Key> keys() const;
+ void setKeys(const QList<Qt::Key> &newKeys);
+
+ Qt::MouseButtons buttons() const;
+ void setButtons(Qt::MouseButtons newButtons);
+
+private Q_SLOTS:
+ void updateLabel();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISMOUSEINPUTEDITOR_H
diff --git a/krita/ui/input/config/kis_mouse_input_editor.ui b/krita/ui/input/config/kis_mouse_input_editor.ui
new file mode 100644
index 0000000..3f1b20b
--- /dev/null
+++ b/krita/ui/input/config/kis_mouse_input_editor.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisMouseInputEditor</class>
+ <widget class="QWidget" name="KisMouseInputEditor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>100</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="1">
+ <widget class="KisInputButton" name="mouseButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="configure">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="KPushButton" name="clearMouseButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-clear-locationbar-rtl">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="KisInputButton" name="modifiersButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="configure">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="modifiersLabel">
+ <property name="styleSheet">
+ <string notr="true">background: none;</string>
+ </property>
+ <property name="text">
+ <string>Modifiers</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="mouseLabel">
+ <property name="styleSheet">
+ <string notr="true">background: none;</string>
+ </property>
+ <property name="text">
+ <string>Mouse Button</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="KPushButton" name="clearModifiersButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-clear-locationbar-rtl">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="4">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Edit Mouse Input</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KPushButton</class>
+ <extends>QPushButton</extends>
+ <header>kpushbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KisInputButton</class>
+ <extends>QPushButton</extends>
+ <header>input/config/kis_input_button.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/config/kis_wheel_input_editor.cpp b/krita/ui/input/config/kis_wheel_input_editor.cpp
new file mode 100644
index 0000000..f752fb6
--- /dev/null
+++ b/krita/ui/input/config/kis_wheel_input_editor.cpp
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_wheel_input_editor.h"
+
+#include "ui_kis_wheel_input_editor.h"
+#include <QMenu>
+#include <QWidgetAction>
+#include <QTimer>
+
+class KisWheelInputEditor::Private
+{
+public:
+ Private() { }
+
+ Ui::KisWheelInputEditor *ui;
+};
+
+KisWheelInputEditor::KisWheelInputEditor(QWidget *parent)
+ : KPushButton(parent), d(new Private)
+{
+ QWidget *popup = new QWidget();
+
+ d->ui = new Ui::KisWheelInputEditor;
+ d->ui->setupUi(popup);
+ d->ui->wheelButton->setType(KisInputButton::WheelType);
+
+ QWidgetAction *action = new QWidgetAction(this);
+ action->setDefaultWidget(popup);
+
+ QMenu *menu = new QMenu(this);
+ menu->addAction(action);
+ setMenu(menu);
+
+ QTimer::singleShot(0, this, SLOT(showMenu()));
+
+ connect(d->ui->wheelButton, SIGNAL(dataChanged()), SLOT(updateLabel()));
+ connect(d->ui->modifiersButton, SIGNAL(dataChanged()), SLOT(updateLabel()));
+ connect(d->ui->clearWheelButton, SIGNAL(clicked(bool)), d->ui->wheelButton, SLOT(clear()));
+ connect(d->ui->clearModifiersButton, SIGNAL(clicked(bool)), d->ui->modifiersButton, SLOT(clear()));
+}
+
+KisWheelInputEditor::~KisWheelInputEditor()
+{
+ delete d->ui;
+ delete d;
+}
+
+QList< Qt::Key > KisWheelInputEditor::keys() const
+{
+ return d->ui->modifiersButton->keys();
+}
+
+void KisWheelInputEditor::setKeys(const QList< Qt::Key > &newKeys)
+{
+ d->ui->modifiersButton->setKeys(newKeys);
+ updateLabel();
+}
+
+KisShortcutConfiguration::MouseWheelMovement KisWheelInputEditor::wheel() const
+{
+ return d->ui->wheelButton->wheel();
+}
+
+void KisWheelInputEditor::setWheel(KisShortcutConfiguration::MouseWheelMovement newWheel)
+{
+ d->ui->wheelButton->setWheel(newWheel);
+ updateLabel();
+}
+
+void KisWheelInputEditor::updateLabel()
+{
+ QString text;
+
+ if (d->ui->modifiersButton->keys().size() > 0) {
+ text.append(KisShortcutConfiguration::keysToText(d->ui->modifiersButton->keys()));
+ text.append(" + ");
+ }
+
+ text.append(KisShortcutConfiguration::wheelToText(d->ui->wheelButton->wheel()));
+
+ setText(text);
+}
diff --git a/krita/ui/input/config/kis_wheel_input_editor.h b/krita/ui/input/config/kis_wheel_input_editor.h
new file mode 100644
index 0000000..7425e57
--- /dev/null
+++ b/krita/ui/input/config/kis_wheel_input_editor.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISWHEELINPUTEDITOR_H
+#define KISWHEELINPUTEDITOR_H
+
+#include <KPushButton>
+
+#include "input/kis_shortcut_configuration.h"
+
+namespace Ui
+{
+class KisWheelInputEditor;
+}
+
+/**
+ * \brief An editor widget for mouse wheel input with modifiers.
+ */
+class KisWheelInputEditor : public KPushButton
+{
+ Q_OBJECT
+public:
+ KisWheelInputEditor(QWidget *parent = 0);
+ ~KisWheelInputEditor();
+
+ QList<Qt::Key> keys() const;
+ void setKeys(const QList<Qt::Key> &newKeys);
+
+ KisShortcutConfiguration::MouseWheelMovement wheel() const;
+ void setWheel(KisShortcutConfiguration::MouseWheelMovement newWheel);
+
+private Q_SLOTS:
+ void updateLabel();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISWHEELINPUTEDITOR_H
diff --git a/krita/ui/input/config/kis_wheel_input_editor.ui b/krita/ui/input/config/kis_wheel_input_editor.ui
new file mode 100644
index 0000000..5a813fc
--- /dev/null
+++ b/krita/ui/input/config/kis_wheel_input_editor.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KisWheelInputEditor</class>
+ <widget class="QWidget" name="KisWheelInputEditor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>100</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="1">
+ <widget class="KisInputButton" name="modifiersButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="configure">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="wheelLabel">
+ <property name="styleSheet">
+ <string notr="true">background: none;</string>
+ </property>
+ <property name="text">
+ <string>Mouse Wheel</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Edit Mouse Wheel Input</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="KisInputButton" name="wheelButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="configure">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="KPushButton" name="clearWheelButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-clear-locationbar-rtl">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="modifiersLabel">
+ <property name="styleSheet">
+ <string notr="true">background: none;</string>
+ </property>
+ <property name="text">
+ <string>Modifiers</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="KPushButton" name="clearModifiersButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-clear-locationbar-rtl">
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KPushButton</class>
+ <extends>QPushButton</extends>
+ <header>kpushbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KisInputButton</class>
+ <extends>QPushButton</extends>
+ <header>input/config/kis_input_button.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/krita/ui/input/kis_abstract_input_action.cpp b/krita/ui/input/kis_abstract_input_action.cpp
index 093f872..ebb63ef 100644
--- a/krita/ui/input/kis_abstract_input_action.cpp
+++ b/krita/ui/input/kis_abstract_input_action.cpp
@@ -25,18 +25,19 @@
class KisAbstractInputAction::Private
{
public:
- KisInputManager* inputManager;
-
QString name;
QString description;
QHash<QString, int> indexes;
QPointF lastMousePosition;
+
+ static KisInputManager* inputManager;
};
-KisAbstractInputAction::KisAbstractInputAction(KisInputManager* manager) : d(new Private)
+KisInputManager *KisAbstractInputAction::Private::inputManager = 0;
+
+KisAbstractInputAction::KisAbstractInputAction() : d(new Private)
{
- d->inputManager = manager;
d->indexes.insert(i18n("Activate"), 0);
}
@@ -92,7 +93,7 @@ bool KisAbstractInputAction::supportsHiResInputEvents() const
KisInputManager* KisAbstractInputAction::inputManager() const
{
- return d->inputManager;
+ return Private::inputManager;
}
QString KisAbstractInputAction::name() const
@@ -124,3 +125,8 @@ void KisAbstractInputAction::setShortcutIndexes(const QHash< QString, int >& ind
{
d->indexes = indexes;
}
+
+void KisAbstractInputAction::setInputManager(KisInputManager *manager)
+{
+ Private::inputManager = manager;
+}
diff --git a/krita/ui/input/kis_abstract_input_action.h b/krita/ui/input/kis_abstract_input_action.h
index 50afffa..ae5bb46 100644
--- a/krita/ui/input/kis_abstract_input_action.h
+++ b/krita/ui/input/kis_abstract_input_action.h
@@ -59,7 +59,7 @@ public:
*
* \param manager The InputManager this action belongs to.
*/
- explicit KisAbstractInputAction(KisInputManager *manager);
+ explicit KisAbstractInputAction();
/**
* Destructor.
*/
@@ -160,6 +160,9 @@ protected:
virtual void mouseMoved(const QPointF &lastPos, const QPointF &pos);
private:
+ friend class KisInputManager;
+ static void setInputManager(KisInputManager *manager);
+
class Private;
Private * const d;
};
diff --git a/krita/ui/input/kis_alternate_invocation_action.cpp b/krita/ui/input/kis_alternate_invocation_action.cpp
index c518215..e05799f 100644
--- a/krita/ui/input/kis_alternate_invocation_action.cpp
+++ b/krita/ui/input/kis_alternate_invocation_action.cpp
@@ -26,11 +26,10 @@
#include "kis_input_manager.h"
-KisAlternateInvocationAction::KisAlternateInvocationAction(KisInputManager *manager)
- : KisAbstractInputAction(manager)
+KisAlternateInvocationAction::KisAlternateInvocationAction()
{
setName(i18n("Alternate Invocation"));
- setDescription(i18n("Alternate Invocation performs an alternate action with the current tool. For example, using the brush tool it picks a color from the canvas."));
+ setDescription(i18n("The <i>Alternate Invocation</i> action performs an alternate action with the current tool. For example, using the brush tool it picks a color from the canvas."));
QHash<QString, int> shortcuts;
shortcuts.insert(i18n("Toggle Primary Mode"), PrimaryAlternateToggleShortcut);
shortcuts.insert(i18n("Toggle Secondary Mode"), SecondaryAlternateToggleShortcut);
diff --git a/krita/ui/input/kis_alternate_invocation_action.h b/krita/ui/input/kis_alternate_invocation_action.h
index 5255ea4..bdfc699 100644
--- a/krita/ui/input/kis_alternate_invocation_action.h
+++ b/krita/ui/input/kis_alternate_invocation_action.h
@@ -39,7 +39,7 @@ public:
SecondaryAlternateToggleShortcut, ///< Toggle Secondary mode.
};
- explicit KisAlternateInvocationAction(KisInputManager *manager);
+ explicit KisAlternateInvocationAction();
virtual ~KisAlternateInvocationAction();
void begin(int shortcut, QEvent *event);
diff --git a/krita/ui/input/kis_change_primary_setting_action.cpp b/krita/ui/input/kis_change_primary_setting_action.cpp
index cd7ecd0..738b631 100644
--- a/krita/ui/input/kis_change_primary_setting_action.cpp
+++ b/krita/ui/input/kis_change_primary_setting_action.cpp
@@ -23,11 +23,10 @@
#include "kis_input_manager.h"
#include <KoToolProxy.h>
-KisChangePrimarySettingAction::KisChangePrimarySettingAction(KisInputManager* manager)
- : KisAbstractInputAction(manager)
+KisChangePrimarySettingAction::KisChangePrimarySettingAction()
{
- setName(i18n("Change Tool Primary Setting"));
- setDescription(i18n("Changes a tool's \"Primary Setting\", for example the brush size for the brush tool."));
+ setName(i18n("Change Primary Setting"));
+ setDescription(i18n("The <i>Change Primary Setting</i> action changes a tool's \"Primary Setting\", for example the brush size for the brush tool."));
}
KisChangePrimarySettingAction::~KisChangePrimarySettingAction()
diff --git a/krita/ui/input/kis_change_primary_setting_action.h b/krita/ui/input/kis_change_primary_setting_action.h
index 0efc167..3a1097d 100644
--- a/krita/ui/input/kis_change_primary_setting_action.h
+++ b/krita/ui/input/kis_change_primary_setting_action.h
@@ -30,7 +30,7 @@
class KisChangePrimarySettingAction : public KisAbstractInputAction
{
public:
- explicit KisChangePrimarySettingAction(KisInputManager* manager);
+ explicit KisChangePrimarySettingAction();
virtual ~KisChangePrimarySettingAction();
void begin(int shortcut, QEvent *event);
diff --git a/krita/ui/input/kis_input_manager.cpp b/krita/ui/input/kis_input_manager.cpp
index 667fdcf..6869b54 100644
--- a/krita/ui/input/kis_input_manager.cpp
+++ b/krita/ui/input/kis_input_manager.cpp
@@ -47,6 +47,10 @@
#include "kis_stroke_shortcut.h"
#include "kis_single_action_shortcut.h"
+#include "kis_input_profile.h"
+#include "kis_input_profile_manager.h"
+#include "kis_shortcut_configuration.h"
+
class KisInputManager::Private
{
public:
@@ -65,15 +69,10 @@ public:
bool trySetMirrorMode(const QPointF &mousePosition);
void saveTabletEvent(const QTabletEvent *event);
void resetSavedTabletEvent(QEvent::Type type);
- void addStrokeShortcut(KisAbstractInputAction* action, int index,
- const QList<Qt::Key> &modifiers,
- const QList<Qt::MouseButton> &buttons);
+ void addStrokeShortcut(KisAbstractInputAction* action, int index, const QList< Qt::Key >& modifiers, Qt::MouseButtons buttons);
void addKeyShortcut(KisAbstractInputAction* action, int index,
- const QList<Qt::Key> &modifiers,
- Qt::Key key);
- void addWheelShortcut(KisAbstractInputAction* action, int index,
- const QList<Qt::Key> &modifiers,
- KisSingleActionShortcut::WheelAction wheelAction);
+ const QList<Qt::Key> &modifiers);
+ void addWheelShortcut(KisAbstractInputAction* action, int index, const QList< Qt::Key >& modifiers, KisShortcutConfiguration::MouseWheelMovement wheelAction);
bool processUnhandledEvent(QEvent *event);
Qt::Key workaroundShiftAltMetaHell(const QKeyEvent *keyEvent);
void setupActions();
@@ -117,108 +116,85 @@ static inline QList<Qt::MouseButton> BUTTONS(Qt::MouseButton button1, Qt::MouseB
void KisInputManager::Private::addStrokeShortcut(KisAbstractInputAction* action, int index,
const QList<Qt::Key> &modifiers,
- const QList<Qt::MouseButton> &buttons)
+ Qt::MouseButtons buttons)
{
KisStrokeShortcut *strokeShortcut =
new KisStrokeShortcut(action, index);
- strokeShortcut->setButtons(modifiers, buttons);
+
+ QList<Qt::MouseButton> buttonList;
+ if(buttons & Qt::LeftButton) {
+ buttonList << Qt::LeftButton;
+ }
+ if(buttons & Qt::RightButton) {
+ buttonList << Qt::RightButton;
+ }
+ if(buttons & Qt::MidButton) {
+ buttonList << Qt::MidButton;
+ }
+ if(buttons & Qt::XButton1) {
+ buttonList << Qt::XButton1;
+ }
+ if(buttons & Qt::XButton2) {
+ buttonList << Qt::XButton2;
+ }
+
+ strokeShortcut->setButtons(modifiers, buttonList);
matcher.addShortcut(strokeShortcut);
}
void KisInputManager::Private::addKeyShortcut(KisAbstractInputAction* action, int index,
- const QList<Qt::Key> &modifiers,
- Qt::Key key)
+ const QList<Qt::Key> &keys)
{
KisSingleActionShortcut *keyShortcut =
new KisSingleActionShortcut(action, index);
- keyShortcut->setKey(modifiers, key);
+
+ QList<Qt::Key> modifiers = keys.mid(1);
+ keyShortcut->setKey(modifiers, keys.at(0));
matcher.addShortcut(keyShortcut);
}
void KisInputManager::Private::addWheelShortcut(KisAbstractInputAction* action, int index,
const QList<Qt::Key> &modifiers,
- KisSingleActionShortcut::WheelAction wheelAction)
+ KisShortcutConfiguration::MouseWheelMovement wheelAction)
{
KisSingleActionShortcut *keyShortcut =
new KisSingleActionShortcut(action, index);
- keyShortcut->setWheel(modifiers, wheelAction);
+
+ KisSingleActionShortcut::WheelAction a;
+ switch(wheelAction) {
+ case KisShortcutConfiguration::WheelUp:
+ a = KisSingleActionShortcut::WheelUp;
+ break;
+ case KisShortcutConfiguration::WheelDown:
+ a = KisSingleActionShortcut::WheelDown;
+ break;
+ case KisShortcutConfiguration::WheelLeft:
+ a = KisSingleActionShortcut::WheelLeft;
+ break;
+ case KisShortcutConfiguration::WheelRight:
+ a = KisSingleActionShortcut::WheelRight;
+ break;
+ default:
+ return;
+ }
+
+ keyShortcut->setWheel(modifiers, a);
matcher.addShortcut(keyShortcut);
}
void KisInputManager::Private::setupActions()
{
-#if QT_VERSION >= 0x040700
- Qt::MouseButton middleButton = Qt::MiddleButton;
-#else
- Qt::MouseButton middleButton = Qt::MidButton;
-#endif
-
- //Create all the actions.
- KisAbstractInputAction* action = new KisToolInvocationAction(q);
- matcher.addAction(action);
- addStrokeShortcut(action, KisToolInvocationAction::ActivateShortcut, KEYS(), BUTTONS(Qt::LeftButton));
- addKeyShortcut(action, KisToolInvocationAction::ConfirmShortcut, KEYS(), Qt::Key_Return);
- addKeyShortcut(action, KisToolInvocationAction::ConfirmShortcut, KEYS(), Qt::Key_Enter);
- addKeyShortcut(action, KisToolInvocationAction::CancelShortcut, KEYS(), Qt::Key_Escape);
- defaultInputAction = action;
-
- action = new KisAlternateInvocationAction(q);
- matcher.addAction(action);
- addStrokeShortcut(action, KisAlternateInvocationAction::PrimaryAlternateToggleShortcut, KEYS(Qt::Key_Control), BUTTONS(Qt::LeftButton));
- addStrokeShortcut(action, KisAlternateInvocationAction::SecondaryAlternateToggleShortcut, KEYS(Qt::Key_Control, Qt::Key_Alt), BUTTONS(Qt::LeftButton));
-
- action = new KisChangePrimarySettingAction(q);
- matcher.addAction(action);
- addStrokeShortcut(action, 0, KEYS(Qt::Key_Shift), BUTTONS(Qt::LeftButton));
-
-
- action = new KisPanAction(q);
- matcher.addAction(action);
-
- addStrokeShortcut(action, KisPanAction::PanToggleShortcut, KEYS(Qt::Key_Space), BUTTONS(Qt::LeftButton));
- addStrokeShortcut(action, KisPanAction::PanToggleShortcut, KEYS(), BUTTONS(middleButton));
-
- addKeyShortcut(action, KisPanAction::PanLeftShortcut, KEYS(), Qt::Key_Left);
- addKeyShortcut(action, KisPanAction::PanRightShortcut, KEYS(), Qt::Key_Right);
- addKeyShortcut(action, KisPanAction::PanUpShortcut, KEYS(), Qt::Key_Up);
- addKeyShortcut(action, KisPanAction::PanDownShortcut, KEYS(), Qt::Key_Down);
-
-
- action = new KisRotateCanvasAction(q);
- matcher.addAction(action);
-
- addStrokeShortcut(action, KisRotateCanvasAction::RotateToggleShortcut, KEYS(Qt::Key_Shift, Qt::Key_Space), BUTTONS(Qt::LeftButton));
- addStrokeShortcut(action, KisRotateCanvasAction::DiscreteRotateToggleShortcut, KEYS(Qt::Key_Shift, Qt::Key_Alt, Qt::Key_Space), BUTTONS(Qt::LeftButton));
- addStrokeShortcut(action, KisRotateCanvasAction::RotateToggleShortcut, KEYS(Qt::Key_Shift), BUTTONS(middleButton));
-
- addKeyShortcut(action, KisRotateCanvasAction::RotateLeftShortcut, KEYS(), Qt::Key_4);
- addKeyShortcut(action, KisRotateCanvasAction::RotateResetShortcut, KEYS(), Qt::Key_5);
- addKeyShortcut(action, KisRotateCanvasAction::RotateRightShortcut, KEYS(), Qt::Key_6);
-
-
- action = new KisZoomAction(q);
- matcher.addAction(action);
-
- addStrokeShortcut(action, KisZoomAction::ZoomToggleShortcut, KEYS(Qt::Key_Control), BUTTONS(middleButton));
-
- addStrokeShortcut(action, KisZoomAction::ZoomToggleShortcut, KEYS(Qt::Key_Control, Qt::Key_Space), BUTTONS(Qt::LeftButton));
- addStrokeShortcut(action, KisZoomAction::DiscreteZoomToggleShortcut, KEYS(Qt::Key_Control, Qt::Key_Alt, Qt::Key_Space), BUTTONS(Qt::LeftButton));
-
- addWheelShortcut(action, KisZoomAction::ZoomInShortcut, KEYS(), KisSingleActionShortcut::WheelUp);
- addWheelShortcut(action, KisZoomAction::ZoomOutShortcut, KEYS(), KisSingleActionShortcut::WheelDown);
-
- addKeyShortcut(action, KisZoomAction::ZoomInShortcut, KEYS(), Qt::Key_Plus);
- addKeyShortcut(action, KisZoomAction::ZoomOutShortcut, KEYS(), Qt::Key_Minus);
-
- addKeyShortcut(action, KisZoomAction::ZoomResetShortcut, KEYS(), Qt::Key_1);
- addKeyShortcut(action, KisZoomAction::ZoomToPageShortcut, KEYS(), Qt::Key_2);
- addKeyShortcut(action, KisZoomAction::ZoomToWidthShortcut, KEYS(), Qt::Key_3);
-
- action = new KisShowPaletteAction(q);
- matcher.addAction(action);
+ QList<KisAbstractInputAction*> actions = KisInputProfileManager::instance()->actions();
+ foreach(KisAbstractInputAction *action, actions) {
+ if(dynamic_cast<KisToolInvocationAction*>(action)) {
+ defaultInputAction = action;
+ }
+ }
- addStrokeShortcut(action, 0, KEYS(), BUTTONS(Qt::RightButton));
- addKeyShortcut(action, 0, KEYS(), Qt::Key_F);
+ connect(KisInputProfileManager::instance(), SIGNAL(currentProfileChanged()), q, SLOT(profileChanged()));
+ if(KisInputProfileManager::instance()->currentProfile()) {
+ q->profileChanged();
+ }
}
bool KisInputManager::Private::processUnhandledEvent(QEvent *event)
@@ -452,9 +428,24 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
}
case QEvent::Wheel: {
QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
- KisSingleActionShortcut::WheelAction action =
- wheelEvent->delta() > 0 ?
- KisSingleActionShortcut::WheelUp : KisSingleActionShortcut::WheelDown;
+ KisSingleActionShortcut::WheelAction action;
+
+ if(wheelEvent->orientation() == Qt::Horizontal) {
+ if(wheelEvent->delta() < 0) {
+ action = KisSingleActionShortcut::WheelRight;
+ }
+ else {
+ action = KisSingleActionShortcut::WheelLeft;
+ }
+ }
+ else {
+ if(wheelEvent->delta() > 0) {
+ action = KisSingleActionShortcut::WheelUp;
+ }
+ else {
+ action = KisSingleActionShortcut::WheelDown;
+ }
+ }
retval = d->matcher.wheelEvent(action, wheelEvent);
break;
@@ -466,6 +457,8 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
case QEvent::FocusIn:
//Clear all state so we don't have half-matched shortcuts dangling around.
d->matcher.reset();
+ //Make sure the input actions know we are active.
+ KisAbstractInputAction::setInputManager(this);
break;
case QEvent::TabletPress:
case QEvent::TabletMove:
@@ -535,3 +528,25 @@ QPointF KisInputManager::widgetToPixel(const QPointF& position)
return d->canvas->coordinatesConverter()->widgetToDocument(pixel);
}
+void KisInputManager::profileChanged()
+{
+ d->matcher.reset();
+ d->matcher.clearShortcuts();
+
+ QList<KisShortcutConfiguration*> shortcuts = KisInputProfileManager::instance()->currentProfile()->allShortcuts();
+ foreach(KisShortcutConfiguration *shortcut, shortcuts) {
+ switch(shortcut->type()) {
+ case KisShortcutConfiguration::KeyCombinationType:
+ d->addKeyShortcut(shortcut->action(), shortcut->mode(), shortcut->keys());
+ break;
+ case KisShortcutConfiguration::MouseButtonType:
+ d->addStrokeShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->buttons());
+ break;
+ case KisShortcutConfiguration::MouseWheelType:
+ d->addWheelShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->wheel());
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/krita/ui/input/kis_input_manager.h b/krita/ui/input/kis_input_manager.h
index 1334e7f..9ca1e0a 100644
--- a/krita/ui/input/kis_input_manager.h
+++ b/krita/ui/input/kis_input_manager.h
@@ -90,6 +90,7 @@ public:
private Q_SLOTS:
void setMirrorAxis();
void slotToolChanged();
+ void profileChanged();
private:
class Private;
diff --git a/krita/ui/input/kis_input_profile.cpp b/krita/ui/input/kis_input_profile.cpp
new file mode 100644
index 0000000..0377441
--- /dev/null
+++ b/krita/ui/input/kis_input_profile.cpp
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_profile.h"
+
+#include <QStringList>
+#include <QMultiHash>
+
+#include "kis_abstract_input_action.h"
+#include "kis_shortcut_configuration.h"
+
+class KisInputProfile::Private
+{
+public:
+ Private() { }
+
+ QString name;
+ QMultiHash<KisAbstractInputAction *, KisShortcutConfiguration *> shortcuts;
+};
+
+KisInputProfile::KisInputProfile(QObject *parent)
+ : QObject(parent), d(new Private())
+{
+
+}
+
+KisInputProfile::~KisInputProfile()
+{
+
+}
+
+QString KisInputProfile::name() const
+{
+ return d->name;
+}
+void KisInputProfile::setName(const QString &name)
+{
+ if (d->name != name) {
+ d->name = name;
+ emit nameChanged();
+ }
+}
+
+QList< KisShortcutConfiguration * > KisInputProfile::allShortcuts() const
+{
+ return d->shortcuts.values();
+}
+
+QList< KisShortcutConfiguration * > KisInputProfile::shortcutsForAction(KisAbstractInputAction *action) const
+{
+ if (d->shortcuts.contains(action)) {
+ return d->shortcuts.values(action);
+ }
+
+ return QList<KisShortcutConfiguration *>();
+}
+
+void KisInputProfile::addShortcut(KisShortcutConfiguration *shortcut)
+{
+ Q_ASSERT(shortcut);
+ Q_ASSERT(shortcut->action());
+ d->shortcuts.insert(shortcut->action(), shortcut);
+}
+
+void KisInputProfile::removeShortcut(KisShortcutConfiguration *shortcut)
+{
+ Q_ASSERT(shortcut);
+ Q_ASSERT(shortcut->action());
+ d->shortcuts.remove(shortcut->action(), shortcut);
+}
diff --git a/krita/ui/input/kis_input_profile.h b/krita/ui/input/kis_input_profile.h
new file mode 100644
index 0000000..675e709
--- /dev/null
+++ b/krita/ui/input/kis_input_profile.h
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTPROFILE_H
+#define KISINPUTPROFILE_H
+
+#include <QObject>
+#include <QMetaType>
+
+class KisAbstractInputAction;
+class KisShortcutConfiguration;
+/**
+ * \brief A container class for sets of shortcuts associated with an action.
+ *
+ *
+ */
+class KisInputProfile : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ */
+ KisInputProfile(QObject *parent = 0);
+ /**
+ * Destructor.
+ */
+ virtual ~KisInputProfile();
+
+ /**
+ * \return The name of the profile.
+ */
+ QString name() const;
+
+ /**
+ * \return A list of all shortcuts available.
+ */
+ QList<KisShortcutConfiguration *> allShortcuts() const;
+ /**
+ * \return A list of shortcuts associated with the given action.
+ *
+ * \param action The action for which to list the shortcuts.
+ */
+ QList<KisShortcutConfiguration *> shortcutsForAction(KisAbstractInputAction *action) const;
+
+ /**
+ * Add a shortcut to this profile.
+ *
+ * \param shortcut The shortcut to add.
+ */
+ void addShortcut(KisShortcutConfiguration *shortcut);
+ /**
+ * Remove a shortcut from this profile.
+ *
+ * \param shortcut The shortcut to remove.
+ */
+ void removeShortcut(KisShortcutConfiguration *shortcut);
+
+public Q_SLOTS:
+ /**
+ * Set the name of this profile.
+ *
+ * \param name The name to set.
+ */
+ void setName(const QString &name);
+
+Q_SIGNALS:
+ /**
+ * Emitted when the name of this profile changes.
+ */
+ void nameChanged();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTPROFILE_H
diff --git a/krita/ui/input/kis_input_profile_manager.cpp b/krita/ui/input/kis_input_profile_manager.cpp
new file mode 100644
index 0000000..7b77691
--- /dev/null
+++ b/krita/ui/input/kis_input_profile_manager.cpp
@@ -0,0 +1,287 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_input_profile_manager.h"
+#include "kis_input_profile.h"
+
+#include <QMap>
+#include <QStringList>
+#include <QDir>
+
+#include <KGlobal>
+#include <KStandardDirs>
+#include <KConfig>
+#include <KConfigGroup>
+
+#include "kis_config.h"
+#include "kis_alternate_invocation_action.h"
+#include "kis_change_primary_setting_action.h"
+#include "kis_pan_action.h"
+#include "kis_rotate_canvas_action.h"
+#include "kis_show_palette_action.h"
+#include "kis_tool_invocation_action.h"
+#include "kis_zoom_action.h"
+#include "kis_shortcut_configuration.h"
+
+class KisInputProfileManager::Private
+{
+public:
+ Private() : currentProfile(0) { }
+
+ void createActions();
+ QString profileFileName(const QString &profileName);
+
+ KisInputProfile *currentProfile;
+
+ QMap<QString, KisInputProfile *> profiles;
+
+ QList<KisAbstractInputAction *> actions;
+};
+
+K_GLOBAL_STATIC(KisInputProfileManager, inputProfileManager)
+
+KisInputProfileManager *KisInputProfileManager::instance()
+{
+ return inputProfileManager;
+}
+
+QList< KisInputProfile * > KisInputProfileManager::profiles() const
+{
+ return d->profiles.values();
+}
+
+QStringList KisInputProfileManager::profileNames() const
+{
+ return d->profiles.keys();
+}
+
+KisInputProfile *KisInputProfileManager::profile(const QString &name) const
+{
+ if (d->profiles.contains(name)) {
+ return d->profiles.value(name);
+ }
+
+ return 0;
+}
+
+KisInputProfile *KisInputProfileManager::currentProfile() const
+{
+ return d->currentProfile;
+}
+
+void KisInputProfileManager::setCurrentProfile(KisInputProfile *profile)
+{
+ if (profile && profile != d->currentProfile) {
+ d->currentProfile = profile;
+ emit currentProfileChanged();
+ }
+}
+
+KisInputProfile *KisInputProfileManager::addProfile(const QString &name)
+{
+ if (d->profiles.contains(name)) {
+ return d->profiles.value(name);
+ }
+
+ KisInputProfile *profile = new KisInputProfile(this);
+ profile->setName(name);
+ d->profiles.insert(name, profile);
+
+ emit profilesChanged();
+
+ return profile;
+}
+
+void KisInputProfileManager::removeProfile(const QString &name)
+{
+ if (d->profiles.contains(name)) {
+ QString currentProfileName = d->currentProfile->name();
+
+ delete d->profiles.value(name);
+ d->profiles.remove(name);
+
+ //Delete the settings file for the removed profile, if it exists
+ QDir userDir(KGlobal::dirs()->saveLocation("appdata", "input/"));
+
+ if (userDir.exists(d->profileFileName(name))) {
+ userDir.remove(d->profileFileName(name));
+ }
+
+ if (currentProfileName == name) {
+ d->currentProfile = d->profiles.begin().value();
+ emit currentProfileChanged();
+ }
+
+ emit profilesChanged();
+ }
+}
+
+bool KisInputProfileManager::renameProfile(const QString &oldName, const QString &newName)
+{
+ if (!d->profiles.contains(oldName)) {
+ return false;
+ }
+
+ KisInputProfile *profile = d->profiles.value(oldName);
+ d->profiles.remove(oldName);
+ profile->setName(newName);
+ d->profiles.insert(newName, profile);
+
+ emit profilesChanged();
+
+ return true;
+}
+
+void KisInputProfileManager::duplicateProfile(const QString &name, const QString &newName)
+{
+ if (!d->profiles.contains(name) || d->profiles.contains(newName)) {
+ return;
+ }
+
+ KisInputProfile *newProfile = new KisInputProfile(this);
+ newProfile->setName(newName);
+ d->profiles.insert(newName, newProfile);
+
+ KisInputProfile *profile = d->profiles.value(name);
+ QList<KisShortcutConfiguration *> shortcuts = profile->allShortcuts();
+ Q_FOREACH(KisShortcutConfiguration * shortcut, shortcuts) {
+ newProfile->addShortcut(new KisShortcutConfiguration(*shortcut));
+ }
+
+ emit profilesChanged();
+}
+
+QList< KisAbstractInputAction * > KisInputProfileManager::actions()
+{
+ return d->actions;
+}
+
+void KisInputProfileManager::loadProfiles()
+{
+ //Remove any profiles that already exist
+ d->currentProfile = 0;
+ qDeleteAll(d->profiles);
+ d->profiles.clear();
+
+ //Look up all profiles (this includes those installed to $prefix as well as the user's local data dir)
+ QStringList profiles = KGlobal::dirs()->findAllResources("appdata", "input/*", KStandardDirs::NoDuplicates | KStandardDirs::Recursive);
+ Q_FOREACH(const QString & p, profiles) {
+ //Open the file
+ KConfig config(p, KConfig::SimpleConfig);
+
+ if (!config.hasGroup("General") || !config.group("General").hasKey("name")) {
+ //Skip if we don't have the proper settings.
+ continue;
+ }
+
+ KisInputProfile *newProfile = addProfile(config.group("General").readEntry("name"));
+ Q_FOREACH(KisAbstractInputAction * action, d->actions) {
+ if (!config.hasGroup(action->name())) {
+ continue;
+ }
+
+ KConfigGroup grp = config.group(action->name());
+ //Read the settings for the action and create the appropriate shortcuts.
+ Q_FOREACH(const QString & entry, grp.entryMap()) {
+ KisShortcutConfiguration *shortcut = new KisShortcutConfiguration;
+ shortcut->setAction(action);
+
+ if (shortcut->unserialize(entry)) {
+ newProfile->addShortcut(shortcut);
+ }
+ else {
+ delete shortcut;
+ }
+ }
+ }
+ }
+
+ KisConfig cfg;
+ QString currentProfile = cfg.currentInputProfile();
+
+ if (currentProfile.isEmpty() || !d->profiles.contains(currentProfile)) {
+ d->currentProfile = d->profiles.begin().value();
+ }
+ else {
+ d->currentProfile = d->profiles.value(currentProfile);
+ }
+
+ emit currentProfileChanged();
+}
+
+void KisInputProfileManager::saveProfiles()
+{
+ QString storagePath = KGlobal::dirs()->saveLocation("appdata", "input/");
+ Q_FOREACH(KisInputProfile * p, d->profiles) {
+ QString fileName = d->profileFileName(p->name());
+ KConfig config(storagePath + fileName, KConfig::SimpleConfig);
+
+ config.group("General").writeEntry("name", p->name());
+
+ Q_FOREACH(KisAbstractInputAction * action, d->actions) {
+ KConfigGroup grp = config.group(action->name());
+ grp.deleteGroup(); //Clear the group of any existing shortcuts.
+
+ int index = 0;
+ QList<KisShortcutConfiguration *> shortcuts = p->shortcutsForAction(action);
+ Q_FOREACH(KisShortcutConfiguration * shortcut, shortcuts) {
+ grp.writeEntry(QString("%1").arg(index++), shortcut->serialize());
+ }
+ }
+
+ config.sync();
+ }
+
+ KisConfig config;
+ config.setCurrentInputProfile(d->currentProfile->name());
+
+ //Force a reload of the current profile in input manager and whatever else uses the profile.
+ emit currentProfileChanged();
+}
+
+KisInputProfileManager::KisInputProfileManager(QObject *parent)
+ : QObject(parent), d(new Private())
+{
+ d->createActions();
+}
+
+KisInputProfileManager::~KisInputProfileManager()
+{
+ qDeleteAll(d->profiles);
+ qDeleteAll(d->actions);
+ delete d;
+}
+
+void KisInputProfileManager::Private::createActions()
+{
+ //TODO: Make this plugin based
+ //Note that the ordering here determines how things show up in the UI
+ actions.append(new KisToolInvocationAction());
+ actions.append(new KisAlternateInvocationAction());
+ actions.append(new KisChangePrimarySettingAction());
+ actions.append(new KisPanAction());
+ actions.append(new KisRotateCanvasAction());
+ actions.append(new KisZoomAction());
+ actions.append(new KisShowPaletteAction());
+}
+
+QString KisInputProfileManager::Private::profileFileName(const QString &profileName)
+{
+ return profileName.toLower().replace(QRegExp("[^a-z0-9]"), "").append(".profile");
+}
diff --git a/krita/ui/input/kis_input_profile_manager.h b/krita/ui/input/kis_input_profile_manager.h
new file mode 100644
index 0000000..5ecf112
--- /dev/null
+++ b/krita/ui/input/kis_input_profile_manager.h
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISINPUTPROFILEMANAGER_H
+#define KISINPUTPROFILEMANAGER_H
+
+#include <QObject>
+
+#include "krita_export.h"
+
+class KisAbstractInputAction;
+class KisInputProfile;
+
+/**
+ * \brief A class to manage a list of profiles and actions.
+ *
+ *
+ */
+class KRITAUI_EXPORT KisInputProfileManager : public QObject
+{
+ Q_OBJECT
+public:
+ KisInputProfileManager(QObject *parent = 0);
+ ~KisInputProfileManager();
+ Q_DISABLE_COPY(KisInputProfileManager);
+
+ /**
+ * Retrieve a profile by name.
+ *
+ * \param name The name of the profile to retrieve.
+ *
+ * \return The profile with the given name, or 0 if not found.
+ */
+ KisInputProfile *profile(const QString &name) const;
+ /**
+ * \return A list of all profiles.
+ */
+ QList<KisInputProfile *> profiles() const;
+ /**
+ * \return A list of the names of all profiles.
+ */
+ QStringList profileNames() const;
+
+ /**
+ * \return The current active profile.
+ */
+ KisInputProfile *currentProfile() const;
+ /**
+ * Set the current active profile.
+ *
+ * \param profile The profile to set as current.
+ */
+ void setCurrentProfile(KisInputProfile *profile);
+
+ /**
+ * Add a profile.
+ *
+ * \param name The name of the new profile.
+ *
+ * \return The new, empty profile or the non-empty profile if it already exists.
+ */
+ KisInputProfile *addProfile(const QString &name);
+ /**
+ * Remove a profile.
+ *
+ * This will remove the given profile from the list of profiles and delete it.
+ *
+ * \param name The profile to remove.
+ */
+ void removeProfile(const QString &name);
+ /**
+ * Rename a profile.
+ *
+ * \param oldName The current name of the profile.
+ * \param newName The new name of the profile.
+ *
+ * \return true if successful, false if not.
+ */
+ bool renameProfile(const QString &oldName, const QString &newName);
+ /**
+ * Duplicate a profile.
+ *
+ * This creates a new profile with the given name and copies all
+ * data from the old profile to the new profile.
+ *
+ * \param name The name of the profile to duplicate.
+ * \param newName The name of the new profile.
+ */
+ void duplicateProfile(const QString &name, const QString &newName);
+
+ /**
+ * \return The list of all available actions.
+ */
+ QList< KisAbstractInputAction * > actions();
+
+ /**
+ * Load all profiles from the configuration stored on disk.
+ */
+ void loadProfiles();
+ /**
+ * Save all profiles to configuration on disk.
+ */
+ void saveProfiles();
+
+ /**
+ * \return The singleton instance of this class.
+ */
+ static KisInputProfileManager *instance();
+
+Q_SIGNALS:
+ /**
+ * Emitted when the list of profiles changes.
+ */
+ void profilesChanged();
+ /**
+ * Emitted when the current active profile changes.
+ */
+ void currentProfileChanged();
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif // KISINPUTPROFILEMANAGER_H
diff --git a/krita/ui/input/kis_pan_action.cpp b/krita/ui/input/kis_pan_action.cpp
index a2ca296..7164dbe 100644
--- a/krita/ui/input/kis_pan_action.cpp
+++ b/krita/ui/input/kis_pan_action.cpp
@@ -38,10 +38,11 @@ public:
const int panDistance;
};
-KisPanAction::KisPanAction(KisInputManager *manager)
- : KisAbstractInputAction(manager), d(new Private)
+KisPanAction::KisPanAction()
+ : d(new Private)
{
setName(i18n("Pan Canvas"));
+ setDescription(i18n("The <i>Pan Canvas</i> action pans the canvas."));
QHash<QString, int> shortcuts;
shortcuts.insert(i18n("Toggle Pan Mode"), PanToggleShortcut);
diff --git a/krita/ui/input/kis_pan_action.h b/krita/ui/input/kis_pan_action.h
index 9944271..656789a 100644
--- a/krita/ui/input/kis_pan_action.h
+++ b/krita/ui/input/kis_pan_action.h
@@ -40,7 +40,7 @@ public:
PanDownShortcut ///< Pan down by a fixed amount.
};
- explicit KisPanAction(KisInputManager *manager);
+ explicit KisPanAction();
virtual ~KisPanAction();
void activate();
diff --git a/krita/ui/input/kis_rotate_canvas_action.cpp b/krita/ui/input/kis_rotate_canvas_action.cpp
index 2cc0810..578fda2 100644
--- a/krita/ui/input/kis_rotate_canvas_action.cpp
+++ b/krita/ui/input/kis_rotate_canvas_action.cpp
@@ -36,10 +36,12 @@ public:
};
-KisRotateCanvasAction::KisRotateCanvasAction(KisInputManager* manager)
- : KisAbstractInputAction(manager), d(new Private())
+KisRotateCanvasAction::KisRotateCanvasAction()
+ : d(new Private())
{
setName(i18n("Rotate Canvas"));
+ setDescription(i18n("The <i>Rotate Canvas</i> action rotates the canvas."));
+
QHash<QString, int> shortcuts;
shortcuts.insert(i18n("Toggle Rotate Mode"), RotateToggleShortcut);
shortcuts.insert(i18n("Toggle Discrete Rotate Mode"), DiscreteRotateToggleShortcut);
diff --git a/krita/ui/input/kis_rotate_canvas_action.h b/krita/ui/input/kis_rotate_canvas_action.h
index 30a700f..e247933 100644
--- a/krita/ui/input/kis_rotate_canvas_action.h
+++ b/krita/ui/input/kis_rotate_canvas_action.h
@@ -41,7 +41,7 @@ public:
RotateRightShortcut, ///< Rotate right by a fixed amount.
RotateResetShortcut ///< Reset the rotation to 0.
};
- explicit KisRotateCanvasAction(KisInputManager* manager);
+ explicit KisRotateCanvasAction();
virtual ~KisRotateCanvasAction();
void activate();
diff --git a/krita/ui/input/kis_shortcut_configuration.cpp b/krita/ui/input/kis_shortcut_configuration.cpp
new file mode 100644
index 0000000..3eff2c5
--- /dev/null
+++ b/krita/ui/input/kis_shortcut_configuration.cpp
@@ -0,0 +1,349 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_shortcut_configuration.h"
+
+#include <QStringList>
+#include <QKeySequence>
+#include <KLocalizedString>
+
+class KisShortcutConfiguration::Private
+{
+public:
+ Private()
+ : action(0),
+ type(UnknownType),
+ mode(0),
+ wheel(NoMovement),
+ gesture(NoGesture)
+ { }
+
+ KisAbstractInputAction *action;
+ ShortcutType type;
+ uint mode;
+
+ QList<Qt::Key> keys;
+ Qt::MouseButtons buttons;
+ MouseWheelMovement wheel;
+ GestureAction gesture;
+};
+
+KisShortcutConfiguration::KisShortcutConfiguration()
+ : d(new Private)
+{
+
+}
+
+KisShortcutConfiguration::KisShortcutConfiguration(const KisShortcutConfiguration &other)
+ : d(new Private)
+{
+ d->action = other.action();
+ d->type = other.type();
+ d->mode = other.mode();
+ d->keys = other.keys();
+ d->buttons = other.buttons();
+ d->wheel = other.wheel();
+ d->gesture = other.gesture();
+}
+
+KisShortcutConfiguration::~KisShortcutConfiguration()
+{
+ delete d;
+}
+
+QString KisShortcutConfiguration::serialize()
+{
+ QString serialized("{");
+
+ serialized.append(QString::number(d->mode, 16));
+ serialized.append(';');
+ serialized.append(QString::number(d->type, 16));
+ serialized.append(";[");
+
+ for (QList<Qt::Key>::iterator itr = d->keys.begin(); itr != d->keys.end(); ++itr) {
+ serialized.append(QString::number(*itr, 16));
+
+ if (itr + 1 != d->keys.end()) {
+ serialized.append(',');
+ }
+ }
+
+ serialized.append("];");
+
+ serialized.append(QString::number(d->buttons, 16));
+ serialized.append(';');
+ serialized.append(QString::number(d->wheel, 16));
+ serialized.append(';');
+ serialized.append(QString::number(d->gesture, 16));
+ serialized.append('}');
+
+ return serialized;
+}
+
+bool KisShortcutConfiguration::unserialize(const QString &serialized)
+{
+ if (!serialized.startsWith('{'))
+ return false;
+
+ //Parse the serialized data and apply it to the current shortcut
+ QString remainder = serialized;
+
+ //Remove brackets
+ remainder.remove('{').remove('}');
+
+ //Split the remainder by ;
+ QStringList parts = remainder.split(';');
+
+ if (parts.size() < 6)
+ return false; //Invalid input, abort
+
+ //First entry in the list is the mode
+ d->mode = parts.at(0).toUInt();
+
+ //Second entry is the shortcut type
+ d->type = static_cast<ShortcutType>(parts.at(1).toInt());
+
+ if (d->type == UnknownType) {
+ //Reject input that would set this shortcut to "Unknown"
+ return false;
+ }
+
+ //Third entry is the list of keys
+ QString serializedKeys = parts.at(2);
+ //Remove brackets
+ serializedKeys.remove('[').remove(']');
+ //Split by , and add each entry as a key
+ QStringList keylist = serializedKeys.split(',');
+ Q_FOREACH(QString key, keylist) {
+ if (!key.isEmpty()) {
+ d->keys.append(static_cast<Qt::Key>(key.toUInt(0, 16)));
+ }
+ }
+
+ //Fourth entry is the button mask
+ d->buttons = static_cast<Qt::MouseButtons>(parts.at(3).toInt());
+ d->wheel = static_cast<MouseWheelMovement>(parts.at(4).toUInt());
+ d->gesture = static_cast<GestureAction>(parts.at(5).toUInt());
+
+ return true;
+}
+
+KisAbstractInputAction *KisShortcutConfiguration::action() const
+{
+ return d->action;
+}
+
+void KisShortcutConfiguration::setAction(KisAbstractInputAction *newAction)
+{
+ if (d->action != newAction) {
+ d->action = newAction;
+ }
+}
+
+KisShortcutConfiguration::ShortcutType KisShortcutConfiguration::type() const
+{
+ return d->type;
+}
+
+void KisShortcutConfiguration::setType(KisShortcutConfiguration::ShortcutType newType)
+{
+ if (d->type != newType) {
+ d->type = newType;
+ }
+}
+
+uint KisShortcutConfiguration::mode() const
+{
+ return d->mode;
+}
+
+void KisShortcutConfiguration::setMode(uint newMode)
+{
+ if (d->mode != newMode) {
+ d->mode = newMode;
+ }
+}
+
+QList< Qt::Key > KisShortcutConfiguration::keys() const
+{
+ return d->keys;
+}
+
+void KisShortcutConfiguration::setKeys(const QList< Qt::Key > &newKeys)
+{
+ if (d->keys != newKeys) {
+ d->keys = newKeys;
+ }
+}
+
+Qt::MouseButtons KisShortcutConfiguration::buttons() const
+{
+ return d->buttons;
+}
+
+void KisShortcutConfiguration::setButtons(Qt::MouseButtons newButtons)
+{
+ if (d->buttons != newButtons) {
+ d->buttons = newButtons;
+ }
+}
+
+KisShortcutConfiguration::MouseWheelMovement KisShortcutConfiguration::wheel() const
+{
+ return d->wheel;
+}
+
+void KisShortcutConfiguration::setWheel(KisShortcutConfiguration::MouseWheelMovement type)
+{
+ if (d->wheel != type) {
+ d->wheel = type;
+ }
+}
+
+KisShortcutConfiguration::GestureAction KisShortcutConfiguration::gesture() const
+{
+ return d->gesture;
+}
+
+void KisShortcutConfiguration::setGesture(KisShortcutConfiguration::GestureAction type)
+{
+ if (d->gesture != type) {
+ d->gesture = type;
+ }
+}
+
+QString KisShortcutConfiguration::buttonsToText(Qt::MouseButtons buttons)
+{
+ QString text;
+
+ int buttonCount = 0;
+
+ if (buttons & Qt::LeftButton) {
+ text.append(i18nc("Left Mouse Button", "Left"));
+ buttonCount++;
+ }
+
+ if (buttons & Qt::RightButton) {
+ if (buttonCount++ > 0) {
+ text.append(" + ");
+ }
+
+ text.append(i18nc("Right Mouse Button", "Right"));
+ }
+
+ if (buttons & Qt::MidButton) {
+ if (buttonCount++ > 0) {
+ text.append(" + ");
+ }
+
+ text.append(i18nc("Middle Mouse Button", "Middle"));
+ }
+
+ if (buttons & Qt::XButton1) {
+ if (buttonCount++ > 0) {
+ text.append(" + ");
+ }
+
+ text.append(i18nc("Mouse Back Button", "Back"));
+ }
+
+ if (buttons & Qt::XButton1) {
+ if (buttonCount++ > 0) {
+ text.append(" + ");
+ }
+
+ text.append(i18nc("Mouse Forward Button", "Forward"));
+ }
+
+ if (buttonCount == 0) {
+ text.append(i18nc("No input", "None"));
+ }
+ else {
+ text.append(' ');
+ text.append(i18ncp("Mouse Buttons", "Button", "Buttons", buttonCount));
+ }
+
+ return text;
+}
+
+QString KisShortcutConfiguration::keysToText(const QList<Qt::Key> &keys)
+{
+ QString output;
+
+ foreach (Qt::Key key, keys) {
+ if (output.size() > 0) {
+ output.append(" + ");
+ }
+
+ switch (key) { //Because QKeySequence fails for Ctrl, Alt, Shift and Meta
+ case Qt::Key_Control:
+ output.append(i18nc("Ctrl key", "Ctrl"));
+ break;
+
+ case Qt::Key_Meta:
+ output.append(i18nc("Meta key", "Meta"));
+ break;
+
+ case Qt::Key_Alt:
+ output.append(i18nc("Alt key", "Alt"));
+ break;
+
+ case Qt::Key_Shift:
+ output.append(i18nc("Shift key", "Shift"));
+ break;
+
+ default:
+ QKeySequence s(key);
+ output.append(s.toString(QKeySequence::NativeText));
+ break;
+ }
+
+ }
+
+ if (output.size() == 0) {
+ output = i18nc("No input", "None");
+ }
+
+ return output;
+}
+
+QString KisShortcutConfiguration::wheelToText(KisShortcutConfiguration::MouseWheelMovement wheel)
+{
+ switch (wheel) {
+ case KisShortcutConfiguration::WheelUp:
+ return i18n("Mouse Wheel Up");
+ break;
+
+ case KisShortcutConfiguration::WheelDown:
+ return i18n("Mouse Wheel Down");
+ break;
+
+ case KisShortcutConfiguration::WheelLeft:
+ return i18n("Mouse Wheel Left");
+ break;
+
+ case KisShortcutConfiguration::WheelRight:
+ return i18n("Mouse Wheel Right");
+ break;
+
+ default:
+ return i18nc("No input", "None");
+ break;
+ }
+}
diff --git a/krita/ui/input/kis_shortcut_configuration.h b/krita/ui/input/kis_shortcut_configuration.h
new file mode 100644
index 0000000..3e78d41
--- /dev/null
+++ b/krita/ui/input/kis_shortcut_configuration.h
@@ -0,0 +1,261 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2013 Arjen Hiemstra <ahiemstra at heimr.nl>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISSHORTCUTCONFIGURATION_H
+#define KISSHORTCUTCONFIGURATION_H
+
+#include <QList>
+#include <QMetaType>
+
+class QString;
+class KisAbstractInputAction;
+
+/**
+ * \brief A class encapsulating all settings for a single shortcut.
+ *
+ * This class encapsulates mouse buttons, keyboard keys and other settings
+ * related to a single shortcut for a single action.
+ *
+ * \note Each action can have several modes that activate it with usually
+ * different behaviour for each mode. Different shortcuts can activate
+ * different modes.
+ */
+class KisShortcutConfiguration
+{
+public:
+ /**
+ * The type of shortcut, i.e. what kind of input does it expect.
+ */
+ enum ShortcutType {
+ UnknownType, ///< Unknown, empty shortcut.
+ KeyCombinationType, ///< A list of keys that should be pressed.
+ MouseButtonType, ///< A mouse button, possibly with key modifiers.
+ MouseWheelType, ///< Mouse wheel movement, possibly with key modifiers.
+ GestureType, ///< A touch gesture.
+ };
+
+ /**
+ * The type of mouse wheel movement.
+ */
+ enum MouseWheelMovement {
+ NoMovement, ///< No movement.
+ WheelUp, ///< Upwards movement, away from the user.
+ WheelDown, ///< Downwards movement, toward the user.
+ WheelLeft, ///< Left movement.
+ WheelRight, ///< Right movement.
+ };
+
+ /**
+ * The type of gesture.
+ */
+ enum GestureAction {
+ NoGesture, ///< No gesture.
+ PinchGesture, ///< Pinch gesture, fingers moving towards or away from each other.
+ PanGesture, ///< Pan gesture, fingers staying together but moving across the screen.
+ };
+
+ /**
+ * Constructor.
+ */
+ KisShortcutConfiguration();
+ /**
+ * Copy constructor.
+ */
+ KisShortcutConfiguration(const KisShortcutConfiguration &other);
+ /**
+ * Destructor.
+ */
+ virtual ~KisShortcutConfiguration();
+
+ /**
+ * Serialize the data of this shortcut into a string that can be saved into
+ * a configuration file.
+ *
+ * The string will have the following format:
+ *
+ * {mode;type;[key,key];buttons;wheel;gesture}
+ *
+ * with each property serialized into a base-16 integer.
+ *
+ * \return A serialized representation of this shortcut.
+ */
+ QString serialize();
+ /**
+ * Apply the data from a serialized shortcut to this shortcut.
+ *
+ * This method expects a string as described in serialize().
+ *
+ * \param serialized The serialized shortcut.
+ *
+ * \return true if successful, false if an error occurred.
+ *
+ * \sa serialize()
+ */
+ bool unserialize(const QString &serialized);
+
+ /**
+ * \return The action this shortcut is associated with.
+ */
+ KisAbstractInputAction *action() const;
+ /**
+ * Set the action this shortcut should be associated with.
+ *
+ * \param newAction The action to set.
+ */
+ void setAction(KisAbstractInputAction *newAction);
+
+ /**
+ * \return The type of shortcut.
+ */
+ ShortcutType type() const;
+ /**
+ * Set the type of shortcut.
+ *
+ * \param newType The type to set.
+ */
+ void setType(ShortcutType newType);
+
+ /**
+ * \return The mode of the action this shortcut will trigger.
+ */
+ uint mode() const;
+ /**
+ * Set the mode of the action this shortcut will trigger.
+ *
+ * \param newMode The mode to set.
+ */
+ void setMode(uint newMode);
+
+ /**
+ * \return The list of keys that will trigger this shortcut.
+ *
+ * \note Not applicable when type is GestureType.
+ */
+ QList<Qt::Key> keys() const;
+ /**
+ * Set the list of keys that will trigger this shortcut.
+ *
+ * \param newKeys The list of keys to use.
+ *
+ * \note Not applicable when type is GestureType.
+ */
+ void setKeys(const QList<Qt::Key> &newKeys);
+
+ /**
+ * \return The mouse buttons that will trigger this shortcut.
+ *
+ * \note Only applicable when type is MouseButtonType.
+ */
+ Qt::MouseButtons buttons() const;
+ /**
+ * Set the mouse buttons that will trigger this shortcut.
+ *
+ * \param newButtons The mouse buttons to use.
+ *
+ * \note Only applicable when type is MouseButtonType.
+ */
+ void setButtons(Qt::MouseButtons newButtons);
+
+ /**
+ * \return The mouse wheel movement that will trigger this shortcut.
+ *
+ * \note Only applicable when type is MouseWheelType.
+ */
+ MouseWheelMovement wheel() const;
+ /**
+ * Set the mouse wheel movement that will trigger this shortcut.
+ *
+ * \param type The wheel movement to use.
+ *
+ * \note Only applicable when type is MouseWheelType.
+ */
+ void setWheel(MouseWheelMovement type);
+
+ /**
+ * \return The gesture that will trigger this shortcut.
+ *
+ * \note Only applicable when type is GestureType.
+ */
+ GestureAction gesture() const;
+ /**
+ * Set the gesture that will trigger this shortcut.
+ *
+ * \param type The gesture to use.
+ *
+ * \note Only applicable when type is GestureType.
+ */
+ void setGesture(GestureAction type);
+
+ /**
+ * Convert a set of mouse buttons into a user-readable
+ * string.
+ *
+ * This will convert the given set of buttons into a
+ * string that can be shown to a user. For example, the
+ * combination Qt::LeftButton + Qt::RightButton will produce
+ * the string "Left + Right Button".
+ *
+ * \param buttons The buttons to convert.
+ *
+ * \return A string representing the buttons that can be shown
+ * to a user.
+ *
+ * \note An empty set will produce the string "No Input".
+ */
+ static QString buttonsToText(Qt::MouseButtons buttons);
+ /**
+ * Convert a list of keys to a user-readable string.
+ *
+ * This will convert the given list of keys into a string
+ * that can be shown to a user. For example, the list
+ * [Qt::Key_Shift, Qt::Key_Space] will produce the string
+ * "Shift + Space".
+ *
+ * \param keys The keys to convert.
+ *
+ * \return A string representing the keys that can be shown
+ * to a user.
+ *
+ * \note An empty list will produce the string "No Input".
+ */
+ static QString keysToText(const QList<Qt::Key> &keys);
+ /**
+ * Convert the given mouse wheel movement to a string.
+ *
+ * This will convert the given mouse wheel movement into a
+ * string that can be shown to a user. For example, WheelUp
+ * will produce the string "Mouse Wheel Up".
+ *
+ * \param wheel The mouse wheel movement to convert.
+ *
+ * \return A string representing the mouse wheel movement
+ * that can be shown to a user.
+ *
+ * \note NoMovement will produce the string "No Input".
+ */
+ static QString wheelToText(MouseWheelMovement wheel);
+
+private:
+ class Private;
+ Private *const d;
+};
+
+Q_DECLARE_METATYPE(KisShortcutConfiguration *);
+
+#endif // KISSHORTCUTCONFIGURATION_H
diff --git a/krita/ui/input/kis_shortcut_matcher.cpp b/krita/ui/input/kis_shortcut_matcher.cpp
index 0f21108..d2392b5 100644
--- a/krita/ui/input/kis_shortcut_matcher.cpp
+++ b/krita/ui/input/kis_shortcut_matcher.cpp
@@ -213,6 +213,14 @@ void KisShortcutMatcher::suppressAllActions(bool value)
m_d->suppressAllActions = value;
}
+void KisShortcutMatcher::clearShortcuts()
+{
+ qDeleteAll(m_d->singleActionShortcuts);
+ m_d->singleActionShortcuts.clear();
+ qDeleteAll(m_d->strokeShortcuts);
+ m_d->strokeShortcuts.clear();
+}
+
bool KisShortcutMatcher::tryRunWheelShortcut(KisSingleActionShortcut::WheelAction wheelAction, QWheelEvent *event)
{
return tryRunSingleActionShortcutImpl(wheelAction, event, m_d->keys);
diff --git a/krita/ui/input/kis_shortcut_matcher.h b/krita/ui/input/kis_shortcut_matcher.h
index 3e3e7cc..f87dd68 100644
--- a/krita/ui/input/kis_shortcut_matcher.h
+++ b/krita/ui/input/kis_shortcut_matcher.h
@@ -183,6 +183,11 @@ public:
*/
void suppressAllActions(bool value);
+ /**
+ * Remove all shortcuts that have been registered.
+ */
+ void clearShortcuts();
+
private:
friend class KisInputManagerTest;
diff --git a/krita/ui/input/kis_show_palette_action.cpp b/krita/ui/input/kis_show_palette_action.cpp
index 96cfd6b..b6fddaa 100644
--- a/krita/ui/input/kis_show_palette_action.cpp
+++ b/krita/ui/input/kis_show_palette_action.cpp
@@ -25,10 +25,10 @@
#include "kis_input_manager.h"
-KisShowPaletteAction::KisShowPaletteAction(KisInputManager* manager)
- : KisAbstractInputAction(manager)
+KisShowPaletteAction::KisShowPaletteAction()
{
setName(i18n("Show Popup Palette"));
+ setDescription(i18n("The <i>Show Popup Palette</i> displays the popup palette."));
}
KisShowPaletteAction::~KisShowPaletteAction()
diff --git a/krita/ui/input/kis_show_palette_action.h b/krita/ui/input/kis_show_palette_action.h
index ebafab3..5f16a9a 100644
--- a/krita/ui/input/kis_show_palette_action.h
+++ b/krita/ui/input/kis_show_palette_action.h
@@ -29,7 +29,7 @@
class KisShowPaletteAction : public KisAbstractInputAction
{
public:
- explicit KisShowPaletteAction(KisInputManager* manager);
+ explicit KisShowPaletteAction();
virtual ~KisShowPaletteAction();
virtual void begin(int, QEvent *);
diff --git a/krita/ui/input/kis_single_action_shortcut.h b/krita/ui/input/kis_single_action_shortcut.h
index 9660947..d90a9ab 100644
--- a/krita/ui/input/kis_single_action_shortcut.h
+++ b/krita/ui/input/kis_single_action_shortcut.h
@@ -32,7 +32,9 @@ class KRITAUI_EXPORT KisSingleActionShortcut : public KisAbstractShortcut
public:
enum WheelAction {
WheelUp, ///< Mouse wheel moves up.
- WheelDown ///< Mouse wheel moves down.
+ WheelDown, ///< Mouse wheel moves down.
+ WheelLeft, ///< Mouse wheel moves left.
+ WheelRight, ///< Mouse wheel moves right.
};
KisSingleActionShortcut(KisAbstractInputAction *action, int index);
diff --git a/krita/ui/input/kis_tool_invocation_action.cpp b/krita/ui/input/kis_tool_invocation_action.cpp
index 3159af1..0537ba6 100644
--- a/krita/ui/input/kis_tool_invocation_action.cpp
+++ b/krita/ui/input/kis_tool_invocation_action.cpp
@@ -39,11 +39,17 @@ public:
bool active;
};
-KisToolInvocationAction::KisToolInvocationAction(KisInputManager *manager)
- : KisAbstractInputAction(manager), d(new Private(this))
+KisToolInvocationAction::KisToolInvocationAction()
+ : d(new Private(this))
{
setName(i18n("Tool Invocation"));
- setDescription(i18n("Tool Invocation invokes the current tool, for example, using the brush tool, it will start painting."));
+ setDescription(i18n("The <i>Tool Invocation</i> action invokes the current tool, for example, using the brush tool, it will start painting."));
+
+ QHash<QString, int> indexes;
+ indexes.insert(i18n("Activate"), ActivateShortcut);
+ indexes.insert(i18n("Confirm"), ConfirmShortcut);
+ indexes.insert(i18n("Cancel"), CancelShortcut);
+ setShortcutIndexes(indexes);
}
KisToolInvocationAction::~KisToolInvocationAction()
@@ -95,7 +101,7 @@ void KisToolInvocationAction::end(QEvent *event)
if (tabletEvent) {
inputManager()->toolProxy()->tabletEvent(tabletEvent, d->tabletToPixel(tabletEvent->hiResGlobalPos()));
- } else {
+ } else if (mouseEvent) {
inputManager()->toolProxy()->mouseReleaseEvent(mouseEvent, inputManager()->widgetToPixel(mouseEvent->posF()));
}
diff --git a/krita/ui/input/kis_tool_invocation_action.h b/krita/ui/input/kis_tool_invocation_action.h
index 0662c7d..0dc5c62 100644
--- a/krita/ui/input/kis_tool_invocation_action.h
+++ b/krita/ui/input/kis_tool_invocation_action.h
@@ -35,7 +35,7 @@ public:
ConfirmShortcut,
CancelShortcut
};
- explicit KisToolInvocationAction(KisInputManager *manager);
+ explicit KisToolInvocationAction();
virtual ~KisToolInvocationAction();
void begin(int shortcut, QEvent *event);
diff --git a/krita/ui/input/kis_zoom_action.cpp b/krita/ui/input/kis_zoom_action.cpp
index 3d0e96b..8b96a39 100644
--- a/krita/ui/input/kis_zoom_action.cpp
+++ b/krita/ui/input/kis_zoom_action.cpp
@@ -76,10 +76,11 @@ void KisZoomAction::Private::zoomTo(bool zoomIn, QEvent *event)
}
}
-KisZoomAction::KisZoomAction(KisInputManager* manager)
- : KisAbstractInputAction(manager), d(new Private(this))
+KisZoomAction::KisZoomAction()
+ : d(new Private(this))
{
setName(i18n("Zoom Canvas"));
+ setDescription(i18n("The <i>Zoom Canvas</i> action zooms the canvas."));
QHash< QString, int > shortcuts;
shortcuts.insert(i18n("Toggle Zoom Mode"), ZoomToggleShortcut);
diff --git a/krita/ui/input/kis_zoom_action.h b/krita/ui/input/kis_zoom_action.h
index f49a3f4..ba85575 100644
--- a/krita/ui/input/kis_zoom_action.h
+++ b/krita/ui/input/kis_zoom_action.h
@@ -41,7 +41,7 @@ public:
ZoomToPageShortcut, ///< Zoom fit to page.
ZoomToWidthShortcut ///< Zoom fit to width.
};
- explicit KisZoomAction(KisInputManager* manager);
+ explicit KisZoomAction();
virtual ~KisZoomAction();
void activate();
diff --git a/krita/ui/kis_config.cc b/krita/ui/kis_config.cc
index c6e50da..8234289 100644
--- a/krita/ui/kis_config.cc
+++ b/krita/ui/kis_config.cc
@@ -933,6 +933,15 @@ void KisConfig::setToolbarSlider(int sliderNumber, const QString &slider)
m_cfg.writeEntry(QString("toolbarslider_%1").arg(sliderNumber), slider);
}
+QString KisConfig::currentInputProfile() const
+{
+ return m_cfg.readEntry("currentInputProfile", QString());
+}
+
+void KisConfig::setCurrentInputProfile(const QString& name)
+{
+ m_cfg.writeEntry("currentInputProfile", name);
+}
bool KisConfig::useSystemMonitorProfile() const
{
diff --git a/krita/ui/kis_config.h b/krita/ui/kis_config.h
index dace8b7..bed0a98 100644
--- a/krita/ui/kis_config.h
+++ b/krita/ui/kis_config.h
@@ -287,6 +287,9 @@ public:
QString toolbarSlider(int sliderNumber);
void setToolbarSlider(int sliderNumber, const QString &slider);
+ QString currentInputProfile() const;
+ void setCurrentInputProfile(const QString& name);
+
template<class T>
void writeEntry(const QString& name, const T& value) {
m_cfg.writeEntry(name, value);
diff --git a/krita/ui/kis_view2.cpp b/krita/ui/kis_view2.cpp
index 0b9a254..c8b8d84 100644
--- a/krita/ui/kis_view2.cpp
+++ b/krita/ui/kis_view2.cpp
@@ -128,6 +128,7 @@
#include <kis_paintop_preset.h>
#include "ko_favorite_resource_manager.h"
#include "kis_action_manager.h"
+#include "input/kis_input_profile_manager.h"
#include "kis_paintop_box.h"
@@ -407,6 +408,8 @@ KisView2::KisView2(KoPart *part, KisDoc2 * doc, QWidget * parent)
collection->readSettings(&group);
}
+ KisInputProfileManager::instance()->loadProfiles();
+
#if 0
//check for colliding shortcuts
diff --git a/krita/ui/tests/kis_input_manager_test.cpp b/krita/ui/tests/kis_input_manager_test.cpp
index b973f1a..51bfcc8 100644
--- a/krita/ui/tests/kis_input_manager_test.cpp
+++ b/krita/ui/tests/kis_input_manager_test.cpp
@@ -72,7 +72,7 @@ void KisInputManagerTest::testStrokeShortcut()
struct TestingAction : public KisAbstractInputAction
{
- TestingAction() : KisAbstractInputAction(0), m_isHighResolution(false) { reset(); }
+ TestingAction() : KisAbstractInputAction(), m_isHighResolution(false) { reset(); }
~TestingAction() {}
void begin(int shortcut, QEvent *event) { m_beginIndex = shortcut; m_beginNonNull = event;}
More information about the kde-doc-english
mailing list