Use QML ListView in KCM
This commit is contained in:
parent
5d9b8d966c
commit
c0036d2d9b
9 changed files with 165 additions and 54 deletions
|
@ -8,7 +8,7 @@ set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE
|
|||
|
||||
project(kdeconnect VERSION ${RELEASE_SERVICE_VERSION})
|
||||
|
||||
set(KF_MIN_VERSION "5.240")
|
||||
set(KF_MIN_VERSION "6.0.0")
|
||||
set(QT_MIN_VERSION "6.7.0")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
@ -94,7 +94,7 @@ ecm_find_qmlmodule(QtQuick.Particles 2.0)
|
|||
|
||||
add_definitions(-DQT_NO_URL_CAST_FROM_STRING -DQT_NO_KEYWORDS -DQT_NO_CAST_FROM_ASCII)
|
||||
|
||||
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED COMPONENTS DBus Quick QuickControls2 Network Multimedia)
|
||||
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED COMPONENTS DBus Quick QuickWidgets QuickControls2 Network Multimedia)
|
||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS I18n ConfigWidgets DBusAddons IconThemes Notifications
|
||||
KIO KCMUtils Service Solid Kirigami People WindowSystem GuiAddons DocTools Crash)
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ Kirigami.ScrollablePage
|
|||
text: i18nd("kdeconnect-app", "No devices found")
|
||||
icon.name: 'edit-none-symbolic'
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Kirigami.Units.largeSpacing * 4)
|
||||
visible: devices.count === 0
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
qt_add_resources(kcm_SRCS assets.qrc)
|
||||
|
||||
add_definitions(-DTRANSLATION_DOMAIN="kdeconnect-kcm")
|
||||
|
||||
|
||||
kcoreaddons_add_plugin(kcm_kdeconnect SOURCES kcm.cpp INSTALL_NAMESPACE plasma/kcms/systemsettings_qwidgets)
|
||||
kcoreaddons_add_plugin(kcm_kdeconnect SOURCES kcm.cpp ${kcm_SRCS} INSTALL_NAMESPACE plasma/kcms/systemsettings_qwidgets)
|
||||
kcmutils_generate_desktop_file(kcm_kdeconnect)
|
||||
|
||||
ki18n_wrap_ui(kcm_kdeconnect kcm.ui)
|
||||
|
@ -9,6 +10,7 @@ ki18n_wrap_ui(kcm_kdeconnect kcm.ui)
|
|||
target_link_libraries(kcm_kdeconnect
|
||||
Qt::Core
|
||||
Qt::Gui
|
||||
Qt::QuickWidgets
|
||||
KF6::I18n
|
||||
KF6::KCMUtils
|
||||
kdeconnectinterfaces
|
||||
|
|
|
@ -5,5 +5,6 @@ $XGETTEXT rc.cpp -o $podir/kdeconnect-kcm.pot
|
|||
rm -f rc.cpp
|
||||
|
||||
#.cpp (-j passed to merge into existing file)
|
||||
$XGETTEXT `find . -name '*.qml'` -j -o $podir/kdeconnect-kcm.pot
|
||||
$XGETTEXT `find . -name '*.cpp'` -j -o $podir/kdeconnect-kcm.pot
|
||||
|
||||
|
|
7
kcm/assets.qrc
Normal file
7
kcm/assets.qrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE RCC>
|
||||
|
||||
<RCC version="1.0">
|
||||
<qresource prefix="/kdeconnectkcm">
|
||||
<file>list.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
52
kcm/kcm.cpp
52
kcm/kcm.cpp
|
@ -14,6 +14,9 @@
|
|||
#include <KPluginMetaData>
|
||||
#include <kcmutils_version.h>
|
||||
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "dbushelpers.h"
|
||||
#include "dbusinterfaces.h"
|
||||
#include "devicesmodel.h"
|
||||
|
@ -22,6 +25,21 @@
|
|||
|
||||
K_PLUGIN_CLASS_WITH_JSON(KdeConnectKcm, "kcm_kdeconnect.json")
|
||||
|
||||
class QQuickWidgetPaleteChangeWatcher : public QObject
|
||||
{
|
||||
using QObject::QObject;
|
||||
|
||||
bool eventFilter(QObject *watched, QEvent *event) override
|
||||
{
|
||||
if (event->type() == QEvent::PaletteChange || event->type() == QEvent::ApplicationPaletteChange) {
|
||||
// We know that watched is a QQuickWidget
|
||||
QQuickWidget *w = static_cast<QQuickWidget *>(watched);
|
||||
w->setClearColor(w->palette().color(QPalette::Window));
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
};
|
||||
|
||||
KdeConnectKcm::KdeConnectKcm(QObject *parent, const KPluginMetaData &md, const QVariantList &args)
|
||||
: KCModule(parent, md)
|
||||
, daemon(new DaemonDbusInterface(this))
|
||||
|
@ -37,7 +55,14 @@ KdeConnectKcm::KdeConnectKcm(QObject *parent, const KPluginMetaData &md, const Q
|
|||
|
||||
sortProxyModel = new DevicesSortProxyModel(devicesModel);
|
||||
|
||||
kcmUi.deviceList->setModel(sortProxyModel);
|
||||
kcmUi.list_quick_widget->setMinimumWidth(250 * kcmUi.list_quick_widget->devicePixelRatio());
|
||||
kcmUi.list_quick_widget->rootContext()->setContextObject(new KLocalizedContext(kcmUi.list_quick_widget));
|
||||
kcmUi.list_quick_widget->setClearColor(kcmUi.list_quick_widget->palette().color(QPalette::Window));
|
||||
kcmUi.list_quick_widget->setSource(QUrl(QStringLiteral("qrc:/kdeconnectkcm/list.qml")));
|
||||
kcmUi.list_quick_widget->rootObject()->setProperty("model", QVariant::fromValue(sortProxyModel));
|
||||
connect(kcmUi.list_quick_widget->rootObject(), SIGNAL(clicked(QString)), this, SLOT(deviceSelected(QString)));
|
||||
|
||||
kcmUi.list_quick_widget->installEventFilter(new QQuickWidgetPaleteChangeWatcher(kcmUi.list_quick_widget));
|
||||
|
||||
kcmUi.deviceInfo->setVisible(false);
|
||||
kcmUi.progressBar->setVisible(false);
|
||||
|
@ -67,8 +92,6 @@ KdeConnectKcm::KdeConnectKcm(QObject *parent, const KPluginMetaData &md, const Q
|
|||
|
||||
setButtons(KCModule::Help | KCModule::NoAdditionalButton);
|
||||
|
||||
connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection);
|
||||
connect(kcmUi.deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected);
|
||||
connect(kcmUi.accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing);
|
||||
connect(kcmUi.reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::cancelPairing);
|
||||
connect(kcmUi.cancel_button, &QAbstractButton::clicked, this, &KdeConnectKcm::cancelPairing);
|
||||
|
@ -88,11 +111,8 @@ KdeConnectKcm::KdeConnectKcm(QObject *parent, const KPluginMetaData &md, const Q
|
|||
const QString pluginCM = colonIdx < 0 ? QString() : input.mid(colonIdx + 1);
|
||||
|
||||
connect(devicesModel, &DevicesModel::rowsInserted, this, [this, deviceId, pluginCM]() {
|
||||
auto row = devicesModel->rowForDevice(deviceId);
|
||||
if (row >= 0) {
|
||||
const QModelIndex idx = sortProxyModel->mapFromSource(devicesModel->index(row));
|
||||
kcmUi.deviceList->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
kcmUi.list_quick_widget->rootObject()->setProperty("currentDeviceId", deviceId);
|
||||
deviceSelected(deviceId);
|
||||
if (!pluginCM.isEmpty()) {
|
||||
kcmUi.pluginSelector->showConfiguration(pluginCM);
|
||||
}
|
||||
|
@ -136,29 +156,19 @@ void KdeConnectKcm::refresh()
|
|||
daemon->forceOnNetworkChange();
|
||||
}
|
||||
|
||||
void KdeConnectKcm::resetSelection()
|
||||
{
|
||||
if (!currentDevice) {
|
||||
return;
|
||||
}
|
||||
kcmUi.deviceList->selectionModel()->setCurrentIndex(sortProxyModel->mapFromSource(currentIndex), QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
void KdeConnectKcm::deviceSelected(const QModelIndex ¤t)
|
||||
void KdeConnectKcm::deviceSelected(const QString &deviceId)
|
||||
{
|
||||
if (currentDevice) {
|
||||
disconnect(currentDevice, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
if (!current.isValid()) {
|
||||
currentDevice = devicesModel->getDevice(devicesModel->rowForDevice(deviceId));
|
||||
if (!currentDevice) {
|
||||
currentDevice = nullptr;
|
||||
kcmUi.deviceInfo->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
currentIndex = sortProxyModel->mapToSource(current);
|
||||
currentDevice = devicesModel->getDevice(currentIndex.row());
|
||||
|
||||
kcmUi.noDevicePlaceholder->setVisible(false);
|
||||
bool valid = (currentDevice != nullptr && currentDevice->isValid());
|
||||
kcmUi.deviceInfo->setVisible(valid);
|
||||
|
|
|
@ -30,11 +30,10 @@ private:
|
|||
void save() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void deviceSelected(const QModelIndex ¤t);
|
||||
void deviceSelected(const QString &deviceId);
|
||||
void requestPairing();
|
||||
void pluginsConfigChanged(bool changed);
|
||||
void sendPing();
|
||||
void resetSelection();
|
||||
void pairingFailed(const QString &error);
|
||||
void refresh();
|
||||
void renameShow();
|
||||
|
@ -53,7 +52,6 @@ private:
|
|||
DevicesModel *devicesModel;
|
||||
DevicesSortProxyModel *sortProxyModel;
|
||||
DeviceDbusInterface *currentDevice;
|
||||
QModelIndex currentIndex;
|
||||
QStringList m_oldSupportedPluginNames;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
|
63
kcm/kcm.ui
63
kcm/kcm.ui
|
@ -51,7 +51,6 @@
|
|||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
|
@ -59,14 +58,14 @@
|
|||
<string>KDE Connect</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
<enum>Qt::TextFormat::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
@ -82,8 +81,7 @@
|
|||
<string>Edit</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="edit-rename">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
<iconset theme="edit-rename"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -104,15 +102,24 @@
|
|||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dialog-ok">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
<iconset theme="dialog-ok"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="deviceList"/>
|
||||
<widget class="QQuickWidget" name="list_quick_widget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="resizeMode">
|
||||
<enum>QQuickWidget::ResizeMode::SizeRootObjectToView</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refresh_button">
|
||||
|
@ -152,7 +159,7 @@
|
|||
</property>
|
||||
<layout class="QHBoxLayout" name="header">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
<enum>QLayout::SizeConstraint::SetMaximumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
|
@ -185,7 +192,6 @@
|
|||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
|
@ -193,7 +199,7 @@
|
|||
<string>Device</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
<enum>Qt::TextFormat::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -213,7 +219,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
@ -229,10 +235,10 @@
|
|||
<item>
|
||||
<widget class="KSqueezedTextLabel" name="verificationKey">
|
||||
<property name="text">
|
||||
<string>🔑 abababab</string>
|
||||
<string>KSqueezedTextLabel</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -241,7 +247,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
@ -340,7 +346,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KMessageWidget" name="messages" native="true"/>
|
||||
<widget class="KMessageWidget" name="messages"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KPluginWidget" name="pluginSelector" native="true">
|
||||
|
@ -351,7 +357,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::WheelFocus</enum>
|
||||
<enum>Qt::FocusPolicy::WheelFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -373,10 +379,10 @@
|
|||
<string><html><head/><body><p>No device selected.<br><br>If you own an Android device, make sure to install the <a href="https://play.google.com/store/apps/details?id=org.kde.kdeconnect_tp"><span style=" text-decoration: underline;">KDE Connect Android app</span></a> (also available <a href="https://f-droid.org/repository/browse/?fdid=org.kde.kdeconnect_tp"><span style=" text-decoration: underline;">from F-Droid</span></a>) and it should appear in the list. If you have an iPhone, make sure to install the <a href="https://apps.apple.com/us/app/kde-connect/id1580245991"><span style=" text-decoration: underline;">KDE Connect iOS app</span></a> <br><br>If you are having problems, visit the <a href="https://userbase.kde.org/KDEConnect"><span style=" text-decoration: underline;">KDE Connect Community wiki</span></a> for help.</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -388,7 +394,7 @@
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
|
||||
<set>Qt::TextInteractionFlag::LinksAccessibleByKeyboard|Qt::TextInteractionFlag::LinksAccessibleByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -401,12 +407,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KPluginWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>kpluginwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KMessageWidget</class>
|
||||
<extends>QFrame</extends>
|
||||
|
@ -418,6 +418,17 @@
|
|||
<extends>QLabel</extends>
|
||||
<header>ksqueezedtextlabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QQuickWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">QtQuickWidgets/QQuickWidget</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KPluginWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>kpluginwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
81
kcm/list.qml
Normal file
81
kcm/list.qml
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2016 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kdeconnect
|
||||
|
||||
ScrollView {
|
||||
id: root
|
||||
|
||||
focus: true
|
||||
|
||||
signal clicked(string device)
|
||||
|
||||
property string currentDeviceId
|
||||
|
||||
property alias model: devices.model
|
||||
|
||||
Component.onCompleted: {
|
||||
if (background) {
|
||||
background.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: devices
|
||||
|
||||
focus: true
|
||||
|
||||
section {
|
||||
property: "status"
|
||||
delegate: Kirigami.ListSectionHeader {
|
||||
|
||||
width: ListView.view.width
|
||||
|
||||
text: switch (parseInt(section))
|
||||
{
|
||||
case DevicesModel.Paired:
|
||||
return i18nd("kdeconnect-kcm", "Remembered")
|
||||
case DevicesModel.Reachable:
|
||||
return i18nd("kdeconnect-kcm", "Available")
|
||||
case (DevicesModel.Reachable | DevicesModel.Paired):
|
||||
return i18nd("kdeconnect-kcm", "Connected")
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.PlaceholderMessage {
|
||||
text: i18nd("kdeconnect-kcm", "No devices found")
|
||||
icon.name: 'edit-none-symbolic'
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Kirigami.Units.largeSpacing * 4)
|
||||
visible: devices.count === 0
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: delegate
|
||||
icon.name: iconName
|
||||
text: model.name
|
||||
width: ListView.view.width
|
||||
highlighted: root.currentDeviceId === deviceId
|
||||
|
||||
focus: true
|
||||
|
||||
contentItem: Kirigami.IconTitleSubtitle {
|
||||
title: delegate.text
|
||||
subtitle: toolTip
|
||||
icon: icon.fromControlsIcon(delegate.icon)
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
root.currentDeviceId = deviceId
|
||||
root.clicked(deviceId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue