KXmlGui

kcheckaccelerators.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer <kalle@kde.org>
4 SPDX-FileCopyrightText: 1998, 1999, 2000 KDE Team
5 SPDX-FileCopyrightText: 2008 Nick Shaforostoff <shaforostoff@kde.ru>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9
10#include "kcheckaccelerators.h"
11
12#include <QAction>
13#include <QApplication>
14#include <QChar>
15#include <QCheckBox>
16#include <QClipboard>
17#include <QComboBox>
18#include <QDebug>
19#include <QDialog>
20#include <QDialogButtonBox>
21#include <QFile>
22#include <QGroupBox>
23#include <QLabel>
24#include <QMenu>
25#include <QMouseEvent>
26#include <QPushButton>
27#include <QShortcutEvent>
28#include <QTabBar>
29#include <QTextBrowser>
30#include <QVBoxLayout>
31
32#include <KAcceleratorManager>
33#include <KConfig>
34#include <KConfigGroup>
35#include <KLocalizedString>
36#include <KSharedConfig>
37
38KCheckAccelerators::KCheckAccelerators(QObject *parent, int key_, bool autoCheck_)
39 : QObject(parent)
40 , key(key_)
41 , block(false)
42 , autoCheck(autoCheck_)
43 , drklash(nullptr)
44{
45 setObjectName(QStringLiteral("kapp_accel_filter"));
46
47 KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development"));
48 alwaysShow = cg.readEntry("AlwaysShowCheckAccelerators", false);
49
50 parent->installEventFilter(this);
51 connect(&autoCheckTimer, &QTimer::timeout, this, &KCheckAccelerators::autoCheckSlot);
52}
53
54bool KCheckAccelerators::eventFilter(QObject * /*obj*/, QEvent *e)
55{
56 if (block) {
57 return false;
58 }
59
60 switch (e->type()) { // just simplify debuggin
62 if (key && (static_cast<QKeyEvent *>(e)->key() == key)) {
63 block = true;
64 checkAccelerators(false);
65 block = false;
66 e->accept();
67 return true;
68 }
69 break;
72 // Only care about widgets; this also avoids starting the timer in other
73 // threads
74 if (!static_cast<QChildEvent *>(e)->child()->isWidgetType()) {
75 break;
76 }
77 Q_FALLTHROUGH();
78 // fall-through
79 case QEvent::Resize:
83 if (autoCheck) {
84 autoCheckTimer.setSingleShot(true);
85 autoCheckTimer.start(20); // 20 ms
86 }
87 return false;
88 case QEvent::Timer:
90 case QEvent::Paint:
91 return false;
92 default:
93 // qCDebug(DEBUG_KXMLGUI) << "KCheckAccelerators::eventFilter " << e->type()
94 // << " " << autoCheck;
95 break;
96 }
97 return false;
98}
99
100void KCheckAccelerators::autoCheckSlot()
101{
102 if (block) {
103 autoCheckTimer.setSingleShot(true);
104 autoCheckTimer.start(20);
105 return;
106 }
107 block = true;
108 checkAccelerators(!alwaysShow);
109 block = false;
110}
111
112void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic)
113{
114 if (drklash) {
115 return;
116 }
117
118 drklash = new QDialog(actWin);
119 drklash->setAttribute(Qt::WA_DeleteOnClose);
120 drklash->setObjectName(QStringLiteral("kapp_accel_check_dlg"));
121 drklash->setWindowTitle(i18nc("@title:window", "Dr. Klash' Accelerator Diagnosis"));
122 drklash->resize(500, 460);
123 QVBoxLayout *layout = new QVBoxLayout(drklash);
124 drklash_view = new QTextBrowser(drklash);
125 layout->addWidget(drklash_view);
126 QCheckBox *disableAutoCheck = nullptr;
127 if (automatic) {
128 disableAutoCheck = new QCheckBox(i18nc("@option:check", "Disable automatic checking"), drklash);
129 connect(disableAutoCheck, &QCheckBox::toggled, this, &KCheckAccelerators::slotDisableCheck);
130 layout->addWidget(disableAutoCheck);
131 }
132 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, drklash);
133 layout->addWidget(buttonBox);
134 connect(buttonBox, &QDialogButtonBox::rejected, drklash, &QDialog::close);
135 if (disableAutoCheck) {
136 disableAutoCheck->setFocus();
137 } else {
138 drklash_view->setFocus();
139 }
140}
141
142void KCheckAccelerators::slotDisableCheck(bool on)
143{
144 autoCheck = !on;
145 if (!on) {
146 autoCheckSlot();
147 }
148}
149
150void KCheckAccelerators::checkAccelerators(bool automatic)
151{
152 QWidget *actWin = qApp->activeWindow();
153 if (!actWin) {
154 return;
155 }
156
158 QString a;
159 QString c;
160 QString r;
162
163 if (automatic) { // for now we only show dialogs on F12 checks
164 return;
165 }
166
167 if (c.isEmpty() && r.isEmpty() && (automatic || a.isEmpty())) {
168 return;
169 }
170
171 QString s;
172
173 if (!c.isEmpty()) {
174 s += i18n("<h2>Accelerators changed</h2>")
175 + QLatin1String(
176 "<table "
177 "border><tr><th><b>%1</b></th><th><b>%2</b></th></tr>%3</table>")
178 .arg(i18n("Old Text"), i18n("New Text"), c);
179 }
180
181 if (!r.isEmpty()) {
182 s += i18n("<h2>Accelerators removed</h2>") + QLatin1String("<table border><tr><th><b>%1</b></th></tr>%2</table>").arg(i18n("Old Text"), r);
183 }
184
185 if (!a.isEmpty()) {
186 s += i18n("<h2>Accelerators added (just for your info)</h2>")
187 + QLatin1String("<table border><tr><th><b>%1</b></th></tr>%2</table>").arg(i18n("New Text"), a);
188 }
189
190 createDialog(actWin, automatic);
191 drklash_view->setHtml(s);
192 drklash->show();
193 drklash->raise();
194
195 // dlg will be destroyed before returning
196}
197
198void KCheckAccelerators::initiateIfNeeded()
199{
200 static QPointer<KCheckAccelerators> checker;
201 if (checker) {
202 return;
203 }
204
205 KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development"));
206 QString sKey = cg.readEntry("CheckAccelerators").trimmed();
207 int key = 0;
208 if (!sKey.isEmpty()) {
209 QList<QKeySequence> cuts = QKeySequence::listFromString(sKey);
210 if (!cuts.isEmpty()) {
211 key = cuts.first()[0].toCombined();
212 }
213 }
214 const bool autoCheck = cg.readEntry("AutoCheckAccelerators", true);
215 if (key == 0 && !autoCheck) {
216 return;
217 }
218
219 checker = new KCheckAccelerators(qApp, key, autoCheck);
220}
221
222#include "moc_kcheckaccelerators.cpp"
static void last_manage(QString &added, QString &changed, QString &removed)
static void manage(QWidget *widget, bool programmers_mode=false)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void toggled(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
ShortcutOverride
void accept()
Type type() const const
QList< QKeySequence > listFromString(const QString &str, SequenceFormat format)
T & first()
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void installEventFilter(QObject *filterObj)
bool isWidgetType() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
WA_DeleteOnClose
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void timeout()
bool close()
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 28 2025 11:58:03 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.