1 /* This file is part of the KDE project
2  * Copyright (C) 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "kis_alternate_invocation_action.h"
20 
21 #include <QApplication>
22 #include <klocalizedstring.h>
23 
24 #include <kis_tool_proxy.h>
25 #include <kis_canvas2.h>
26 
27 #include "kis_input_manager.h"
28 #include "kis_cursor.h"
29 
30 struct KisAlternateInvocationAction::Private
31 {
32     KisTool::ToolAction savedAction;
33 };
34 
KisAlternateInvocationAction()35 KisAlternateInvocationAction::KisAlternateInvocationAction()
36     : KisAbstractInputAction("Alternate Invocation")
37     , m_d(new Private)
38 {
39     setName(i18n("Alternate Invocation"));
40     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."));
41     QHash<QString, int> shortcuts;
42     shortcuts.insert(i18n("Primary Mode"), PrimaryAlternateModeShortcut);
43     shortcuts.insert(i18n("Secondary Mode"), SecondaryAlternateModeShortcut);
44     shortcuts.insert(i18n("Tertiary Mode"), TertiaryAlternateModeShortcut);
45 
46 
47     shortcuts.insert(i18n("Pick Foreground Color from Current Layer"), PickColorFgLayerModeShortcut);
48     shortcuts.insert(i18n("Pick Background Color from Current Layer"), PickColorBgLayerModeShortcut);
49 
50     shortcuts.insert(i18n("Pick Foreground Color from Merged Image"), PickColorFgImageModeShortcut);
51     shortcuts.insert(i18n("Pick Background Color from Merged Image"), PickColorBgImageModeShortcut);
52 
53     setShortcutIndexes(shortcuts);
54 }
55 
~KisAlternateInvocationAction()56 KisAlternateInvocationAction::~KisAlternateInvocationAction()
57 {
58 }
59 
shortcutToToolAction(int shortcut) const60 KisTool::ToolAction KisAlternateInvocationAction::shortcutToToolAction(int shortcut) const
61 {
62     KisTool::ToolAction action = KisTool::Alternate_NONE;
63 
64     switch ((Shortcut)shortcut) {
65     case PickColorFgLayerModeShortcut:
66         action = KisTool::AlternatePickFgNode;
67         break;
68     case PickColorBgLayerModeShortcut:
69         action = KisTool::AlternatePickBgNode;
70         break;
71     case PickColorFgImageModeShortcut:
72         action = KisTool::AlternatePickFgImage;
73         break;
74     case PickColorBgImageModeShortcut:
75         action = KisTool::AlternatePickBgImage;
76         break;
77     case PrimaryAlternateModeShortcut:
78         action = KisTool::AlternateSecondary;
79         break;
80     case SecondaryAlternateModeShortcut:
81         action = KisTool::AlternateThird;
82         break;
83     case TertiaryAlternateModeShortcut:
84         action = KisTool::AlternateFourth;
85         break;
86     }
87 
88     return action;
89 }
90 
activate(int shortcut)91 void KisAlternateInvocationAction::activate(int shortcut)
92 {
93     KisTool::ToolAction action = shortcutToToolAction(shortcut);
94     inputManager()->toolProxy()->activateToolAction(action);
95 }
96 
deactivate(int shortcut)97 void KisAlternateInvocationAction::deactivate(int shortcut)
98 {
99     KisTool::ToolAction action = shortcutToToolAction(shortcut);
100     inputManager()->toolProxy()->deactivateToolAction(action);
101 }
102 
priority() const103 int KisAlternateInvocationAction::priority() const
104 {
105     return 9;
106 }
107 
begin(int shortcut,QEvent * event)108 void KisAlternateInvocationAction::begin(int shortcut, QEvent *event)
109 {
110     if (!event) return;
111 
112     KisAbstractInputAction::begin(shortcut, event);
113 
114     QMouseEvent targetEvent(QEvent::MouseButtonPress, eventPosF(event), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); // There must be a better way
115 
116     m_d->savedAction = shortcutToToolAction(shortcut);
117 
118     inputManager()->toolProxy()->forwardEvent(KisToolProxy::BEGIN, m_d->savedAction, &targetEvent, event);
119 }
120 
end(QEvent * event)121 void KisAlternateInvocationAction::end(QEvent *event)
122 {
123     if (!event) return;
124 
125     Qt::KeyboardModifiers modifiers;
126 
127     switch (m_d->savedAction) {
128     case KisTool::AlternatePickFgNode:
129         modifiers = Qt::ControlModifier;
130         break;
131     case KisTool::AlternateThird:
132         modifiers = Qt::ControlModifier | Qt::AltModifier;
133         break;
134     default:
135         ;
136     }
137 
138     QMouseEvent targetEvent = QMouseEvent(QEvent::MouseButtonRelease, eventPosF(event), Qt::LeftButton, Qt::LeftButton, modifiers);
139     inputManager()->toolProxy()->forwardEvent(KisToolProxy::END, m_d->savedAction, &targetEvent, event);
140 
141     KisAbstractInputAction::end(event);
142 }
143 
inputEvent(QEvent * event)144 void KisAlternateInvocationAction::inputEvent(QEvent* event)
145 {
146     if (event && ((event->type() == QEvent::MouseMove) || (event->type() == QEvent::TabletMove))) {
147         Qt::KeyboardModifiers modifiers;
148         switch (m_d->savedAction) {
149         case KisTool::AlternatePickFgNode:
150             modifiers =  Qt::ControlModifier;
151             break;
152         case KisTool::AlternateThird:
153             modifiers = Qt::ControlModifier | Qt::AltModifier;
154             break;
155         default:
156             modifiers = Qt::ShiftModifier;
157         }
158 
159         QMouseEvent targetEvent(QEvent::MouseMove, eventPosF(event), Qt::LeftButton, Qt::LeftButton, modifiers);
160         inputManager()->toolProxy()->forwardEvent(KisToolProxy::CONTINUE, m_d->savedAction, &targetEvent, event);
161     }
162 }
163 
supportsHiResInputEvents(int shortcut) const164 bool KisAlternateInvocationAction::supportsHiResInputEvents(int shortcut) const
165 {
166     return inputManager()->toolProxy()->alternateActionSupportsHiResEvents(
167         KisTool::actionToAlternateAction(shortcutToToolAction(shortcut)));
168 }
169