Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_shortcut_configuration.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the KDE project
3 * SPDX-FileCopyrightText: 2013 Arjen Hiemstra <ahiemstra@heimr.nl>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include <QStringList>
11#include <QKeySequence>
12#include <KLocalizedString>
13
14#include <boost/preprocessor/repeat_from_to.hpp>
15
36
42
44 : d(new Private)
45{
46 d->action = other.action();
47 d->type = other.type();
48 d->mode = other.mode();
49 d->keys = other.keys();
50 d->buttons = other.buttons();
51 d->wheel = other.wheel();
52 d->gesture = other.gesture();
53}
54
56{
57 d->action = other.action();
58 d->type = other.type();
59 d->mode = other.mode();
60 d->keys = other.keys();
61 d->buttons = other.buttons();
62 d->wheel = other.wheel();
63 d->gesture = other.gesture();
64
65 return *this;
66}
67
69{
70 return d->type == other.d->type && d->keys == other.d->keys && d->buttons == other.d->buttons
71 && d->wheel == other.d->wheel && d->gesture == other.d->gesture;
72}
73
78
80{
81 QString serialized("{");
82
83 serialized.append(QString::number(d->mode, 16));
84 serialized.append(';');
85#ifdef Q_OS_MACOS
86 if (d->type == GestureType) {
87 serialized.append(QString::number(MacOSGestureType, 16));
88 } else {
89 serialized.append(QString::number(d->type, 16));
90 }
91#else
92 serialized.append(QString::number(d->type, 16));
93#endif
94 serialized.append(";[");
95
96 for (QList<Qt::Key>::iterator itr = d->keys.begin(); itr != d->keys.end(); ++itr) {
97 serialized.append(QString::number(*itr, 16));
98
99 if (itr + 1 != d->keys.end()) {
100 serialized.append(',');
101 }
102 }
103
104 serialized.append("];");
105
106 serialized.append(QString::number(d->buttons, 16));
107 serialized.append(';');
108 serialized.append(QString::number(d->wheel, 16));
109 serialized.append(';');
110 serialized.append(QString::number(d->gesture, 16));
111 serialized.append('}');
112
113 return serialized;
114}
115
116bool KisShortcutConfiguration::unserialize(const QString &serialized)
117{
118 if (!serialized.startsWith('{'))
119 return false;
120
121 //Parse the serialized data and apply it to the current shortcut
122 QString remainder = serialized;
123
124 //Remove brackets
125 remainder.remove('{').remove('}');
126
127 //Split the remainder by ;
128 QStringList parts = remainder.split(';');
129
130 if (parts.size() < 6)
131 return false; //Invalid input, abort
132
133 //First entry in the list is the mode
134 d->mode = parts.at(0).toUInt(nullptr, 16);
135
136 //Second entry is the shortcut type
137 d->type = static_cast<ShortcutType>(parts.at(1).toInt(nullptr, 16));
138
139 if (d->type == UnknownType) {
140 //Reject input that would set this shortcut to "Unknown"
141 return false;
142 }
143
144#ifdef Q_OS_MACOS
145 // On MacOS, the GestureType gestures aren't handled. But! MacOSGestureType gestures are handled as
146 // GestureTypes. Confusing? Yes, but this is done only here (and when serializing).
147 if (d->type == GestureType) {
148 return false;
149 }
150 if (d->type == MacOSGestureType) {
151 d->type = GestureType;
152 }
153#else
154 // only macOS platform handles these gestures
155 if (d->type == MacOSGestureType) {
156 return false;
157 }
158#endif
159
160 //Third entry is the list of keys
161 QString serializedKeys = parts.at(2);
162 //Remove brackets
163 serializedKeys.remove('[').remove(']');
164 //Split by , and add each entry as a key
165 QStringList keylist = serializedKeys.split(',');
166 Q_FOREACH(QString key, keylist) {
167 if (!key.isEmpty()) {
168 d->keys.append(static_cast<Qt::Key>(key.toUInt(nullptr, 16)));
169 }
170 }
171
172 //Fourth entry is the button mask
173 d->buttons = static_cast<Qt::MouseButtons>(parts.at(3).toInt(nullptr, 16));
174 d->wheel = static_cast<MouseWheelMovement>(parts.at(4).toUInt(nullptr, 16));
175 d->gesture = static_cast<GestureAction>(parts.at(5).toUInt(nullptr, 16));
176
177 return true;
178}
179
184
186{
187 if (d->action != newAction) {
188 d->action = newAction;
189 }
190}
191
196
198{
199 if (d->type != newType) {
200 d->type = newType;
201 }
202}
203
205{
206 return d->mode;
207}
208
210{
211 if (d->mode != newMode) {
212 d->mode = newMode;
213 }
214}
215
220
222{
223 if (d->keys != newKeys) {
224 d->keys = newKeys;
225 }
226}
227
228Qt::MouseButtons KisShortcutConfiguration::buttons() const
229{
230 return d->buttons;
231}
232
233void KisShortcutConfiguration::setButtons(Qt::MouseButtons newButtons)
234{
235 if (d->buttons != newButtons) {
236 d->buttons = newButtons;
237 }
238}
239
244
251
256
263
265{
266 return d->type == UnknownType || (d->type == KeyCombinationType && d->keys.isEmpty())
267 || (d->type == MouseButtonType && d->buttons.testFlag(Qt::NoButton))
268 || (d->type == MouseWheelType && d->wheel == NoMovement)
269 || ((d->type == GestureType || d->type == MacOSGestureType)
270 && (d->gesture == NoGesture || d->gesture == MaxGesture));
271}
272
274{
275 switch (d->type) {
277 return keysToText(d->keys);
278 case MouseButtonType:
279 return buttonsInputToText(d->keys, d->buttons);
280 case MouseWheelType:
281 return wheelInputToText(d->keys, d->wheel);
282 case GestureType:
283 case MacOSGestureType:
284 return gestureToText(d->gesture);
285 default:
286 return QString();
287 }
288}
289
291{
292 QString text;
293 QString sep = i18nc("Separator in the list of mouse buttons for shortcut", " + ");
294
295 int buttonCount = 0;
296
297 if (buttons & Qt::LeftButton) {
298 text.append(i18nc("Left Mouse Button", "Left"));
299 buttonCount++;
300 }
301
302 if (buttons & Qt::RightButton) {
303 if (buttonCount++ > 0) {
304 text.append(sep);
305 }
306
307 text.append(i18nc("Right Mouse Button", "Right"));
308 }
309
310 if (buttons & Qt::MiddleButton) {
311 if (buttonCount++ > 0) {
312 text.append(sep);
313 }
314
315 text.append(i18nc("Middle Mouse Button", "Middle"));
316 }
317
318 if (buttons & Qt::BackButton) {
319 if (buttonCount++ > 0) {
320 text.append(sep);
321 }
322
323 text.append(i18nc("Mouse Back Button", "Back"));
324 }
325
326 if (buttons & Qt::ForwardButton) {
327 if (buttonCount++ > 0) {
328 text.append(sep);
329 }
330
331 text.append(i18nc("Mouse Forward Button", "Forward"));
332 }
333
334 if (buttons & Qt::TaskButton) {
335 if (buttonCount++ > 0) {
336 text.append(sep);
337 }
338
339 text.append(i18nc("Mouse Task Button", "Task"));
340 }
341
342// Qt supports up to ExtraButton24 so include those
343#define EXTRA_BUTTON(z, n, _)\
344 if (buttons & Qt::ExtraButton##n) { \
345 if (buttonCount++ > 0) { text.append(sep); } \
346 text.append(i18nc("Mouse Button", "Mouse %1", n + 3)); \
347 }
348BOOST_PP_REPEAT_FROM_TO(4, 25, EXTRA_BUTTON, _)
349#undef EXTRA_BUTTON
350
351 if (buttonCount == 0) {
352 text.append(i18nc("No mouse buttons for shortcut", "None"));
353 }
354 else {
355 text = i18ncp(
356 "%1 = List of mouse buttons for shortcut. "
357 "Plural form is chosen upon the number of buttons in that list.",
358 "%1 Button", "%1 Buttons", text, buttonCount);
359 }
360
361 return text;
362}
363
365{
366 QString output;
367
368 Q_FOREACH (Qt::Key key, keys) {
369#if defined(Q_OS_MAC)
370 // This works for modifier keys on macOS but not other platforms.
371 // They are shown with symbols, so no translation or separators needed.
372 output.append(QKeySequence(key).toString(QKeySequence::NativeText));
373#else
374 if (output.size() > 0) {
375 output.append(i18nc("Separator in the list of keys for shortcut", " + "));
376 }
377
378 switch (key) { //Because QKeySequence fails for Ctrl, Alt, Shift and Meta
379 case Qt::Key_Control:
380 output.append(i18nc("Ctrl key", "Ctrl"));
381 break;
382
383 case Qt::Key_Meta:
384 output.append(i18nc("Meta key", "Meta"));
385 break;
386
387 case Qt::Key_Alt:
388 output.append(i18nc("Alt key", "Alt"));
389 break;
390
391 case Qt::Key_Shift:
392 output.append(i18nc("Shift key", "Shift"));
393 break;
394
395 default:
396 QKeySequence s(key);
397 output.append(s.toString(QKeySequence::NativeText));
398 break;
399 }
400#endif
401 }
402
403 if (output.size() == 0) {
404 output = i18nc("No keys for shortcut", "None");
405 }
406
407 return output;
408}
409
411{
412 switch (wheel) {
414 return i18n("Mouse Wheel Up");
415 break;
416
418 return i18n("Mouse Wheel Down");
419 break;
420
422 return i18n("Mouse Wheel Left");
423 break;
424
426 return i18n("Mouse Wheel Right");
427 break;
428
430 return i18n("Trackpad Pan");
431 break;
432
433 default:
434 return i18nc("No mouse wheel buttons for shortcut", "None");
435 break;
436 }
437}
438
440{
442
443 if (keys.size() > 0) {
444 return i18nc(
445 "%1 = modifier keys in shortcut; %2 = mouse buttons in shortcut",
446 "%1 + %2",
448 buttonsText);
449 }
450 else {
451 return buttonsText;
452 }
453}
454
456{
457 QString wheelText = KisShortcutConfiguration::wheelToText(wheel);
458
459 if (keys.size() > 0) {
460 return i18nc(
461 "%1 = modifier keys in shortcut; %2 = mouse wheel buttons in shortcut",
462 "%1 + %2",
464 wheelText);
465 }
466 else {
467 return wheelText;
468 }
469}
470
472{
473 switch (action) {
474#ifdef Q_OS_MACOS
475 case PinchGesture:
476 return i18n("Pinch Gesture");
477 case PanGesture:
478 return i18n("Pan Gesture");
479 case RotateGesture:
480 return i18n("Rotate Gesture");
481 case SmartZoomGesture:
482 return i18n("Smart Zoom Gesture");
483#else
484 case OneFingerTap:
485 return i18n("One Finger Tap");
486 case TwoFingerTap:
487 return i18n("Two Finger Tap");
488 case ThreeFingerTap:
489 return i18n("Three Finger Tap");
490 case FourFingerTap:
491 return i18n("Four Finger Tap");
492 case FiveFingerTap:
493 return i18n("Five Finger Tap");
494 case OneFingerDrag:
495 return i18n("One Finger Drag");
496 case TwoFingerDrag:
497 return i18n("Two Finger Drag");
498 case ThreeFingerDrag:
499 return i18n("Three Finger Drag");
500 case FourFingerDrag:
501 return i18n("Four Finger Drag");
502 case FiveFingerDrag:
503 return i18n("Five Finger Drag");
504#endif
505 default:
506 return i18n("No Gesture");
507 }
508}
unsigned int uint
Abstract base class for input actions.
A class encapsulating all settings for a single shortcut.
void setButtons(Qt::MouseButtons newButtons)
void setWheel(MouseWheelMovement type)
bool operator==(const KisShortcutConfiguration &other) const
static QString buttonsToText(Qt::MouseButtons buttons)
static QString keysToText(const QList< Qt::Key > &keys)
KisAbstractInputAction * action() const
@ MouseButtonType
A mouse button, possibly with key modifiers.
@ MouseWheelType
Mouse wheel movement, possibly with key modifiers.
@ KeyCombinationType
A list of keys that should be pressed.
@ UnknownType
Unknown, empty shortcut.
KisShortcutConfiguration & operator=(const KisShortcutConfiguration &other)
static QString wheelInputToText(const QList< Qt::Key > &keys, MouseWheelMovement wheel)
bool unserialize(const QString &serialized)
static QString wheelToText(MouseWheelMovement wheel)
void setAction(KisAbstractInputAction *newAction)
void setType(ShortcutType newType)
void setKeys(const QList< Qt::Key > &newKeys)
@ WheelTrackpad
A pan movement on a trackpad.
@ WheelDown
Downwards movement, toward the user.
@ WheelUp
Upwards movement, away from the user.
static QString gestureToText(GestureAction action)
static QString buttonsInputToText(const QList< Qt::Key > &keys, Qt::MouseButtons buttons)
#define EXTRA_BUTTON(z, n, _)
QString buttons(const T &ev)
#define _(s)
Definition xcftools.h:32