Krita Source Code Documentation
Loading...
Searching...
No Matches
KKeySequenceButton Class Reference

#include <kkeysequencewidget_p.h>

+ Inheritance diagram for KKeySequenceButton:

Public Member Functions

 KKeySequenceButton (KisKKeySequenceWidgetPrivate *d, QWidget *parent)
 
 ~KKeySequenceButton () override
 

Protected Member Functions

bool event (QEvent *event) override
 
void keyPressEvent (QKeyEvent *event) override
 
void keyReleaseEvent (QKeyEvent *event) override
 

Private Attributes

KisKKeySequenceWidgetPrivate *const d
 

Detailed Description

Definition at line 12 of file kkeysequencewidget_p.h.

Constructor & Destructor Documentation

◆ KKeySequenceButton()

KKeySequenceButton::KKeySequenceButton ( KisKKeySequenceWidgetPrivate * d,
QWidget * parent )
inlineexplicit

Definition at line 17 of file kkeysequencewidget_p.h.

18 : QPushButton(parent),
19 d(d) {}
KisKKeySequenceWidgetPrivate *const d

◆ ~KKeySequenceButton()

KKeySequenceButton::~KKeySequenceButton ( )
override

Definition at line 602 of file kkeysequencewidget.cpp.

603{
604}

Member Function Documentation

◆ event()

bool KKeySequenceButton::event ( QEvent * event)
overrideprotected

Reimplemented for internal reasons.

Definition at line 607 of file kkeysequencewidget.cpp.

608{
609 if (d->isRecording && e->type() == QEvent::KeyPress) {
610 keyPressEvent(static_cast<QKeyEvent *>(e));
611 return true;
612 }
613
614 // The shortcut 'alt+c' ( or any other dialog local action shortcut )
615 // ended the recording and triggered the action associated with the
616 // action. In case of 'alt+c' ending the dialog. It seems that those
617 // ShortcutOverride events get sent even if grabKeyboard() is active.
618 if (d->isRecording && e->type() == QEvent::ShortcutOverride) {
619 e->accept();
620 return true;
621 }
622
623 if (d->isRecording && e->type() == QEvent::ContextMenu) {
624 // is caused by Qt::Key_Menu
625 e->accept();
626 return true;
627 }
628
629 return QPushButton::event(e);
630}
void keyPressEvent(QKeyEvent *event) override

References d, KisKKeySequenceWidgetPrivate::isRecording, and keyPressEvent().

◆ keyPressEvent()

void KKeySequenceButton::keyPressEvent ( QKeyEvent * event)
overrideprotected

Here is the trap, which is different on every OS. On Windows, Qt has incomprehensible rules on translating AltGr-related key sequences into shortcuts. On macOS symbols may confuse Qt when using Cmd+Shift-based shortcuts. * So we should just ask Qt itself what it expects to receive as a shortcut :)

That is exactly what Qt's QKeySequenceEdit does internally.

TODO: in the future replace the whole widget with QKeySequenceEdit, it uses QKeyMapper directly.

Take the first element, which is usually the shortcut form the latin layout of the keyboard

Definition at line 829 of file kkeysequencewidget.cpp.

830{
831 int keyQt = e->key();
832 if (keyQt == -1) {
833 // Qt sometimes returns garbage keycodes, I observed -1, if it doesn't know a key.
834 // We cannot do anything useful with those (several keys have -1, indistinguishable)
835 // and QKeySequence.toString() will also yield a garbage string.
836 KMessageBox::error(this,
837 i18n("The key you just pressed is not supported by Qt."),
838 i18n("Unsupported Key"));
839 return d->cancelRecording();
840 }
841
842 uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
843
844 //don't have the return or space key appear as first key of the sequence when they
845 //were pressed to start editing - catch and them and imitate their effect
846 if (!d->isRecording && ((keyQt == Qt::Key_Return || keyQt == Qt::Key_Space))) {
847 d->startRecording();
848 d->modifierKeys = newModifiers;
850 return;
851 }
852
853 // We get events even if recording isn't active.
854 if (!d->isRecording) {
855 return QPushButton::keyPressEvent(e);
856 }
857
858 e->accept();
859 d->modifierKeys = newModifiers;
860
861 switch (keyQt) {
862 case Qt::Key_AltGr: //or else we get unicode salad
863 return;
864 case Qt::Key_Shift:
865 case Qt::Key_Control:
866 case Qt::Key_Alt:
867 case Qt::Key_Meta:
868 case Qt::Key_Super_L:
869 case Qt::Key_Super_R:
872 break;
873 default:
874
875 if (d->nKey == 0 && !(d->modifierKeys & ~Qt::SHIFT)) {
876 // It's the first key and no modifier pressed. Check if this is
877 // allowed
879 || d->allowModifierless)) {
880 // No it's not
881 return;
882 }
883 }
884
885 // We now have a valid key press.
886 if (keyQt) {
899#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
900 const QList<int> vec = QKeyMapper::possibleKeys(e);
901#else
902 const QList<QKeyCombination> vec = QKeyMapper::possibleKeys(e);
903#endif
904
905 if (!vec.isEmpty() && e->modifiers() != Qt::NoModifier) {
910 keyQt = vec.first();
911 } else if ((keyQt == Qt::Key_Backtab) && (d->modifierKeys & Qt::SHIFT)) {
912 keyQt = Qt::Key_Tab | d->modifierKeys;
913 } else if (isShiftAsModifierAllowed(keyQt)) {
914 keyQt |= d->modifierKeys;
915 } else {
916 keyQt |= (d->modifierKeys & ~Qt::SHIFT);
917 }
918
919 if (d->nKey == 0) {
920 d->keySequence = QKeySequence(keyQt);
921 } else {
922 d->keySequence =
924 }
925
926 d->nKey++;
927 if ((!d->multiKeyShortcutsAllowed) || (d->nKey >= 4)) {
928 d->doneRecording();
929 return;
930 }
933 }
934 }
935}
unsigned int uint
static bool isOkWhenModifierless(int keyQt)
void doneRecording(bool validate=true)
static QKeySequence appendToSequence(const QKeySequence &seq, int keyQt)

References KisKKeySequenceWidgetPrivate::allowModifierless, KisKKeySequenceWidgetPrivate::appendToSequence(), KisKKeySequenceWidgetPrivate::cancelRecording(), KisKKeySequenceWidgetPrivate::controlModifierlessTimeout(), d, KisKKeySequenceWidgetPrivate::doneRecording(), KisKKeySequenceWidgetPrivate::isOkWhenModifierless(), KisKKeySequenceWidgetPrivate::isRecording, KisKKeySequenceWidgetPrivate::keySequence, KisKKeySequenceWidgetPrivate::modifierKeys, KisKKeySequenceWidgetPrivate::multiKeyShortcutsAllowed, KisKKeySequenceWidgetPrivate::nKey, KisKKeySequenceWidgetPrivate::startRecording(), and KisKKeySequenceWidgetPrivate::updateShortcutDisplay().

◆ keyReleaseEvent()

void KKeySequenceButton::keyReleaseEvent ( QKeyEvent * event)
overrideprotected

Definition at line 937 of file kkeysequencewidget.cpp.

938{
939 if (e->key() == -1) {
940 // ignore garbage, see keyPressEvent()
941 return;
942 }
943
944 if (!d->isRecording) {
945 return QPushButton::keyReleaseEvent(e);
946 }
947
948 e->accept();
949
950 uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
951
952 //if a modifier that belongs to the shortcut was released...
953 if ((newModifiers & d->modifierKeys) < d->modifierKeys) {
954 d->modifierKeys = newModifiers;
957 }
958}

References KisKKeySequenceWidgetPrivate::controlModifierlessTimeout(), d, KisKKeySequenceWidgetPrivate::isRecording, KisKKeySequenceWidgetPrivate::modifierKeys, and KisKKeySequenceWidgetPrivate::updateShortcutDisplay().

Member Data Documentation

◆ d

KisKKeySequenceWidgetPrivate* const KKeySequenceButton::d
private

Definition at line 32 of file kkeysequencewidget_p.h.


The documentation for this class was generated from the following files: