Advance Wayland and KDE package bring-up
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer <kalle@kde.org>
|
||||
SPDX-FileCopyrightText: 1998, 1999, 2000 KDE Team
|
||||
SPDX-FileCopyrightText: 2008 Nick Shaforostoff <shaforostoff@kde.ru>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kcheckaccelerators.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QChar>
|
||||
#include <QCheckBox>
|
||||
#include <QClipboard>
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFile>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QShortcutEvent>
|
||||
#include <QTabBar>
|
||||
#include <QTextBrowser>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <KAcceleratorManager>
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KLocalizedString>
|
||||
#include <KSharedConfig>
|
||||
|
||||
class KCheckAcceleratorsInitializer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KCheckAcceleratorsInitializer(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
void initiateIfNeeded()
|
||||
{
|
||||
KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development"));
|
||||
QString sKey = cg.readEntry("CheckAccelerators").trimmed();
|
||||
int key = 0;
|
||||
if (!sKey.isEmpty()) {
|
||||
QList<QKeySequence> cuts = QKeySequence::listFromString(sKey);
|
||||
if (!cuts.isEmpty()) {
|
||||
key = cuts.first()[0].toCombined();
|
||||
}
|
||||
}
|
||||
const bool autoCheck = cg.readEntry("AutoCheckAccelerators", true);
|
||||
if (key == 0 && !autoCheck) {
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
new KCheckAccelerators(qApp, key, autoCheck);
|
||||
deleteLater();
|
||||
}
|
||||
};
|
||||
|
||||
static void startupFunc()
|
||||
{
|
||||
// Static because in some cases this is called multiple times
|
||||
// but if an application had any of the bad cases we always want
|
||||
// to skip the check
|
||||
static bool doCheckAccelerators = true;
|
||||
|
||||
if (!doCheckAccelerators) {
|
||||
return;
|
||||
}
|
||||
|
||||
QCoreApplication *app = QCoreApplication::instance();
|
||||
if (!app) {
|
||||
// We're being loaded by something that doesn't have a QCoreApplication
|
||||
// this would probably crash at some later point since we do use qApp->
|
||||
// quite a lot, so skip the magic
|
||||
doCheckAccelerators = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QCoreApplication::startingUp()) {
|
||||
// If the app has already started, this means we're not being run as part of
|
||||
// qt_call_pre_routines, which most probably means that we're being run as
|
||||
// part of KXmlGui being loaded as part of some plugin of the app, so don't
|
||||
// do any magic
|
||||
doCheckAccelerators = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QCoreApplication::eventDispatcher()) {
|
||||
// We are called with event dispatcher being null when KXmlGui is being
|
||||
// loaded through plasma-integration instead of being linked to the app
|
||||
// (i.e. QtCreator vs Okular) For apps that don't link directly to KXmlGui
|
||||
// do not do the accelerator magic
|
||||
doCheckAccelerators = false;
|
||||
return;
|
||||
}
|
||||
|
||||
KCheckAcceleratorsInitializer *initializer = new KCheckAcceleratorsInitializer(app);
|
||||
// Call initiateIfNeeded once we're in the event loop
|
||||
// This is to prevent using KSharedConfig before main() can set the app name
|
||||
QMetaObject::invokeMethod(initializer, "initiateIfNeeded", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
Q_COREAPP_STARTUP_FUNCTION(startupFunc)
|
||||
|
||||
KCheckAccelerators::KCheckAccelerators(QObject *parent, int key_, bool autoCheck_)
|
||||
: QObject(parent)
|
||||
, key(key_)
|
||||
, block(false)
|
||||
, autoCheck(autoCheck_)
|
||||
, drklash(nullptr)
|
||||
{
|
||||
setObjectName(QStringLiteral("kapp_accel_filter"));
|
||||
|
||||
KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development"));
|
||||
alwaysShow = cg.readEntry("AlwaysShowCheckAccelerators", false);
|
||||
|
||||
parent->installEventFilter(this);
|
||||
connect(&autoCheckTimer, &QTimer::timeout, this, &KCheckAccelerators::autoCheckSlot);
|
||||
}
|
||||
|
||||
bool KCheckAccelerators::eventFilter(QObject * /*obj*/, QEvent *e)
|
||||
{
|
||||
if (block) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (e->type()) { // just simplify debuggin
|
||||
case QEvent::ShortcutOverride:
|
||||
if (key && (static_cast<QKeyEvent *>(e)->key() == key)) {
|
||||
block = true;
|
||||
checkAccelerators(false);
|
||||
block = false;
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QEvent::ChildAdded:
|
||||
case QEvent::ChildRemoved:
|
||||
// Only care about widgets; this also avoids starting the timer in other
|
||||
// threads
|
||||
if (!static_cast<QChildEvent *>(e)->child()->isWidgetType()) {
|
||||
break;
|
||||
}
|
||||
Q_FALLTHROUGH();
|
||||
// fall-through
|
||||
case QEvent::Resize:
|
||||
case QEvent::LayoutRequest:
|
||||
case QEvent::WindowActivate:
|
||||
case QEvent::WindowDeactivate:
|
||||
if (autoCheck) {
|
||||
autoCheckTimer.setSingleShot(true);
|
||||
autoCheckTimer.start(20); // 20 ms
|
||||
}
|
||||
return false;
|
||||
case QEvent::Timer:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::Paint:
|
||||
return false;
|
||||
default:
|
||||
// qCDebug(DEBUG_KXMLGUI) << "KCheckAccelerators::eventFilter " << e->type()
|
||||
// << " " << autoCheck;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void KCheckAccelerators::autoCheckSlot()
|
||||
{
|
||||
if (block) {
|
||||
autoCheckTimer.setSingleShot(true);
|
||||
autoCheckTimer.start(20);
|
||||
return;
|
||||
}
|
||||
block = true;
|
||||
checkAccelerators(!alwaysShow);
|
||||
block = false;
|
||||
}
|
||||
|
||||
void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic)
|
||||
{
|
||||
if (drklash) {
|
||||
return;
|
||||
}
|
||||
|
||||
drklash = new QDialog(actWin);
|
||||
drklash->setAttribute(Qt::WA_DeleteOnClose);
|
||||
drklash->setObjectName(QStringLiteral("kapp_accel_check_dlg"));
|
||||
drklash->setWindowTitle(i18nc("@title:window", "Dr. Klash' Accelerator Diagnosis"));
|
||||
drklash->resize(500, 460);
|
||||
QVBoxLayout *layout = new QVBoxLayout(drklash);
|
||||
drklash_view = new QTextBrowser(drklash);
|
||||
layout->addWidget(drklash_view);
|
||||
QCheckBox *disableAutoCheck = nullptr;
|
||||
if (automatic) {
|
||||
disableAutoCheck = new QCheckBox(i18nc("@option:check", "Disable automatic checking"), drklash);
|
||||
connect(disableAutoCheck, &QCheckBox::toggled, this, &KCheckAccelerators::slotDisableCheck);
|
||||
layout->addWidget(disableAutoCheck);
|
||||
}
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, drklash);
|
||||
layout->addWidget(buttonBox);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, drklash, &QDialog::close);
|
||||
if (disableAutoCheck) {
|
||||
disableAutoCheck->setFocus();
|
||||
} else {
|
||||
drklash_view->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void KCheckAccelerators::slotDisableCheck(bool on)
|
||||
{
|
||||
autoCheck = !on;
|
||||
if (!on) {
|
||||
autoCheckSlot();
|
||||
}
|
||||
}
|
||||
|
||||
void KCheckAccelerators::checkAccelerators(bool automatic)
|
||||
{
|
||||
QWidget *actWin = qApp->activeWindow();
|
||||
if (!actWin) {
|
||||
return;
|
||||
}
|
||||
|
||||
KAcceleratorManager::manage(actWin);
|
||||
QString a;
|
||||
QString c;
|
||||
QString r;
|
||||
KAcceleratorManager::last_manage(a, c, r);
|
||||
|
||||
if (automatic) { // for now we only show dialogs on F12 checks
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.isEmpty() && r.isEmpty() && (automatic || a.isEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString s;
|
||||
|
||||
if (!c.isEmpty()) {
|
||||
s += i18n("<h2>Accelerators changed</h2>")
|
||||
+ QLatin1String(
|
||||
"<table "
|
||||
"border><tr><th><b>%1</b></th><th><b>%2</b></th></tr>%3</table>")
|
||||
.arg(i18n("Old Text"), i18n("New Text"), c);
|
||||
}
|
||||
|
||||
if (!r.isEmpty()) {
|
||||
s += i18n("<h2>Accelerators removed</h2>") + QLatin1String("<table border><tr><th><b>%1</b></th></tr>%2</table>").arg(i18n("Old Text"), r);
|
||||
}
|
||||
|
||||
if (!a.isEmpty()) {
|
||||
s += i18n("<h2>Accelerators added (just for your info)</h2>")
|
||||
+ QLatin1String("<table border><tr><th><b>%1</b></th></tr>%2</table>").arg(i18n("New Text"), a);
|
||||
}
|
||||
|
||||
createDialog(actWin, automatic);
|
||||
drklash_view->setHtml(s);
|
||||
drklash->show();
|
||||
drklash->raise();
|
||||
|
||||
// dlg will be destroyed before returning
|
||||
}
|
||||
|
||||
#include "kcheckaccelerators.moc"
|
||||
#include "moc_kcheckaccelerators.cpp"
|
||||
Reference in New Issue
Block a user