Commit 8d266097 authored by Andrey Butirsky's avatar Andrey Butirsky

fix: keyboard layout applet: no flag if Display Name is set

Rework DBus API - getLayoutsList() now provides full details about the
layouts.
Remove Q_PROPERTY's as they are not make much sense here.
Port to a fully event-driven interface towards QML.
parent 58d8b710
set(keyboardlayoutplugin_SRCS
keyboardlayout.cpp
keyboardlayoutplugin.cpp)
keyboardlayoutplugin.cpp
layoutnames.cpp
layoutnames.h
)
ecm_qt_declare_logging_category(keyboardlayoutplugin_SRCS HEADER debug.h
IDENTIFIER KEYBOARD_LAYOUT
CATEGORY_NAME kde.keyboardlayout
DEFAULT_SEVERITY Info)
set_source_files_properties(org.kde.KeyboardLayouts.xml
PROPERTIES INCLUDE layoutnames.h)
qt5_add_dbus_interface(keyboardlayoutplugin_SRCS "org.kde.KeyboardLayouts.xml" keyboard_layout_interface)
add_library(keyboardlayoutplugin SHARED ${keyboardlayoutplugin_SRCS})
......
......@@ -11,22 +11,29 @@
#include <QDBusInterface>
template<>
void KeyboardLayout::requestDBusData<KeyboardLayout::LayoutDisplayName>()
{ if (mIface) requestDBusData(mIface->getLayoutDisplayName(), mLayoutDisplayName, &KeyboardLayout::layoutDisplayNameChanged); }
inline void KeyboardLayout::requestDBusData<KeyboardLayout::Layout>()
{ if (mIface) requestDBusData(mIface->getLayout(), &KeyboardLayout::layoutChanged); }
template<>
void KeyboardLayout::requestDBusData<KeyboardLayout::LayoutLongName>()
{ if (mIface) requestDBusData(mIface->getLayoutLongName(), mLayoutLongName, &KeyboardLayout::layoutLongNameChanged); }
inline void KeyboardLayout::requestDBusData<KeyboardLayout::Layouts>()
{ if (mIface) requestDBusData(mIface->getLayoutsList(), &KeyboardLayout::layoutsChanged); }
template<>
void KeyboardLayout::requestDBusData<KeyboardLayout::Layouts>()
{ if (mIface) requestDBusData(mIface->getLayoutsList(), mLayouts, &KeyboardLayout::layoutsChanged); }
inline void KeyboardLayout::requestDBusData<KeyboardLayout::LayoutLongName>()
{ if (mIface) requestDBusData(mIface->getLayoutLongName(), &KeyboardLayout::layoutLongNameChanged); }
void KeyboardLayout::requestLayoutLongName()
{
requestDBusData<LayoutLongName>();
}
KeyboardLayout::KeyboardLayout(QObject* parent)
: QObject(parent)
, mIface(nullptr)
{
LayoutNames::registerMetaType();
mIface = new OrgKdeKeyboardLayoutsInterface(QStringLiteral("org.kde.keyboard"),
QStringLiteral("/Layouts"),
QDBusConnection::sessionBus(),
......@@ -38,17 +45,13 @@ KeyboardLayout::KeyboardLayout(QObject* parent)
}
connect(mIface, &OrgKdeKeyboardLayoutsInterface::layoutChanged,
this, [this]()
{
requestDBusData<LayoutDisplayName>();
requestDBusData<LayoutLongName>();
});
this, &KeyboardLayout::layoutChanged);
connect(mIface, &OrgKdeKeyboardLayoutsInterface::layoutListChanged,
this, [this]()
{
requestDBusData<LayoutDisplayName>();
requestDBusData<LayoutLongName>();
requestDBusData<Layouts>();
requestDBusData<Layout>();
});
emit mIface->OrgKdeKeyboardLayoutsInterface::layoutListChanged();
......@@ -74,18 +77,17 @@ void KeyboardLayout::setLayout(const QString &layout)
}
template<class T>
void KeyboardLayout::requestDBusData(QDBusPendingReply<T> pendingReply, T &out, void (KeyboardLayout::*notify)())
void KeyboardLayout::requestDBusData(QDBusPendingReply<T> pendingReply, void (KeyboardLayout::*notify)(const T &))
{
const QDBusPendingCallWatcher * const watcher = new QDBusPendingCallWatcher(pendingReply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this,
[this, &out, notify](QDBusPendingCallWatcher *watcher)
[this, notify](QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<T> reply = *watcher;
if (reply.isError()) {
qCWarning(KEYBOARD_LAYOUT) << reply.error().message();
} else {
out = reply.value();
emit (this->*notify)();
emit (this->*notify)(reply.value());
}
watcher->deleteLater();
}
......
......@@ -12,53 +12,37 @@
#include "debug.h"
class OrgKdeKeyboardLayoutsInterface;
class QDBusPendingCallWatcher;
class LayoutNames;
class KeyboardLayout : public QObject
{
Q_OBJECT
Q_PROPERTY(QString layout
WRITE setLayout)
Q_PROPERTY(QString layoutDisplayName
MEMBER mLayoutDisplayName
NOTIFY layoutDisplayNameChanged)
Q_PROPERTY(QString layoutLongName
MEMBER mLayoutLongName
NOTIFY layoutLongNameChanged)
Q_PROPERTY(QStringList layouts
MEMBER mLayouts
NOTIFY layoutsChanged)
public:
explicit KeyboardLayout(QObject *parent = nullptr);
~KeyboardLayout() override;
Q_SIGNALS:
void layoutDisplayNameChanged();
void layoutLongNameChanged();
void layoutsChanged();
void layoutChanged(const QString &idName);
void layoutsChanged(const QVector<LayoutNames> &layouts);
protected Q_SLOTS:
void switchToNextLayout();
void switchToPreviousLayout();
void layoutLongNameChanged(const QString &longName);
private:
void setLayout(const QString &layout);
protected:
Q_INVOKABLE void switchToNextLayout();
Q_INVOKABLE void switchToPreviousLayout();
Q_INVOKABLE void setLayout(const QString &layout);
Q_INVOKABLE void requestLayoutLongName();
enum DBusData {LayoutDisplayName, LayoutLongName, Layouts};
private:
enum DBusData {Layout, LayoutLongName, Layouts};
template<class T>
void requestDBusData(QDBusPendingReply<T> pendingReply, T &out, void (KeyboardLayout::*notify)());
void requestDBusData(QDBusPendingReply<T> pendingReply, void (KeyboardLayout::*notify)(const T &));
template<DBusData>
inline void requestDBusData();
void requestDBusData();
QString mLayoutDisplayName;
QString mLayoutLongName;
QStringList mLayouts;
OrgKdeKeyboardLayoutsInterface *mIface;
};
......
#include "layoutnames.h"
#include <QDBusMetaType>
void LayoutNames::registerMetaType()
{
qDBusRegisterMetaType<LayoutNames>();
qDBusRegisterMetaType<QVector<LayoutNames>>();
}
QDBusArgument &operator<<(QDBusArgument &argument, const LayoutNames &layoutNames)
{
argument.beginStructure();
argument << layoutNames.id << layoutNames.shortName << layoutNames.displayName << layoutNames.longName;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, LayoutNames &layoutNames)
{
argument.beginStructure();
argument >> layoutNames.id >> layoutNames.shortName >> layoutNames.displayName >> layoutNames.longName;
argument.endStructure();
return argument;
}
#ifndef LAYOUTNAMES_H
#define LAYOUTNAMES_H
#include <QMetaType>
class QDBusArgument;
class LayoutNames
{
Q_GADGET
Q_PROPERTY(QString id MEMBER id)
Q_PROPERTY(QString shortName MEMBER shortName)
Q_PROPERTY(QString displayName MEMBER displayName)
Q_PROPERTY(QString longName MEMBER longName)
public:
static void registerMetaType();
QString id;
QString shortName;
QString displayName;
QString longName;
};
Q_DECLARE_METATYPE(LayoutNames)
QDBusArgument &operator<<(QDBusArgument &argument, const LayoutNames &layoutNames);
const QDBusArgument &operator>>(const QDBusArgument &argument, LayoutNames &layoutNames);
#endif // LAYOUTNAMES_H
......@@ -18,15 +18,12 @@
<method name="getLayout">
<arg type="s" direction="out"/>
</method>
<method name="getLayoutDisplayName">
<arg type="s" direction="out"/>
</method>
<method name="getLayoutLongName">
<arg type="s" direction="out"/>
</method>
<method name="getLayoutsList">
<arg type="as" direction="out"/>
<arg type="a(sss)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector&lt;LayoutNames&gt;" />
</method>
</interface>
</node>
......@@ -9,32 +9,45 @@ import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.workspace.keyboardlayout 1.0
PlasmaComponents3.ToolButton {
id: kbLayoutButton
property alias keyboardLayout: keyboardLayout
property alias connections: connections
property bool hasMultipleKeyboardLayouts
property alias layout: layout
readonly property bool hasMultipleKeyboardLayouts: layout.layouts.length > 1
text: layout.layoutLongName
visible: hasMultipleKeyboardLayouts
Accessible.name: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Button to change keyboard layout", "Switch layout")
icon.name: "input-keyboard"
onClicked: layout.switchToNextLayout()
onClicked: keyboardLayout.switchToNextLayout()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
onWheel: {
if (wheel.angleDelta.y > 0) {
layout.switchToNextLayout()
keyboardLayout.switchToNextLayout()
} else {
layout.switchToPreviousLayout()
keyboardLayout.switchToPreviousLayout()
}
}
}
KeyboardLayout {
id: layout
id: keyboardLayout
onLayoutsChanged: hasMultipleKeyboardLayouts = layouts.length > 1
}
Connections {
id: connections
target: keyboardLayout
function onLayoutChanged() {
keyboardLayout.requestLayoutLongName()
}
function onLayoutLongNameChanged(longName) {
text = longName
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment