diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -272,6 +272,7 @@ input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp input/kis_select_layer_action.cpp + input/KisQtWidgetsTweaker.cpp operations/kis_operation.cpp operations/kis_operation_configuration.cpp diff --git a/libs/ui/KisNodeDelegate.cpp b/libs/ui/KisNodeDelegate.cpp --- a/libs/ui/KisNodeDelegate.cpp +++ b/libs/ui/KisNodeDelegate.cpp @@ -802,6 +802,25 @@ } } } break; + case QEvent::ShortcutOverride : { + QLineEdit *edit = qobject_cast(object); + if (edit && edit == d->edit){ + auto* key = static_cast(event); + if (key->modifiers() == Qt::NoModifier){ + switch (key->key()){ + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Return: + case Qt::Key_Enter: + event->accept(); + return true; + default: break; + } + } + } + + } break; case QEvent::FocusOut : { QLineEdit *edit = qobject_cast(object); if (edit && edit == d->edit) { diff --git a/libs/ui/KisPart.cpp b/libs/ui/KisPart.cpp --- a/libs/ui/KisPart.cpp +++ b/libs/ui/KisPart.cpp @@ -76,6 +76,7 @@ #include "kis_action.h" #include "kis_action_registry.h" +#include "input/KisQtWidgetsTweaker.h" Q_GLOBAL_STATIC(KisPart, s_instance) @@ -104,6 +105,7 @@ KisIdleWatcher idleWatcher; KisAnimationCachePopulator animationCachePopulator; + KisQtWidgetsTweaker qtWidgetsTweaker; void loadActions(); }; @@ -199,6 +201,10 @@ KisMainWindow *KisPart::createMainWindow() { + if(!d->qtWidgetsTweaker.isInstalled()) { + qApp->installEventFilter(&d->qtWidgetsTweaker); + d->qtWidgetsTweaker.setInstalled(true); + } KisMainWindow *mw = new KisMainWindow(); dbgUI <<"mainWindow" << (void*)mw << "added to view" << this; diff --git a/libs/ui/input/KisQtWidgetsTweaker.h b/libs/ui/input/KisQtWidgetsTweaker.h new file mode 100644 --- /dev/null +++ b/libs/ui/input/KisQtWidgetsTweaker.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (C) 2017 Nikita Vertikov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +class QEvent; + +/** + * KisQtWidgetsTweaker is used to make minor adjustments to + * "native" qt widgets' behavior application-wise + * by filtering events adressed to them + * It expected to be installed on the application + */ +class KisQtWidgetsTweaker : public QObject +{ + Q_OBJECT +public: + KisQtWidgetsTweaker(QObject* parent = nullptr); + ~KisQtWidgetsTweaker(); + bool eventFilter(QObject *receiver, QEvent* event); + + + bool isInstalled() const; + void setInstalled(bool isInstalled); + +private: + bool _isInstalled; +}; diff --git a/libs/ui/input/KisQtWidgetsTweaker.cpp b/libs/ui/input/KisQtWidgetsTweaker.cpp new file mode 100644 --- /dev/null +++ b/libs/ui/input/KisQtWidgetsTweaker.cpp @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2017 Nikita Vertikov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "KisQtWidgetsTweaker.h" + +#include +#include +#include +#include + + +KisQtWidgetsTweaker::KisQtWidgetsTweaker(QObject *parent) + :QObject(parent), _isInstalled(false) +{ + +} + +KisQtWidgetsTweaker::~KisQtWidgetsTweaker() +{ + +} + +bool KisQtWidgetsTweaker::eventFilter(QObject *receiver, QEvent *event) +{ + + //QLineEdit lets qt's shortcut system take away it's keyboard events + //even is it knows them, such as ctrl+backspace + //if there is application-wide shortcut, assigned to it. + //The following compound statement fixes it + //by accepting ShortcutOverride events. + { + if( (qobject_cast(receiver) != nullptr) + && (event->type() == QEvent::ShortcutOverride) ){ + static constexpr QKeySequence::StandardKey actionsForQLineEdit[]{ + QKeySequence::MoveToNextChar + ,QKeySequence::MoveToPreviousChar + ,QKeySequence::MoveToStartOfLine + ,QKeySequence::MoveToEndOfLine + ,QKeySequence::MoveToPreviousWord + ,QKeySequence::MoveToNextWord + ,QKeySequence::SelectPreviousChar + ,QKeySequence::SelectNextChar + ,QKeySequence::SelectNextWord + ,QKeySequence::SelectPreviousWord + ,QKeySequence::SelectStartOfLine + ,QKeySequence::SelectEndOfLine + ,QKeySequence::SelectAll + ,QKeySequence::Deselect + ,QKeySequence::Backspace + ,QKeySequence::DeleteStartOfWord + ,QKeySequence::Delete + ,QKeySequence::DeleteEndOfWord + ,QKeySequence::DeleteEndOfLine + ,QKeySequence::Copy + ,QKeySequence::Paste + ,QKeySequence::Cut + ,QKeySequence::Undo + ,QKeySequence::Redo + }; + auto* key = static_cast(event); + for(QKeySequence::StandardKey sk : actionsForQLineEdit){ + if (key->matches(sk)){ + event->accept(); + return true; + } + } + } + } + + //code for tweaking the bahavior of other qt elements will go here + return false; +} + +bool KisQtWidgetsTweaker::isInstalled() const +{ + return _isInstalled; +} + +void KisQtWidgetsTweaker::setInstalled(bool isInstalled) +{ + _isInstalled = isInstalled; +}