Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 1998 Mark Donohoe <donohoe@kde.org>
|
||||
SPDX-FileCopyrightText: 2001 Ellis Whitehead <ellis@kde.org>
|
||||
SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com>
|
||||
SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "config-xmlgui.h"
|
||||
|
||||
#include "kkeysequencewidget.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "kactioncollection.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHash>
|
||||
#include <QToolButton>
|
||||
|
||||
#include <KKeySequenceRecorder>
|
||||
#include <KLocalizedString>
|
||||
#include <KMessageBox>
|
||||
#if HAVE_GLOBALACCEL
|
||||
#include <KGlobalAccel>
|
||||
#endif
|
||||
|
||||
static constexpr QStringView inputRecordingMarkupSuffix(u" …");
|
||||
|
||||
static bool shortcutsConflictWith(const QList<QKeySequence> &shortcuts, const QKeySequence &needle)
|
||||
{
|
||||
if (needle.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const QKeySequence &sequence : shortcuts) {
|
||||
if (sequence.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sequence.matches(needle) != QKeySequence::NoMatch //
|
||||
|| needle.matches(sequence) != QKeySequence::NoMatch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class KKeySequenceWidgetPrivate
|
||||
{
|
||||
public:
|
||||
KKeySequenceWidgetPrivate(KKeySequenceWidget *qq);
|
||||
|
||||
void init();
|
||||
|
||||
void updateShortcutDisplay();
|
||||
void startRecording();
|
||||
|
||||
// Conflicts the key sequence @p seq with a current standard shortcut?
|
||||
bool conflictWithStandardShortcuts(const QKeySequence &seq);
|
||||
// Conflicts the key sequence @p seq with a current local shortcut?
|
||||
bool conflictWithLocalShortcuts(const QKeySequence &seq);
|
||||
// Conflicts the key sequence @p seq with a current global shortcut?
|
||||
bool conflictWithGlobalShortcuts(const QKeySequence &seq);
|
||||
|
||||
bool promptStealLocalShortcut(const QList<QAction *> &actions, const QKeySequence &seq);
|
||||
bool promptstealStandardShortcut(KStandardShortcut::StandardShortcut std, const QKeySequence &seq);
|
||||
|
||||
#if HAVE_GLOBALACCEL
|
||||
struct KeyConflictInfo {
|
||||
QKeySequence key;
|
||||
QList<KGlobalShortcutInfo> shortcutInfo;
|
||||
};
|
||||
bool promptStealGlobalShortcut(const std::vector<KeyConflictInfo> &shortcuts, const QKeySequence &sequence);
|
||||
#endif
|
||||
void wontStealShortcut(QAction *item, const QKeySequence &seq);
|
||||
|
||||
bool checkAgainstStandardShortcuts() const
|
||||
{
|
||||
return checkAgainstShortcutTypes & KKeySequenceWidget::StandardShortcuts;
|
||||
}
|
||||
|
||||
bool checkAgainstGlobalShortcuts() const
|
||||
{
|
||||
return checkAgainstShortcutTypes & KKeySequenceWidget::GlobalShortcuts;
|
||||
}
|
||||
|
||||
bool checkAgainstLocalShortcuts() const
|
||||
{
|
||||
return checkAgainstShortcutTypes & KKeySequenceWidget::LocalShortcuts;
|
||||
}
|
||||
|
||||
// private slot
|
||||
void doneRecording();
|
||||
|
||||
// members
|
||||
KKeySequenceWidget *const q;
|
||||
KKeySequenceRecorder *recorder;
|
||||
QHBoxLayout *layout;
|
||||
QPushButton *keyButton;
|
||||
QToolButton *clearButton;
|
||||
|
||||
QKeySequence keySequence;
|
||||
QKeySequence oldKeySequence;
|
||||
QString componentName;
|
||||
|
||||
//! Check the key sequence against KStandardShortcut::find()
|
||||
KKeySequenceWidget::ShortcutTypes checkAgainstShortcutTypes;
|
||||
|
||||
/**
|
||||
* The list of action collections to check against for conflict shortcut
|
||||
*/
|
||||
QList<KActionCollection *> checkActionCollections;
|
||||
|
||||
/**
|
||||
* The action to steal the shortcut from.
|
||||
*/
|
||||
QList<QAction *> stealActions;
|
||||
};
|
||||
|
||||
KKeySequenceWidgetPrivate::KKeySequenceWidgetPrivate(KKeySequenceWidget *qq)
|
||||
: q(qq)
|
||||
, layout(nullptr)
|
||||
, keyButton(nullptr)
|
||||
, clearButton(nullptr)
|
||||
, componentName()
|
||||
, checkAgainstShortcutTypes(KKeySequenceWidget::LocalShortcuts | KKeySequenceWidget::GlobalShortcuts)
|
||||
, stealActions()
|
||||
{
|
||||
}
|
||||
|
||||
void KKeySequenceWidgetPrivate::init()
|
||||
{
|
||||
layout = new QHBoxLayout(q);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
keyButton = new QPushButton(q);
|
||||
keyButton->setFocusPolicy(Qt::StrongFocus);
|
||||
keyButton->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
|
||||
keyButton->setToolTip(
|
||||
i18nc("@info:tooltip",
|
||||
"Click on the button, then enter the shortcut like you would in the program.\nExample for Ctrl+A: hold the Ctrl key and press A."));
|
||||
layout->addWidget(keyButton);
|
||||
|
||||
clearButton = new QToolButton(q);
|
||||
layout->addWidget(clearButton);
|
||||
|
||||
if (qApp->isLeftToRight()) {
|
||||
clearButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-locationbar-rtl")));
|
||||
} else {
|
||||
clearButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-locationbar-ltr")));
|
||||
}
|
||||
|
||||
recorder = new KKeySequenceRecorder(q->window()->windowHandle(), q);
|
||||
recorder->setModifierlessAllowed(false);
|
||||
recorder->setMultiKeyShortcutsAllowed(true);
|
||||
|
||||
updateShortcutDisplay();
|
||||
}
|
||||
|
||||
bool KKeySequenceWidgetPrivate::promptStealLocalShortcut(const QList<QAction *> &actions, const QKeySequence &seq)
|
||||
{
|
||||
const int listSize = actions.size();
|
||||
|
||||
QString title = i18ncp("%1 is the number of conflicts", "Shortcut Conflict", "Shortcut Conflicts", listSize);
|
||||
|
||||
QString conflictingShortcuts;
|
||||
for (const QAction *action : actions) {
|
||||
conflictingShortcuts += i18n("Shortcut '%1' for action '%2'\n",
|
||||
action->shortcut().toString(QKeySequence::NativeText),
|
||||
KLocalizedString::removeAcceleratorMarker(action->text()));
|
||||
}
|
||||
QString message = i18ncp("%1 is the number of ambiguous shortcut clashes (hidden)",
|
||||
"The \"%2\" shortcut is ambiguous with the following shortcut.\n"
|
||||
"Do you want to assign an empty shortcut to this action?\n"
|
||||
"%3",
|
||||
"The \"%2\" shortcut is ambiguous with the following shortcuts.\n"
|
||||
"Do you want to assign an empty shortcut to these actions?\n"
|
||||
"%3",
|
||||
listSize,
|
||||
seq.toString(QKeySequence::NativeText),
|
||||
conflictingShortcuts);
|
||||
|
||||
return KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18nc("@action:button", "Reassign"))) == KMessageBox::Continue;
|
||||
}
|
||||
|
||||
void KKeySequenceWidgetPrivate::wontStealShortcut(QAction *item, const QKeySequence &seq)
|
||||
{
|
||||
QString title(i18nc("@title:window", "Shortcut conflict"));
|
||||
QString msg(
|
||||
i18n("<qt>The '%1' key combination is already used by the <b>%2</b> action.<br>"
|
||||
"Please select a different one.</qt>",
|
||||
seq.toString(QKeySequence::NativeText),
|
||||
KLocalizedString::removeAcceleratorMarker(item->text())));
|
||||
KMessageBox::error(q, msg, title);
|
||||
}
|
||||
|
||||
bool KKeySequenceWidgetPrivate::conflictWithLocalShortcuts(const QKeySequence &keySequence)
|
||||
{
|
||||
if (!(checkAgainstShortcutTypes & KKeySequenceWidget::LocalShortcuts)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add all the actions from the checkActionCollections list to a single list to
|
||||
// be able to process them in a single loop below.
|
||||
// Note that this can't be done in setCheckActionCollections(), because we
|
||||
// keep pointers to the action collections, and between the call to
|
||||
// setCheckActionCollections() and this function some actions might already be
|
||||
// removed from the collection again.
|
||||
QList<QAction *> allActions;
|
||||
for (KActionCollection *collection : std::as_const(checkActionCollections)) {
|
||||
allActions += collection->actions();
|
||||
}
|
||||
|
||||
// Because of multikey shortcuts we can have clashes with many shortcuts.
|
||||
//
|
||||
// Example 1:
|
||||
//
|
||||
// Application currently uses 'CTRL-X,a', 'CTRL-X,f' and 'CTRL-X,CTRL-F'
|
||||
// and the user wants to use 'CTRL-X'. 'CTRL-X' will only trigger as
|
||||
// 'activatedAmbiguously()' for obvious reasons.
|
||||
//
|
||||
// Example 2:
|
||||
//
|
||||
// Application currently uses 'CTRL-X'. User wants to use 'CTRL-X,CTRL-F'.
|
||||
// This will shadow 'CTRL-X' for the same reason as above.
|
||||
//
|
||||
// Example 3:
|
||||
//
|
||||
// Some weird combination of Example 1 and 2 with three shortcuts using
|
||||
// 1/2/3 key shortcuts. I think you can imagine.
|
||||
QList<QAction *> conflictingActions;
|
||||
|
||||
// find conflicting shortcuts with existing actions
|
||||
for (QAction *qaction : std::as_const(allActions)) {
|
||||
if (shortcutsConflictWith(qaction->shortcuts(), keySequence)) {
|
||||
// A conflict with a KAction. If that action is configurable
|
||||
// ask the user what to do. If not reject this keySequence.
|
||||
if (KActionCollection::isShortcutsConfigurable(qaction)) {
|
||||
conflictingActions.append(qaction);
|
||||
} else {
|
||||
wontStealShortcut(qaction, keySequence);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conflictingActions.isEmpty()) {
|
||||
// No conflicting shortcuts found.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (promptStealLocalShortcut(conflictingActions, keySequence)) {
|
||||
stealActions = conflictingActions;
|
||||
// Announce that the user agreed
|
||||
for (QAction *stealAction : std::as_const(stealActions)) {
|
||||
Q_EMIT q->stealShortcut(keySequence, stealAction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if HAVE_GLOBALACCEL
|
||||
bool KKeySequenceWidgetPrivate::promptStealGlobalShortcut(const std::vector<KeyConflictInfo> &clashing, const QKeySequence &sequence)
|
||||
{
|
||||
QString clashingKeys;
|
||||
for (const auto &[key, shortcutInfo] : clashing) {
|
||||
const QString seqAsString = key.toString();
|
||||
for (const KGlobalShortcutInfo &info : shortcutInfo) {
|
||||
clashingKeys += i18n("Shortcut '%1' in Application '%2' for action '%3'\n", //
|
||||
seqAsString,
|
||||
info.componentFriendlyName(),
|
||||
info.friendlyName());
|
||||
}
|
||||
}
|
||||
const int hashSize = clashing.size();
|
||||
|
||||
QString message = i18ncp("%1 is the number of conflicts (hidden), %2 is the key sequence of the shortcut that is problematic",
|
||||
"The shortcut '%2' conflicts with the following key combination:\n",
|
||||
"The shortcut '%2' conflicts with the following key combinations:\n",
|
||||
hashSize,
|
||||
sequence.toString());
|
||||
message += clashingKeys;
|
||||
|
||||
QString title = i18ncp("%1 is the number of shortcuts with which there is a conflict",
|
||||
"Conflict with Registered Global Shortcut",
|
||||
"Conflict with Registered Global Shortcuts",
|
||||
hashSize);
|
||||
|
||||
return KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18nc("@action:button", "Reassign"))) == KMessageBox::Continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool KKeySequenceWidgetPrivate::conflictWithGlobalShortcuts(const QKeySequence &keySequence)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// on windows F12 is reserved by the debugger at all times, so we can't use it for a global shortcut
|
||||
if (KKeySequenceWidget::GlobalShortcuts && keySequence.toString().contains(QLatin1String("F12"))) {
|
||||
QString title = i18n("Reserved Shortcut");
|
||||
QString message = i18n(
|
||||
"The F12 key is reserved on Windows, so cannot be used for a global shortcut.\n"
|
||||
"Please choose another one.");
|
||||
|
||||
KMessageBox::error(q, message, title);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if HAVE_GLOBALACCEL
|
||||
if (!(checkAgainstShortcutTypes & KKeySequenceWidget::GlobalShortcuts)) {
|
||||
return false;
|
||||
}
|
||||
// Global shortcuts are on key+modifier shortcuts. They can clash with
|
||||
// each of the keys of a multi key shortcut.
|
||||
std::vector<KeyConflictInfo> clashing;
|
||||
for (int i = 0; i < keySequence.count(); ++i) {
|
||||
QKeySequence keys(keySequence[i]);
|
||||
if (!KGlobalAccel::isGlobalShortcutAvailable(keySequence, componentName)) {
|
||||
clashing.push_back({keySequence, KGlobalAccel::globalShortcutsByKey(keys)});
|
||||
}
|
||||
}
|
||||
if (clashing.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!promptStealGlobalShortcut(clashing, keySequence)) {
|
||||
return true;
|
||||
}
|
||||
// The user approved stealing the shortcut. We have to steal
|
||||
// it immediately because KAction::setGlobalShortcut() refuses
|
||||
// to set a global shortcut that is already used. There is no
|
||||
// error it just silently fails. So be nice because this is
|
||||
// most likely the first action that is done in the slot
|
||||
// listening to keySequenceChanged().
|
||||
KGlobalAccel::stealShortcutSystemwide(keySequence);
|
||||
return false;
|
||||
#else
|
||||
Q_UNUSED(keySequence);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool KKeySequenceWidgetPrivate::promptstealStandardShortcut(KStandardShortcut::StandardShortcut std, const QKeySequence &seq)
|
||||
{
|
||||
QString title = i18nc("@title:window", "Conflict with Standard Application Shortcut");
|
||||
QString message = i18n(
|
||||
"The '%1' key combination is also used for the standard action "
|
||||
"\"%2\" that some applications use.\n"
|
||||
"Do you really want to use it as a global shortcut as well?",
|
||||
seq.toString(QKeySequence::NativeText),
|
||||
KStandardShortcut::label(std));
|
||||
|
||||
return KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18nc("@action:button", "Reassign"))) == KMessageBox::Continue;
|
||||
}
|
||||
|
||||
bool KKeySequenceWidgetPrivate::conflictWithStandardShortcuts(const QKeySequence &seq)
|
||||
{
|
||||
if (!(checkAgainstShortcutTypes & KKeySequenceWidget::StandardShortcuts)) {
|
||||
return false;
|
||||
}
|
||||
KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(seq);
|
||||
if (ssc != KStandardShortcut::AccelNone && !promptstealStandardShortcut(ssc, seq)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void KKeySequenceWidgetPrivate::startRecording()
|
||||
{
|
||||
keyButton->setDown(true);
|
||||
recorder->startRecording();
|
||||
updateShortcutDisplay();
|
||||
}
|
||||
|
||||
void KKeySequenceWidgetPrivate::doneRecording()
|
||||
{
|
||||
keyButton->setDown(false);
|
||||
stealActions.clear();
|
||||
keyButton->setText(keyButton->text().chopped(inputRecordingMarkupSuffix.size()));
|
||||
q->setKeySequence(recorder->currentKeySequence(), KKeySequenceWidget::Validate);
|
||||
updateShortcutDisplay();
|
||||
}
|
||||
|
||||
void KKeySequenceWidgetPrivate::updateShortcutDisplay()
|
||||
{
|
||||
QString s;
|
||||
QKeySequence sequence = recorder->isRecording() ? recorder->currentKeySequence() : keySequence;
|
||||
if (!sequence.isEmpty()) {
|
||||
s = sequence.toString(QKeySequence::NativeText);
|
||||
} else if (recorder->isRecording()) {
|
||||
s = i18nc("What the user inputs now will be taken as the new shortcut", "Input");
|
||||
} else {
|
||||
s = i18nc("No shortcut defined", "None");
|
||||
}
|
||||
|
||||
if (recorder->isRecording()) {
|
||||
// make it clear that input is still going on
|
||||
s.append(inputRecordingMarkupSuffix);
|
||||
}
|
||||
|
||||
s = QLatin1Char(' ') + s + QLatin1Char(' ');
|
||||
keyButton->setText(s);
|
||||
}
|
||||
|
||||
KKeySequenceWidget::KKeySequenceWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, d(new KKeySequenceWidgetPrivate(this))
|
||||
{
|
||||
d->init();
|
||||
setFocusProxy(d->keyButton);
|
||||
connect(d->keyButton, &QPushButton::clicked, this, &KKeySequenceWidget::captureKeySequence);
|
||||
connect(d->clearButton, &QToolButton::clicked, this, &KKeySequenceWidget::clearKeySequence);
|
||||
|
||||
connect(d->recorder, &KKeySequenceRecorder::currentKeySequenceChanged, this, [this] {
|
||||
d->updateShortcutDisplay();
|
||||
});
|
||||
connect(d->recorder, &KKeySequenceRecorder::recordingChanged, this, [this] {
|
||||
if (!d->recorder->isRecording()) {
|
||||
d->doneRecording();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
KKeySequenceWidget::~KKeySequenceWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
KKeySequenceWidget::ShortcutTypes KKeySequenceWidget::checkForConflictsAgainst() const
|
||||
{
|
||||
return d->checkAgainstShortcutTypes;
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setComponentName(const QString &componentName)
|
||||
{
|
||||
d->componentName = componentName;
|
||||
}
|
||||
|
||||
bool KKeySequenceWidget::multiKeyShortcutsAllowed() const
|
||||
{
|
||||
return d->recorder->multiKeyShortcutsAllowed();
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setMultiKeyShortcutsAllowed(bool allowed)
|
||||
{
|
||||
d->recorder->setMultiKeyShortcutsAllowed(allowed);
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setCheckForConflictsAgainst(ShortcutTypes types)
|
||||
{
|
||||
d->checkAgainstShortcutTypes = types;
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setModifierlessAllowed(bool allow)
|
||||
{
|
||||
d->recorder->setModifierlessAllowed(allow);
|
||||
}
|
||||
|
||||
bool KKeySequenceWidget::isKeySequenceAvailable(const QKeySequence &keySequence) const
|
||||
{
|
||||
if (keySequence.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return !(d->conflictWithLocalShortcuts(keySequence) //
|
||||
|| d->conflictWithGlobalShortcuts(keySequence) //
|
||||
|| d->conflictWithStandardShortcuts(keySequence));
|
||||
}
|
||||
|
||||
bool KKeySequenceWidget::isModifierlessAllowed()
|
||||
{
|
||||
return d->recorder->modifierlessAllowed();
|
||||
}
|
||||
|
||||
bool KKeySequenceWidget::modifierOnlyAllowed() const
|
||||
{
|
||||
return d->recorder->modifierOnlyAllowed();
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setModifierOnlyAllowed(bool allow)
|
||||
{
|
||||
d->recorder->setModifierOnlyAllowed(allow);
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setClearButtonShown(bool show)
|
||||
{
|
||||
d->clearButton->setVisible(show);
|
||||
}
|
||||
|
||||
void KKeySequenceWidget::setCheckActionCollections(const QList<KActionCollection *> &actionCollections)
|
||||
{
|
||||
d->checkActionCollections = actionCollections;
|
||||
}
|
||||
|
||||
// slot
|
||||
void KKeySequenceWidget::captureKeySequence()
|
||||
{
|
||||
d->recorder->setWindow(window()->windowHandle());
|
||||
d->recorder->startRecording();
|
||||
}
|
||||
|
||||
QKeySequence KKeySequenceWidget::keySequence() const
|
||||
{
|
||||
return d->keySequence;
|
||||
}
|
||||
|
||||
// slot
|
||||
void KKeySequenceWidget::setKeySequence(const QKeySequence &seq, Validation validate)
|
||||
{
|
||||
if (d->keySequence == seq) {
|
||||
return;
|
||||
}
|
||||
if (validate == Validate && !isKeySequenceAvailable(seq)) {
|
||||
return;
|
||||
}
|
||||
d->keySequence = seq;
|
||||
d->updateShortcutDisplay();
|
||||
Q_EMIT keySequenceChanged(seq);
|
||||
}
|
||||
|
||||
// slot
|
||||
void KKeySequenceWidget::clearKeySequence()
|
||||
{
|
||||
setKeySequence(QKeySequence());
|
||||
}
|
||||
|
||||
// slot
|
||||
void KKeySequenceWidget::applyStealShortcut()
|
||||
{
|
||||
QSet<KActionCollection *> changedCollections;
|
||||
|
||||
for (QAction *stealAction : std::as_const(d->stealActions)) {
|
||||
// Stealing a shortcut means setting it to an empty one.
|
||||
stealAction->setShortcuts(QList<QKeySequence>());
|
||||
|
||||
// The following code will find the action we are about to
|
||||
// steal from and save it's actioncollection.
|
||||
KActionCollection *parentCollection = nullptr;
|
||||
for (KActionCollection *collection : std::as_const(d->checkActionCollections)) {
|
||||
if (collection->actions().contains(stealAction)) {
|
||||
parentCollection = collection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the changed collection
|
||||
if (parentCollection) {
|
||||
changedCollections.insert(parentCollection);
|
||||
}
|
||||
}
|
||||
|
||||
for (KActionCollection *col : std::as_const(changedCollections)) {
|
||||
col->writeSettings();
|
||||
}
|
||||
|
||||
d->stealActions.clear();
|
||||
}
|
||||
|
||||
bool KKeySequenceWidget::event(QEvent *ev)
|
||||
{
|
||||
constexpr char _highlight[] = "_kde_highlight_neutral";
|
||||
|
||||
if (ev->type() == QEvent::DynamicPropertyChange) {
|
||||
auto dpev = static_cast<QDynamicPropertyChangeEvent *>(ev);
|
||||
if (dpev->propertyName() == _highlight) {
|
||||
d->keyButton->setProperty(_highlight, property(_highlight));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(ev);
|
||||
}
|
||||
|
||||
#include "moc_kkeysequencewidget.cpp"
|
||||
Reference in New Issue
Block a user