diff --git a/components/containmentlayoutmanager/appletcontainer.cpp b/components/containmentlayoutmanager/appletcontainer.cpp index 83200b8dc..ae5456d79 100644 --- a/components/containmentlayoutmanager/appletcontainer.cpp +++ b/components/containmentlayoutmanager/appletcontainer.cpp @@ -1,109 +1,168 @@ /* * Copyright 2019 by Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "appletcontainer.h" #include #include #include #include AppletContainer::AppletContainer(QQuickItem *parent) : ItemContainer(parent) { connect(this, &AppletContainer::contentItemChanged, this, [this]() { if (m_appletItem) { disconnect(m_appletItem->applet(), &Plasma::Applet::busyChanged, this, nullptr); } m_appletItem = qobject_cast(contentItem()); connectBusyIndicator(); + connectConfigurationRequired(); emit appletChanged(); }); } AppletContainer::~AppletContainer() { } void AppletContainer::componentComplete() { connectBusyIndicator(); + connectConfigurationRequired(); ItemContainer::componentComplete(); } PlasmaQuick::AppletQuickItem *AppletContainer::applet() { return m_appletItem; } QQmlComponent *AppletContainer::busyIndicatorComponent() const { return m_busyIndicatorComponent; } void AppletContainer::setBusyIndicatorComponent(QQmlComponent *component) { if (m_busyIndicatorComponent == component) { return; } m_busyIndicatorComponent = component; if (m_busyIndicatorItem) { m_busyIndicatorItem->deleteLater(); m_busyIndicatorItem = nullptr; } emit busyIndicatorComponentChanged(); } void AppletContainer::connectBusyIndicator() { if (m_appletItem && !m_busyIndicatorItem) { Q_ASSERT(m_appletItem->applet()); connect(m_appletItem->applet(), &Plasma::Applet::busyChanged, this, [this] () { if (!m_busyIndicatorComponent || !m_appletItem->applet()->isBusy() || m_busyIndicatorItem) { return; } QQmlContext *context = QQmlEngine::contextForObject(this); Q_ASSERT(context); QObject *instance = m_busyIndicatorComponent->beginCreate(context); m_busyIndicatorItem = qobject_cast(instance); if (!m_busyIndicatorItem) { qWarning() << "Error: busyIndicatorComponent not of Item type"; if (instance) { instance->deleteLater(); } return; } m_busyIndicatorItem->setParentItem(this); m_busyIndicatorItem->setZ(999); m_busyIndicatorComponent->completeCreate(); }); } } +QQmlComponent *AppletContainer::configurationRequiredComponent() const +{ + return m_configurationRequiredComponent; +} + +void AppletContainer::setConfigurationRequiredComponent(QQmlComponent *component) +{ + if (m_configurationRequiredComponent == component) { + return; + } + + m_configurationRequiredComponent = component; + + if (m_configurationRequiredItem) { + m_configurationRequiredItem->deleteLater(); + m_configurationRequiredItem = nullptr; + } + + emit configurationRequiredComponentChanged(); +} + +void AppletContainer::connectConfigurationRequired() +{ + if (m_appletItem && !m_configurationRequiredItem) { + Q_ASSERT(m_appletItem->applet()); + + auto syncConfigRequired = [this] () { + if (!m_configurationRequiredComponent || !m_appletItem->applet()->configurationRequired() || m_configurationRequiredItem) { + return; + } + + QQmlContext *context = QQmlEngine::contextForObject(this); + Q_ASSERT(context); + QObject *instance = m_configurationRequiredComponent->beginCreate(context); + m_configurationRequiredItem = qobject_cast(instance); + + if (!m_configurationRequiredItem) { + qWarning() << "Error: configurationRequiredComponent not of Item type"; + if (instance) { + instance->deleteLater(); + } + return; + } + + m_configurationRequiredItem->setParentItem(this); + m_configurationRequiredItem->setZ(998); + m_configurationRequiredComponent->completeCreate(); + }; + + connect(m_appletItem->applet(), &Plasma::Applet::configurationRequiredChanged, this, syncConfigRequired); + + if (m_appletItem->applet()->configurationRequired()) { + syncConfigRequired(); + } + } +} + #include "moc_appletcontainer.cpp" diff --git a/components/containmentlayoutmanager/appletcontainer.h b/components/containmentlayoutmanager/appletcontainer.h index 0b701079e..28465d041 100644 --- a/components/containmentlayoutmanager/appletcontainer.h +++ b/components/containmentlayoutmanager/appletcontainer.h @@ -1,65 +1,74 @@ /* * Copyright 2019 by Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #pragma once #include "itemcontainer.h" #include #include namespace PlasmaQuick { class AppletQuickItem; } class AppletContainer: public ItemContainer { Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(PlasmaQuick::AppletQuickItem *applet READ applet NOTIFY appletChanged) Q_PROPERTY(QQmlComponent *busyIndicatorComponent READ busyIndicatorComponent WRITE setBusyIndicatorComponent NOTIFY busyIndicatorComponentChanged) + Q_PROPERTY(QQmlComponent *configurationRequiredComponent READ configurationRequiredComponent WRITE setConfigurationRequiredComponent NOTIFY configurationRequiredComponentChanged) + public: AppletContainer(QQuickItem *parent = nullptr); ~AppletContainer(); PlasmaQuick::AppletQuickItem *applet(); QQmlComponent *busyIndicatorComponent() const; void setBusyIndicatorComponent(QQmlComponent *comp); + QQmlComponent *configurationRequiredComponent() const; + void setConfigurationRequiredComponent(QQmlComponent *comp); + protected: void componentComplete() override; Q_SIGNALS: void appletChanged(); void busyIndicatorComponentChanged(); + void configurationRequiredComponentChanged(); private: void connectBusyIndicator(); + void connectConfigurationRequired(); QPointer m_appletItem; QPointer m_busyIndicatorComponent; QQuickItem *m_busyIndicatorItem = nullptr; + QPointer m_configurationRequiredComponent; + QQuickItem *m_configurationRequiredItem = nullptr; }; diff --git a/components/containmentlayoutmanager/qml/BasicAppletContainer.qml b/components/containmentlayoutmanager/qml/BasicAppletContainer.qml index 8b95fbb42..3dd5610bf 100644 --- a/components/containmentlayoutmanager/qml/BasicAppletContainer.qml +++ b/components/containmentlayoutmanager/qml/BasicAppletContainer.qml @@ -1,84 +1,89 @@ /* * Copyright 2019 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.12 import QtQuick.Layouts 1.2 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 3.0 as PlasmaComponents import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager ContainmentLayoutManager.AppletContainer { id: appletContainer editModeCondition: plasmoid.immutable ? ContainmentLayoutManager.ItemContainer.Manual : ContainmentLayoutManager.ItemContainer.AfterPressAndHold Layout.minimumWidth: { if (!applet) { return leftPadding + rightPadding; } if (applet.preferredRepresentation != applet.fullRepresentation && applet.compactRepresentationItem ) { return applet.compactRepresentationItem.Layout.minimumWidth + leftPadding + rightPadding; } else { return applet.Layout.minimumWidth + leftPadding + rightPadding; } } Layout.minimumHeight: { if (!applet) { return topPadding + bottomPadding; } if (applet.preferredRepresentation != applet.fullRepresentation && applet.compactRepresentationItem ) { return applet.compactRepresentationItem.Layout.minimumHeight + topPadding + bottomPadding; } else { return applet.Layout.minimumHeight + topPadding + bottomPadding; } } Layout.preferredWidth: Math.max(applet.Layout.minimumWidth, applet.Layout.preferredWidth) Layout.preferredHeight: Math.max(applet.Layout.minimumHeight, applet.Layout.preferredHeight) Layout.maximumWidth: applet.Layout.maximumWidth Layout.maximumHeight: applet.Layout.maximumHeight leftPadding: background.margins.left topPadding: background.margins.top rightPadding: background.margins.right bottomPadding: background.margins.bottom initialSize.width: applet.switchWidth + leftPadding + rightPadding initialSize.height: applet.switchHeight + topPadding + bottomPadding background: PlasmaCore.FrameSvgItem { imagePath: contentItem && contentItem.backgroundHints == PlasmaCore.Types.StandardBackground ? "widgets/background" : "" } busyIndicatorComponent: PlasmaComponents.BusyIndicator { anchors.centerIn: parent visible: applet.busy running: visible } + configurationRequiredComponent: PlasmaComponents.Button { + anchors.centerIn: parent + text: i18n("Configure...") + onClicked: applet.action("configure").trigger(); + } }