From 5291c774651fe371f67bf1ee36197d8e6acd47e5 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Tue, 21 Dec 2021 19:40:07 +0100 Subject: [PATCH] SystemDialog: Move the different implementations into a LnF file This way a LookAndFeel package can override the dialog and trim it to its needs. --- components/CMakeLists.txt | 1 + components/dialogs/MobileSystemDialog.qml | 325 ------------------ components/dialogs/SystemDialog.qml | 3 +- .../private/MobileSystemDialogButton.qml | 83 ----- components/dialogs/private/ScrollView.qml | 162 --------- components/lookandfeelqml/CMakeLists.txt | 15 + .../lookandfeelqml/kpackageinterface.cpp | 18 + components/lookandfeelqml/kpackageinterface.h | 22 ++ .../lookandfeelqml/lookandfeelqmlplugin.cpp | 25 ++ .../lookandfeelqml/lookandfeelqmlplugin.h | 18 + components/lookandfeelqml/qmldir | 2 + .../contents/systemdialog/SystemDialog.qml | 1 - .../lookandfeel/lookandfeel.cpp | 3 + 13 files changed, 106 insertions(+), 572 deletions(-) delete mode 100644 components/dialogs/MobileSystemDialog.qml delete mode 100644 components/dialogs/private/MobileSystemDialogButton.qml delete mode 100644 components/dialogs/private/ScrollView.qml create mode 100644 components/lookandfeelqml/CMakeLists.txt create mode 100644 components/lookandfeelqml/kpackageinterface.cpp create mode 100644 components/lookandfeelqml/kpackageinterface.h create mode 100644 components/lookandfeelqml/lookandfeelqmlplugin.cpp create mode 100644 components/lookandfeelqml/lookandfeelqmlplugin.h create mode 100644 components/lookandfeelqml/qmldir rename components/dialogs/DesktopSystemDialog.qml => lookandfeel/contents/systemdialog/SystemDialog.qml (99%) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 89bd6f727..3fcd082d1 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(containmentlayoutmanager) add_subdirectory(shellprivate) add_subdirectory(keyboardlayout) add_subdirectory(sessionsprivate) +add_subdirectory(lookandfeelqml) diff --git a/components/dialogs/MobileSystemDialog.qml b/components/dialogs/MobileSystemDialog.qml deleted file mode 100644 index 3f801098b..000000000 --- a/components/dialogs/MobileSystemDialog.qml +++ /dev/null @@ -1,325 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Devin Lin - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ - -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Window 2.15 -import QtGraphicalEffects 1.12 -import org.kde.kirigami 2.18 as Kirigami -import "private" as Private - -Item { - id: root - - default property Item mainItem - - /** - * Title of the dialog. - */ - property string mainText: "" - - /** - * Subtitle of the dialog. - */ - property string subtitle: "" - - /** - * This property holds the default padding of the content. - */ - property real padding: Kirigami.Units.smallSpacing - - /** - * This property holds the left padding of the content. If not specified, it uses `padding`. - */ - property real leftPadding: padding - - /** - * This property holds the right padding of the content. If not specified, it uses `padding`. - */ - property real rightPadding: padding - - /** - * This property holds the top padding of the content. If not specified, it uses `padding`. - */ - property real topPadding: padding - - /** - * This property holds the bottom padding of the content. If not specified, it uses `padding`. - */ - property real bottomPadding: padding - property alias standardButtons: footerButtonBox.standardButtons - - readonly property int flags: Qt.FramelessWindowHint | Qt.Dialog - readonly property real dialogCornerRadius: Kirigami.Units.smallSpacing * 2 - property list actions - property string iconName - - implicitWidth: loader.implicitWidth - implicitHeight: loader.implicitHeight - - readonly property real minimumHeight: implicitWidth - readonly property real minimumWidth: implicitHeight - - required property Kirigami.AbstractApplicationWindow window - - function present() { - root.window.showFullScreen() - } - - onWindowChanged: { - window.color = Qt.binding(() => { - return Qt.rgba(0, 0, 0, 0.5) - }) - } - - // load in async to speed up load times (especially on embedded devices) - Loader { - id: loader - anchors.centerIn: parent - asynchronous: true - - sourceComponent: Item { - // margins for shadow - implicitWidth: Math.min(Screen.width, control.implicitWidth + 2 * Kirigami.Units.gridUnit) - implicitHeight: Math.min(Screen.height, control.implicitHeight + 2 * Kirigami.Units.gridUnit) - - // shadow - RectangularGlow { - id: glow - anchors.topMargin: 1 - anchors.fill: control - cached: true - glowRadius: 2 - cornerRadius: Kirigami.Units.gridUnit - spread: 0.1 - color: Qt.rgba(0, 0, 0, 0.4) - } - - // actual window - Control { - id: control - anchors.fill: parent - anchors.margins: glow.cornerRadius - topPadding: 0 - bottomPadding: 0 - rightPadding: 0 - leftPadding: 0 - - background: Item { - Rectangle { // border - anchors.fill: parent - anchors.margins: -1 - radius: dialogCornerRadius + 1 - color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - } - Rectangle { // background colour - anchors.fill: parent - radius: dialogCornerRadius - color: Kirigami.Theme.backgroundColor - } - } - - contentItem: column - } - } - } - - readonly property var contents: ColumnLayout { - id: column - spacing: 0 - - // header - Control { - id: headerControl - - Layout.fillWidth: true - Layout.maximumWidth: root.window.maximumWidth - - topPadding: 0 - leftPadding: 0 - rightPadding: 0 - bottomPadding: 0 - - background: Item {} - - contentItem: RowLayout { - Kirigami.Heading { - Layout.fillWidth: true - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.bottomMargin: Kirigami.Units.largeSpacing - Layout.leftMargin: Kirigami.Units.largeSpacing - Layout.rightMargin: Kirigami.Units.largeSpacing - Layout.alignment: Qt.AlignVCenter - level: 2 - text: root.mainText - wrapMode: Text.Wrap - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - } - } - } - - // content - Control { - id: content - - Layout.fillHeight: true - Layout.fillWidth: true - Layout.maximumWidth: root.window.maximumWidth - - leftPadding: 0 - rightPadding: 0 - topPadding: 0 - bottomPadding: 0 - - background: Item {} - contentItem: ColumnLayout { - spacing: 0 - clip: true - - Label { - id: subtitleLabel - Layout.fillWidth: true - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.bottomMargin: Kirigami.Units.largeSpacing - Layout.leftMargin: Kirigami.Units.gridUnit * 3 - Layout.rightMargin: Kirigami.Units.gridUnit * 3 - visible: root.subtitle !== "" - horizontalAlignment: Text.AlignHCenter - text: root.subtitle - wrapMode: Label.Wrap - } - - // separator when scrolling - Kirigami.Separator { - Layout.fillWidth: true - opacity: root.mainItem && contentControl.flickableItem && contentControl.flickableItem.contentY !== 0 ? 1 : 0 // always maintain same height (as opposed to visible) - } - - // mainItem is in scrollview, in case of overflow - Private.ScrollView { - id: contentControl - clip: true - - // we cannot have contentItem inside a sub control (allowing for content padding within the scroll area), - // because if the contentItem is a Flickable (ex. ListView), the ScrollView needs it to be top level in order - // to decorate it - contentItem: root.mainItem - canFlickWithMouse: true - - // ensure window colour scheme, and background color - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Window - - // needs to explicitly be set for each side to work - leftPadding: root.leftPadding; topPadding: root.topPadding - rightPadding: root.rightPadding; bottomPadding: root.bottomPadding - - // height of everything else in the dialog other than the content - property real otherHeights: headerControl.height + subtitleLabel.height + footerButtonBox.height + root.topPadding + root.bottomPadding; - - property real calculatedMaximumWidth: root.window.maximumWidth > root.absoluteMaximumWidth ? root.absoluteMaximumWidth : root.window.maximumWidth - property real calculatedMaximumHeight: root.window.maximumHeight > root.absoluteMaximumHeight ? root.absoluteMaximumHeight : root.window.maximumHeight - property real calculatedImplicitWidth: root.mainItem ? (root.mainItem.implicitWidth ? root.mainItem.implicitWidth : root.mainItem.width) + root.leftPadding + root.rightPadding : 0 - property real calculatedImplicitHeight: root.mainItem ? (root.mainItem.implicitHeight ? root.mainItem.implicitHeight : root.mainItem.height) + root.topPadding + root.bottomPadding : 0 - - // don't enforce preferred width and height if not set - Layout.preferredWidth: root.preferredWidth >= 0 ? root.preferredWidth : calculatedImplicitWidth + contentControl.rightSpacing - Layout.preferredHeight: root.preferredHeight >= 0 ? root.preferredHeight - otherHeights : calculatedImplicitHeight + contentControl.bottomSpacing - - Layout.fillWidth: true - Layout.fillHeight: true - Layout.maximumWidth: calculatedMaximumWidth - Layout.maximumHeight: calculatedMaximumHeight >= otherHeights ? calculatedMaximumHeight - otherHeights : 0 // we enforce maximum height solely from the content - - // give an implied width and height to the contentItem so that features like word wrapping/eliding work - // cannot placed directly in contentControl as a child, so we must use a property - property var widthHint: Binding { - target: root.mainItem - property: "width" - // we want to avoid horizontal scrolling, so we apply maximumWidth as a hint if necessary - property real preferredWidthHint: contentControl.width - root.leftPadding - root.rightPadding - contentControl.rightSpacing - property real maximumWidthHint: contentControl.calculatedMaximumWidth - root.leftPadding - root.rightPadding - contentControl.rightSpacing - value: maximumWidthHint < preferredWidthHint ? maximumWidthHint : preferredWidthHint - } - property var heightHint: Binding { - target: root.mainItem - property: "height" - // we are okay with overflow, if it exceeds maximumHeight we will allow scrolling - value: contentControl.Layout.preferredHeight - root.topPadding - root.bottomPadding - contentControl.bottomSpacing - } - - // give explicit warnings since the maximumHeight is ignored when negative, so developers aren't confused - Component.onCompleted: { - if (contentControl.Layout.maximumHeight < 0 || contentControl.Layout.maximumHeight === Infinity) { - console.log("Dialog Warning: the calculated maximumHeight for the content is " + contentControl.Layout.maximumHeight + ", ignoring..."); - } - } - } - } - } - Control { - Layout.fillWidth: true - - leftPadding: 0 - rightPadding: 0 - topPadding: 0 - bottomPadding: 0 - contentItem: footerButtonBox - } - } - - readonly property DialogButtonBox dialogButtonBox: DialogButtonBox { - //We want to report the same width on all so the button area is split equally - id: footerButtonBox - Layout.fillWidth: true - onAccepted: root.window.accept() - onRejected: root.window.reject() - implicitHeight: contentItem.implicitHeight - alignment: undefined - - readonly property real sameWidth: 50 - delegate: Private.MobileSystemDialogButton { - Layout.fillWidth: true - Layout.preferredWidth: footerButtonBox.sameWidth - - readonly property point globalPos: root.window.visible ? mapToItem(footerButtonBox, Qt.point(x, y)) : Qt.point(0, 0) - verticalSeparator: globalPos.x > 0 && root.window.layout === Qt.Horizontal - horizontalSeparator: true - corners.bottomLeftRadius: verticalSeparator ? 0 : root.dialogCornerRadius - corners.bottomRightRadius: globalPos.x >= footerButtonBox.width ? root.dialogCornerRadius : 0 - } - - leftPadding: 0 - rightPadding: 0 - topPadding: 0 - bottomPadding: 0 - - contentItem: GridLayout { - Layout.fillWidth: true - - rowSpacing: 0 - columnSpacing: 0 - rows: root.window.layout === Qt.Vertical ? Number.MAX_VALUE : 1 - columns: root.window.layout !== Qt.Vertical ? Number.MAX_VALUE : 1 - - Repeater { - model: root.actions - delegate: Private.MobileSystemDialogButton { - Layout.fillWidth: true - Layout.preferredWidth: footerButtonBox.sameWidth - readonly property point globalPos: root.window.visible ? mapToItem(footerButtonBox, Qt.point(x, y)) : Qt.point(0, 0) - verticalSeparator: globalPos.x > 0 && root.window.layout === Qt.Horizontal - horizontalSeparator: true - corners.bottomLeftRadius: model.index === root.actions.length - 1 ? root.dialogCornerRadius : 0 - corners.bottomRightRadius: model.index === root.actions.length - 1 && footerButtonBox.standardButtons === 0 ? root.dialogCornerRadius : 0 - action: modelData - } - } - } - } -} diff --git a/components/dialogs/SystemDialog.qml b/components/dialogs/SystemDialog.qml index 3de059eac..06f405602 100644 --- a/components/dialogs/SystemDialog.qml +++ b/components/dialogs/SystemDialog.qml @@ -10,6 +10,7 @@ import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import QtGraphicalEffects 1.12 import org.kde.kirigami 2.18 as Kirigami +import org.kde.plasma.lookandfeel 1.0 /** * Component to create CSD dialogs that come from the system. @@ -110,7 +111,7 @@ Kirigami.AbstractApplicationWindow { id: contentDialog anchors.fill: parent Component.onCompleted: { - var component = !Kirigami.Settings.tabletMode ? "MobileSystemDialog.qml" : "DesktopSystemDialog.qml" + var component = LookAndFeel.fileUrl("systemdialogscript") setSource(component, { window: root, mainText: root.mainText, diff --git a/components/dialogs/private/MobileSystemDialogButton.qml b/components/dialogs/private/MobileSystemDialogButton.qml deleted file mode 100644 index 1fc6c4cb1..000000000 --- a/components/dialogs/private/MobileSystemDialogButton.qml +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Devin Lin - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ - -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Window 2.2 -import QtGraphicalEffects 1.12 -import org.kde.kirigami 2.18 as Kirigami - -AbstractButton { - id: root - - property alias corners: background.corners - - property bool verticalSeparator: false - property bool horizontalSeparator: false - - background: Kirigami.ShadowedRectangle { - id: background - Kirigami.Theme.colorSet: Kirigami.Theme.Button - Kirigami.Theme.inherit: false - color: { - if (root.down) { - let avg = (Kirigami.Theme.backgroundColor.r + Kirigami.Theme.backgroundColor.g + Kirigami.Theme.backgroundColor.b) / 3; - // sample down - avg = Math.max(0, (avg - 0.8) * 5); - return Qt.darker(Kirigami.Theme.backgroundColor, 1.1 + 0.4 * (1 - avg)); - } else if (hoverHandler.hovered) { - return Qt.darker(Kirigami.Theme.backgroundColor, 1.05) - } else { - return Kirigami.Theme.backgroundColor - } - } - - Kirigami.Separator { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - visible: root.verticalSeparator - } - Kirigami.Separator { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - visible: root.horizontalSeparator - } - } - - leftPadding: Kirigami.Units.largeSpacing - rightPadding: Kirigami.Units.largeSpacing - topPadding: Kirigami.Units.largeSpacing - bottomPadding: Kirigami.Units.largeSpacing - - contentItem: Item { - implicitHeight: row.height + Kirigami.Units.smallSpacing - implicitWidth: row.implicitWidth - RowLayout { - id: row - anchors.centerIn: parent - spacing: 0 - - Kirigami.Icon { - Layout.preferredHeight: label.height - Layout.preferredWidth: height - Layout.rightMargin: Kirigami.Units.smallSpacing - visible: root.icon.name - source: root.icon.name - } - Label { - id: label - text: root.text - } - } - - HoverHandler { - id: hoverHandler - } - } -} diff --git a/components/dialogs/private/ScrollView.qml b/components/dialogs/private/ScrollView.qml deleted file mode 100644 index a1fb5c7d6..000000000 --- a/components/dialogs/private/ScrollView.qml +++ /dev/null @@ -1,162 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2016 Marco Martin - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQml 2.15 -import org.kde.kirigami 2.9 as Kirigami - -// taken from Kirigami -MouseArea { - id: root - default property Item contentItem - property Flickable flickableItem - clip: true - - property int horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - property int verticalScrollBarPolicy: Qt.ScrollBarAsNeeded - property int topPadding: 0 - property int leftPadding: 0 - property int bottomPadding: 0 - property int rightPadding: 0 - property bool canFlickWithMouse: false - - // Note: These are used because RefreshableScrollView overrides right and - // bottom padding properties. - property int rightSpacing: !Kirigami.Settings.hasTransientTouchInput && flickableItem && flickableItem.ScrollBar.vertical && flickableItem.ScrollBar.vertical.visible ? flickableItem.ScrollBar.vertical.width : 0 - property int bottomSpacing: !Kirigami.Settings.hasTransientTouchInput && flickableItem && flickableItem.ScrollBar.horizontal && flickableItem.ScrollBar.horizontal.visible ? flickableItem.ScrollBar.horizontal.height : 0 - - Accessible.onScrollDownAction: flickableItem.Accessible.onScrollDownAction - Accessible.onScrollUpAction: flickableItem.Accessible.onScrollUpAction - - Keys.onUpPressed: scroll(Kirigami.Units.gridUnit * 2) - Keys.onDownPressed: scroll(-Kirigami.Units.gridUnit * 2) - - function scroll(y) { - // Don't scroll if the view isn't scrollable! - if (flickableItem.contentHeight < flickableItem.height + flickableItem.contentY) { - return; - } - const minYExtent = flickableItem.topMargin - flickableItem.originY; - const maxYExtent = flickableItem.height - (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY); - - flickableItem.contentY = Math.min(-maxYExtent, Math.max(-minYExtent, flickableItem.contentY - y)); - } - - focus: true - - onPressed: mouse.accepted = mouse.source !== Qt.MouseEventNotSynthesized - onVerticalScrollBarPolicyChanged: { - scrollBarCreationTimer.restart(); - } - onHorizontalScrollBarPolicyChanged: { - scrollBarCreationTimer.restart(); - } - - - onContentItemChanged: { - if (contentItem.hasOwnProperty("contentY")) { - flickableItem = contentItem; - if (typeof(flickableItem.keyNavigationEnabled) != "undefined") { - flickableItem.keyNavigationEnabled = true; - flickableItem.keyNavigationWraps = false; - } - contentItem.parent = flickableParent; - } else { - flickableItem = flickableComponent.createObject(flickableParent); - contentItem.parent = flickableItem.contentItem; - } - - flickableItem.anchors.fill = flickableParent; - - scrollBarCreationTimer.restart(); - } - - Binding { - when: !root.canFlickWithMouse - target: root.flickableItem - property: "interactive" - value: Kirigami.Settings.hasTransientTouchInput - restoreMode: Binding.RestoreBinding - } - Timer { - id: scrollBarCreationTimer - interval: 0 - onTriggered: { - //create or destroy the vertical scrollbar - if ((!flickableItem.ScrollBar.vertical) && - verticalScrollBarPolicy != Qt.ScrollBarAlwaysOff) { - flickableItem.ScrollBar.vertical = verticalScrollComponent.createObject(root); - } else if (flickableItem.ScrollBar.vertical && - verticalScrollBarPolicy == Qt.ScrollBarAlwaysOff) { - flickableItem.ScrollBar.vertical.destroy(); - } - - //create or destroy the horizontal scrollbar - if ((!flickableItem.ScrollBar.horizontal) && - horizontalScrollBarPolicy != Qt.ScrollBarAlwaysOff) { - flickableItem.ScrollBar.horizontal = horizontalScrollComponent.createObject(root); - } else if (flickableItem.ScrollBar.horizontal && - horizontalScrollBarPolicy == Qt.ScrollBarAlwaysOff) { - flickableItem.ScrollBar.horizontal.destroy(); - } - } - } - Kirigami.WheelHandler { - id: wheelHandler - target: root.flickableItem - } - Item { - id: flickableParent - clip: true - anchors { - fill: parent - leftMargin: root.leftPadding - topMargin: root.topPadding - rightMargin: root.rightPadding + root.rightSpacing - bottomMargin: root.bottomPadding + root.bottomSpacing - } - } - Component { - id: flickableComponent - Flickable { - anchors { - fill: parent - } - contentWidth: root.contentItem ? root.contentItem.width : 0 - contentHeight: root.contentItem ? root.contentItem.height : 0 - } - } - Component { - id: verticalScrollComponent - ScrollBar { - z: flickableParent.z + 1 - visible: root.verticalScrollBarPolicy != Qt.ScrollBarAlwaysOff && root.contentItem.visible && size < 1 - interactive: !Kirigami.Settings.hasTransientTouchInput - - anchors { - right: parent.right - top: parent.top - bottom: parent.bottom - bottomMargin: root.bottomSpacing - } - } - } - Component { - id: horizontalScrollComponent - ScrollBar { - z: flickableParent.z + 1 - visible: root.horizontalScrollBarPolicy != Qt.ScrollBarAlwaysOff && root.contentItem.visible && size < 1 - interactive: !Kirigami.Settings.hasTransientTouchInput - - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - rightMargin: root.rightSpacing - } - } - } -} diff --git a/components/lookandfeelqml/CMakeLists.txt b/components/lookandfeelqml/CMakeLists.txt new file mode 100644 index 000000000..f78aa84e0 --- /dev/null +++ b/components/lookandfeelqml/CMakeLists.txt @@ -0,0 +1,15 @@ +set(lookandfeelqmlplugin_SRCS + lookandfeelqmlplugin.cpp + kpackageinterface.cpp +) + +add_library(lookandfeelqmlplugin SHARED ${lookandfeelqmlplugin_SRCS}) +target_link_libraries(lookandfeelqmlplugin + Qt::Qml + KF5::ConfigCore + KF5::Package +) + +install(TARGETS lookandfeelqmlplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/lookandfeel) + +install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/lookandfeel) diff --git a/components/lookandfeelqml/kpackageinterface.cpp b/components/lookandfeelqml/kpackageinterface.cpp new file mode 100644 index 000000000..4881ff61b --- /dev/null +++ b/components/lookandfeelqml/kpackageinterface.cpp @@ -0,0 +1,18 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "kpackageinterface.h" + +KPackageInterface::KPackageInterface(const KPackage::Package &package) + : m_package(package) +{ + Q_ASSERT(m_package.isValid()); +} + +QUrl KPackageInterface::fileUrl(const QByteArray &key) const +{ + return m_package.fileUrl(key); +} diff --git a/components/lookandfeelqml/kpackageinterface.h b/components/lookandfeelqml/kpackageinterface.h new file mode 100644 index 000000000..34c4cb721 --- /dev/null +++ b/components/lookandfeelqml/kpackageinterface.h @@ -0,0 +1,22 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#pragma once + +#include +#include + +class KPackageInterface : public QObject +{ + Q_OBJECT +public: + KPackageInterface(const KPackage::Package &package); + + Q_INVOKABLE QUrl fileUrl(const QByteArray &key) const; + +private: + const KPackage::Package m_package; +}; diff --git a/components/lookandfeelqml/lookandfeelqmlplugin.cpp b/components/lookandfeelqml/lookandfeelqmlplugin.cpp new file mode 100644 index 000000000..6c7d760b0 --- /dev/null +++ b/components/lookandfeelqml/lookandfeelqmlplugin.cpp @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "lookandfeelqmlplugin.h" + +#include "kpackageinterface.h" +#include +#include +#include +#include + +void SessionsPrivatePlugin::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.plasma.lookandfeel")); + + qmlRegisterSingletonType(uri, 1, 0, "LookAndFeel", [](QQmlEngine *, QJSEngine *) { + KConfigGroup cg(KSharedConfig::openConfig(), "KDE"); + const QString packageName = cg.readEntry("LookAndFeelPackage", QString()); + const auto package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel"), packageName); + return new KPackageInterface(package); + }); +} diff --git a/components/lookandfeelqml/lookandfeelqmlplugin.h b/components/lookandfeelqml/lookandfeelqmlplugin.h new file mode 100644 index 000000000..64823086f --- /dev/null +++ b/components/lookandfeelqml/lookandfeelqmlplugin.h @@ -0,0 +1,18 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#pragma once + +#include + +class SessionsPrivatePlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri) override; +}; diff --git a/components/lookandfeelqml/qmldir b/components/lookandfeelqml/qmldir new file mode 100644 index 000000000..3568e10c2 --- /dev/null +++ b/components/lookandfeelqml/qmldir @@ -0,0 +1,2 @@ +module org.kde.plasma.lookandfeel +plugin lookandfeelqmlplugin diff --git a/components/dialogs/DesktopSystemDialog.qml b/lookandfeel/contents/systemdialog/SystemDialog.qml similarity index 99% rename from components/dialogs/DesktopSystemDialog.qml rename to lookandfeel/contents/systemdialog/SystemDialog.qml index eaa4bb6b9..4dc0f8fc2 100644 --- a/components/dialogs/DesktopSystemDialog.qml +++ b/lookandfeel/contents/systemdialog/SystemDialog.qml @@ -10,7 +10,6 @@ import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import QtGraphicalEffects 1.12 import org.kde.kirigami 2.18 as Kirigami -import "private" as Private /** * Dialog used on desktop. Uses SSDs (as opposed to CSDs). diff --git a/shell/packageplugins/lookandfeel/lookandfeel.cpp b/shell/packageplugins/lookandfeel/lookandfeel.cpp index 58992cca8..d50b3e96f 100644 --- a/shell/packageplugins/lookandfeel/lookandfeel.cpp +++ b/shell/packageplugins/lookandfeel/lookandfeel.cpp @@ -70,6 +70,9 @@ void LookAndFeelPackage::initPackage(KPackage::Package *package) package->addDirectoryDefinition("windowswitcher", QStringLiteral("windowswitcher"), i18n("Window Switcher")); package->addFileDefinition("windowswitchermainscript", QStringLiteral("windowswitcher/WindowSwitcher.qml"), i18n("Main Script for Window Switcher")); + package->addDirectoryDefinition("systemdialog", QStringLiteral("systemdialog"), i18n("System Dialog")); + package->addFileDefinition("systemdialogscript", QStringLiteral("systemdialog/SystemDialog.qml"), i18n("The system dialog")); + package->addDirectoryDefinition("layouts", QStringLiteral("layouts"), i18n("Default layout scripts")); package->setPath(DEFAULT_LOOKANDFEEL);