Merge branch 'mart/AppletAttached'

Conflicts:
	src/declarativeimports/core/dialog.cpp
	src/scriptengines/qml/plasmoid/containmentinterface.cpp
This commit is contained in:
Marco Martin 2014-02-06 13:16:11 +01:00
commit 3858044d25
34 changed files with 1196 additions and 606 deletions

View File

@ -19,13 +19,14 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
property int minimumWidth: 200
property int minimumHeight: 300
property Component compactRepresentation: Component {
Layout.minimumWidth: 200
Layout.minimumHeight: 300
Plasmoid.compactRepresentation: Component {
PlasmaComponents.Button {
text: i18n("Click me")
onClicked: plasmoid.expanded = !plasmoid.expanded

View File

@ -17,6 +17,7 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import QtQuick.Layouts 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
@ -30,10 +31,10 @@ Rectangle {
height: 100
radius: 10
smooth: true
property int minimumWidth: units.gridUnit * 20
property int minimumHeight: column.implicitHeight
Layout.minimumWidth: units.gridUnit * 20
Layout.minimumHeight: column.implicitHeight
property Component compactRepresentation: Component {
Plasmoid.compactRepresentation: Component {
Rectangle {
MouseArea {
anchors.fill: parent

View File

@ -26,8 +26,8 @@ Item {
id: root
width: 100
height: 100
property int minimumWidth: units.gridUnit * 20
property int minimumHeight: column.implicitHeight
Layout.minimumWidth: units.gridUnit * 20
Layout.minimumHeight: column.implicitHeight
ColumnLayout {

View File

@ -19,6 +19,7 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
@ -26,8 +27,8 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras
Column {
width: 500
height: 500
property int minimumWidth: 200
property int minimumHeight: 300
Layout.minimumWidth: 200
Layout.minimumHeight: 300
PlasmaCore.DataSource {
id: source

View File

@ -19,12 +19,13 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
property int minimumWidth: 200
property int minimumHeight: 300
Layout.minimumWidth: 200
Layout.minimumHeight: 300
PlasmaComponents.Label {
text: i18n("Hello world")

View File

@ -18,12 +18,13 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
PlasmaCore.SvgItem {
property int minimumWidth: 150
property int minimumHeight: 150
Layout.minimumWidth: 150
Layout.minimumHeight: 150
svg: PlasmaCore.Svg("widgets/notes")
elementId: "yellow-notes"

View File

@ -27,8 +27,8 @@ Item {
width: 400
height: 32
property bool fillWidth: true
property bool fillHeight: true
Layout.fillWidth: true
Layout.fillHeight: true
implicitWidth: tasksModel.count * 50
PlasmaCore.DataSource {

View File

@ -28,8 +28,8 @@ Item {
width: 100
height: 100
clip: true
property int minimumWidth: units.gridUnit * 20
property int minimumHeight: units.gridUnit * 30
Layout.minimumWidth: units.gridUnit * 20
Layout.minimumHeight: units.gridUnit * 30
property int _s: units.iconSizes.small
property int _h: units.iconSizes.desktop

View File

@ -28,8 +28,8 @@ Item {
width: 400
height: 400
property int minimumWidth: units.gridUnit * 20
property int minimumHeight: units.gridUnit * 30
Layout.minimumWidth: units.gridUnit * 20
Layout.minimumHeight: units.gridUnit * 30
property int _s: units.iconSizes.small
property int _h: units.iconSizes.desktop
property int _m: 12

View File

@ -28,8 +28,8 @@ Item {
width: 300
height: 400
clip: true
property int minimumWidth: units.gridUnit * 10
property int minimumHeight: units.gridUnit * 10
Layout.minimumWidth: units.gridUnit * 10
Layout.minimumHeight: units.gridUnit * 10
property int _s: units.iconSizes.small
property int _h: units.iconSizes.medium

View File

@ -18,33 +18,40 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import QtQuick.Layouts 1.1
import org.kde.plasma.components 2.0
Item {
property int minimumWidth: 300
property int minimumHeight: 400
Plasmoid.switchWidth: 300
Plasmoid.switchHeight: 400
ToolBar {
id: toolBar
z: 10
anchors {
top: parent.top
left: parent.left
right: parent.right
Plasmoid.fullRepresentation: Item {
Layout.minimumWidth: 300
Layout.minimumHeight: 400
ToolBar {
id: toolBar
z: 10
//AppletInterface.title: "bah"
anchors {
top: parent.top
left: parent.left
right: parent.right
}
}
}
PageStack {
id: pageStack
toolBar: toolBar
clip: true
anchors {
top: toolBar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
PageStack {
id: pageStack
toolBar: toolBar
clip: true
anchors {
top: toolBar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
initialPage: Qt.createComponent("Menu.qml")
}
initialPage: Qt.createComponent("Menu.qml")
}
}

View File

@ -18,11 +18,12 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0
Image {
property int minimumWidth: 300
property int minimumHeight: 400
Layout.minimumWidth: 300
Layout.minimumHeight: 400
source: "image://appbackgrounds/standard"
fillMode: Image.Tile
asynchronous: true

View File

@ -20,6 +20,7 @@
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
@ -28,8 +29,8 @@ Item {
width: 400
height: 32
property bool fillWidth: true
property bool fillHeight: true
Layout.fillWidth: true
Layout.fillHeight: true
PlasmaCore.DataSource {
id: tasksSource

View File

@ -44,6 +44,10 @@
#include <xcb/shape.h>
#endif
//Unfortunately QWINDOWSIZE_MAX is not exported
#define DIALOGSIZE_MAX ((1<<24)-1)
DialogProxy::DialogProxy(QQuickItem *parent)
: QQuickWindow(parent ? parent->window() : 0),
m_location(Plasma::Types::BottomEdge),
@ -114,6 +118,36 @@ void DialogProxy::setMainItem(QQuickItem *mainItem)
});
}
requestSyncToMainItemSize();
//Extract the representation's Layout, if any
QObject *layout = 0;
//Search a child that has the needed Layout properties
//HACK: here we are not type safe, but is the only way to access to a pointer of Layout
foreach (QObject *child, mainItem->children()) {
//find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight
if (child->property("minimumWidth").isValid() && child->property("minimumHeight").isValid() &&
child->property("preferredWidth").isValid() && child->property("preferredHeight").isValid() &&
child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() &&
child->property("fillWidth").isValid() && child->property("fillHeight").isValid()
) {
layout = child;
}
}
m_mainItemLayout = layout;
if (layout) {
connect(layout, SIGNAL(minimumWidthChanged()), this, SLOT(updateMinimumWidth()));
connect(layout, SIGNAL(minimumHeightChanged()), this, SLOT(updateMinimumHeight()));
connect(layout, SIGNAL(maximumWidthChanged()), this, SLOT(updatemaximumWidth()));
connect(layout, SIGNAL(maximumHeightChanged()), this, SLOT(updatemaximumHeight()));
updateMinimumWidth();
updateMinimumHeight();
updateMaximumWidth();
updateMaximumHeight();
}
}
//if this is called in Component.onCompleted we have to wait a loop the item is added to a scene
@ -604,6 +638,7 @@ void DialogProxy::updateInputShape()
#endif
}
//find the screen which contains the item
QScreen* DialogProxy::screenForItem(QQuickItem* item) const
{
@ -616,5 +651,51 @@ QScreen* DialogProxy::screenForItem(QQuickItem* item) const
return QGuiApplication::primaryScreen();
}
void DialogProxy::updateMinimumWidth()
{
if (m_mainItemLayout) {
setMinimumWidth(m_mainItemLayout.data()->property("minimumWidth").toInt());
} else {
setMinimumWidth(-1);
}
}
void DialogProxy::updateMinimumHeight()
{
if (m_mainItemLayout) {
setMinimumHeight(m_mainItemLayout.data()->property("minimumHeight").toInt());
} else {
setMinimumHeight(-1);
}
}
void DialogProxy::updateMaximumWidth()
{
if (m_mainItemLayout) {
const int hint = m_mainItemLayout.data()->property("maximumWidth").toInt();
if (hint > 0) {
setMaximumWidth(hint);
} else {
setMaximumWidth(DIALOGSIZE_MAX);
}
} else {
setMaximumWidth(DIALOGSIZE_MAX);
}
}
void DialogProxy::updateMaximumHeight()
{
if (m_mainItemLayout) {
const int hint = m_mainItemLayout.data()->property("maximumHeight").toInt();
if (hint > 0) {
setMaximumWidth(hint);
} else {
setMaximumWidth(DIALOGSIZE_MAX);
}
} else {
setMaximumHeight(DIALOGSIZE_MAX);
}
}
#include "dialog.moc"

View File

@ -172,6 +172,11 @@ private Q_SLOTS:
void updateVisibility(bool visible);
void updateMinimumWidth();
void updateMinimumHeight();
void updateMaximumWidth();
void updateMaximumHeight();
private:
QScreen* screenForItem(QQuickItem *item) const;
@ -180,6 +185,9 @@ private:
bool m_hideOnWindowDeactivate;
bool m_outputOnly;
Plasma::Theme m_theme;
//Attached Layout property of mainItem, if any
QWeakPointer <QObject> m_mainItemLayout;
};
#endif

View File

@ -415,6 +415,21 @@ class PLASMA_EXPORT Applet : public QObject
public Q_SLOTS:
//BOOKKEEPING
/**
* Call this method when the applet fails to launch properly. An
* optional reason can be provided.
*
* Not that all children items will be deleted when this method is
* called. If you have pointers to these items, you will need to
* reset them after calling this method.
*
* @param failed true when the applet failed, false when it succeeded
* @param reason an optional reason to show the user why the applet
* failed to launch
* @since 5.0
**/
void setLaunchErrorMessage(const QString &reason = QString());
/**
* Sets the immutability type for this applet (not immutable,
* user immutable or system immutable)
@ -488,22 +503,6 @@ class PLASMA_EXPORT Applet : public QObject
*/
Applet(QObject *parent, const QVariantList &args);
//BOOKEEPING
/**
* Call this method when the applet fails to launch properly. An
* optional reason can be provided.
*
* Not that all children items will be deleted when this method is
* called. If you have pointers to these items, you will need to
* reset them after calling this method.
*
* @param failed true when the applet failed, false when it succeeded
* @param reason an optional reason to show the user why the applet
* failed to launch
* @since 5.0
**/
void setLaunchErrorMessage(const QString &reason = QString());
//CONFIGURATION
/**
* When called, the Applet should write any information needed as part

View File

@ -358,12 +358,21 @@ KConfigGroup *AppletPrivate::mainConfigGroup()
return mainConfig;
}
Containment *c = q->containment();
Plasma::Applet *parentApplet = 0;
if (c) {
parentApplet = qobject_cast<Plasma::Applet *>(c->parent());
}
if (q->isContainment()) {
Corona *corona = static_cast<Containment*>(q)->corona();
KConfigGroup containmentConfig;
//qDebug() << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
if (corona) {
if (parentApplet) {
containmentConfig = parentApplet->config();
containmentConfig = KConfigGroup(&containmentConfig, "Containments");
} else if (corona) {
containmentConfig = KConfigGroup(corona->config(), "Containments");
} else {
containmentConfig = KConfigGroup(KSharedConfig::openConfig(), "Containments");
@ -373,14 +382,7 @@ KConfigGroup *AppletPrivate::mainConfigGroup()
} else {
KConfigGroup appletConfig;
Containment *c = q->containment();
Applet *parentApplet = qobject_cast<Applet *>(q->parent());
if (parentApplet && parentApplet != static_cast<Applet *>(c)) {
// this applet is nested inside another applet! use it's config
// as the parent group in the config
appletConfig = parentApplet->config();
appletConfig = KConfigGroup(&appletConfig, "Applets");
} else if (c) {
if (c) {
// applet directly in a Containment, as usual
appletConfig = c->config();
appletConfig = KConfigGroup(&appletConfig, "Applets");

View File

@ -1,6 +1,7 @@
project(PlasmaQuick)
set(plasmaquick_LIB_SRC
appletquickitem.cpp
plasmaquickview.cpp
configmodel.cpp
configview.cpp
@ -36,6 +37,7 @@ generate_export_header(KF5PlasmaQuick BASE_NAME PlasmaQuick)
set(plasmaquick_LIB_INCLUDES
${CMAKE_CURRENT_BINARY_DIR}/plasmaquick_export.h
appletquickitem.h
plasmaquickview.h
configview.h
configmodel.h

View File

@ -0,0 +1,648 @@
/*
* Copyright 2014 Marco Martin <mart@kde.org>
*
* 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 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 "appletquickitem.h"
#include "private/appletquickitem_p.h"
#include <QQmlComponent>
#include <QQmlExpression>
#include <QQmlEngine>
#include <QQmlProperty>
#include <QQmlContext>
#include <QDebug>
#include <klocalizedstring.h>
#include <Plasma/Applet>
#include <Plasma/Containment>
#include <Plasma/Corona>
#include <kdeclarative/qmlobject.h>
#include <plasma/scripting/appletscript.h>
#include <packageurlinterceptor.h>
QHash<QObject *, AppletQuickItem *> AppletQuickItemPrivate::s_rootObjects = QHash<QObject *, AppletQuickItem *>();
AppletQuickItemPrivate::AppletQuickItemPrivate(Plasma::Applet *a, AppletQuickItem *item)
: q(item),
switchWidth(-1),
switchHeight(-1),
applet(a),
expanded(false)
{
}
void AppletQuickItemPrivate::connectLayoutAttached(QObject *item)
{
QObject *layout = 0;
//Extract the representation's Layout, if any
//No Item?
if (!item) {
return;
}
//Search a child that has the needed Layout properties
//HACK: here we are not type safe, but is the only way to access to a pointer of Layout
foreach (QObject *child, item->children()) {
//find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight
if (child->property("minimumWidth").isValid() && child->property("minimumHeight").isValid() &&
child->property("preferredWidth").isValid() && child->property("preferredHeight").isValid() &&
child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() &&
child->property("fillWidth").isValid() && child->property("fillHeight").isValid()
) {
layout = child;
}
}
if (!layout) {
return;
}
//propagate all the size hints
propagateSizeHint("minimumWidth");
propagateSizeHint("minimumHeight");
propagateSizeHint("preferredWidth");
propagateSizeHint("preferredHeight");
propagateSizeHint("maximumWidth");
propagateSizeHint("maximumHeight");
propagateSizeHint("fillWidth");
propagateSizeHint("fillHeight");
//HACK: check the Layout properties we wrote
QQmlProperty p(q, "Layout.minimumWidth", QtQml::qmlContext(qmlObject->rootObject()));
QObject *ownLayout = 0;
foreach (QObject *child, q->children()) {
//find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight
if (child->property("minimumWidth").isValid() && child->property("minimumHeight").isValid() &&
child->property("preferredWidth").isValid() && child->property("preferredHeight").isValid() &&
child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() &&
child->property("fillWidth").isValid() && child->property("fillHeight").isValid()
) {
ownLayout = child;
}
}
//this should never happen, since we ask to create it if doesn't exists
if (!ownLayout) {
return;
}
//if the representation didn't change, don't do anything
if (representationLayout.data() == layout) {
return;
}
if (representationLayout) {
QObject::disconnect(representationLayout.data(), 0, q, 0);
}
//Here we can't use the new connect syntax because we can't link against QtQuick layouts
QObject::connect(layout, SIGNAL(minimumWidthChanged()),
q, SLOT(minimumWidthChanged()));
QObject::connect(layout, SIGNAL(minimumHeightChanged()),
q, SLOT(minimumHeightChanged()));
QObject::connect(layout, SIGNAL(preferredWidthChanged()),
q, SLOT(preferredWidthChanged()));
QObject::connect(layout, SIGNAL(preferredHeightChanged()),
q, SLOT(preferredHeightChanged()));
QObject::connect(layout, SIGNAL(maximumWidthChanged()),
q, SLOT(maximumWidthChanged()));
QObject::connect(layout, SIGNAL(maximumHeightChanged()),
q, SLOT(maximumHeightChanged()));
QObject::connect(layout, SIGNAL(fillWidthChanged()),
q, SLOT(fillWidthChanged()));
QObject::connect(layout, SIGNAL(fillHeightChanged()),
q, SLOT(fillHeightChanged()));
representationLayout = layout;
AppletQuickItemPrivate::ownLayout = ownLayout;
propagateSizeHint("minimumWidth");
propagateSizeHint("minimumHeight");
propagateSizeHint("preferredWidth");
propagateSizeHint("preferredHeight");
propagateSizeHint("maximumWidth");
propagateSizeHint("maximumHeight");
propagateSizeHint("fillWidth");
propagateSizeHint("fillHeight");
}
void AppletQuickItemPrivate::propagateSizeHint(const QByteArray &layoutProperty)
{
if (ownLayout && representationLayout) {
ownLayout.data()->setProperty(layoutProperty, representationLayout.data()->property(layoutProperty));
}
}
QObject *AppletQuickItemPrivate::createCompactRepresentationItem()
{
if (!compactRepresentation) {
return 0;
}
if (compactRepresentationItem) {
return compactRepresentationItem.data();
}
compactRepresentationItem = qmlObject->createObjectFromComponent(compactRepresentation.data(), QtQml::qmlContext(qmlObject->rootObject()));
emit q->compactRepresentationItemChanged(compactRepresentationItem.data());
return compactRepresentationItem.data();
}
QObject *AppletQuickItemPrivate::createFullRepresentationItem()
{
if (fullRepresentationItem) {
return fullRepresentationItem.data();
}
if (fullRepresentation) {
fullRepresentationItem = qmlObject->createObjectFromComponent(fullRepresentation.data(), QtQml::qmlContext(qmlObject->rootObject()));
} else {
fullRepresentation = qmlObject->mainComponent();
fullRepresentationItem = qmlObject->rootObject();
emit q->fullRepresentationChanged(fullRepresentation.data());
}
QQuickItem *graphicsObj = qobject_cast<QQuickItem *>(fullRepresentationItem.data());
QObject::connect (graphicsObj, &QQuickItem::widthChanged, [=]() {
fullRepresentationResizeTimer.start();
});
QObject::connect (graphicsObj, &QQuickItem::heightChanged, [=]() {
fullRepresentationResizeTimer.start();
});
emit q->fullRepresentationItemChanged(fullRepresentationItem.data());
return fullRepresentationItem.data();
}
QObject *AppletQuickItemPrivate::createCompactRepresentationExpanderItem()
{
if (!compactRepresentationExpander) {
return 0;
}
if (compactRepresentationExpanderItem) {
return compactRepresentationExpanderItem.data();
}
compactRepresentationExpanderItem = qmlObject->createObjectFromComponent(compactRepresentationExpander.data(), QtQml::qmlContext(qmlObject->rootObject()));
compactRepresentationExpanderItem.data()->setProperty("compactRepresentation", QVariant::fromValue(createCompactRepresentationItem()));
compactRepresentationExpanderItem.data()->setProperty("fullRepresentation", QVariant::fromValue(createFullRepresentationItem()));
return compactRepresentationExpanderItem.data();
}
void AppletQuickItemPrivate::compactRepresentationCheck()
{
//ignore 0,0 sizes;
if (q->width() <= 0 && q->height() <= 0) {
return;
}
bool full = false;
if (applet->isContainment()) {
full = true;
} else {
if (switchWidth > 0 && switchHeight > 0) {
full = q->width() > switchWidth && q->height() > switchHeight;
//if a size to switch wasn't set, determine what representation to always chose
} else {
//preferred representation set?
if (preferredRepresentation) {
full = preferredRepresentation.data() == fullRepresentation.data();
//Otherwise, base on FormFactor
} else {
full = (applet->formFactor() != Plasma::Types::Horizontal && applet->formFactor() != Plasma::Types::Vertical);
}
}
if ((full && fullRepresentationItem && fullRepresentationItem.data() == currentRepresentationItem.data()) ||
(!full && compactRepresentationItem && compactRepresentationItem.data() == currentRepresentationItem.data())
) {
return;
}
}
//Expanded
if (full) {
QQuickItem *item = qobject_cast<QQuickItem *>(createFullRepresentationItem());
if (item) {
item->setParentItem(q);
{
//set anchors
QQmlExpression expr(QtQml::qmlContext(qmlObject->rootObject()), item, "parent");
QQmlProperty prop(item, "anchors.fill");
prop.write(expr.evaluate());
}
if (compactRepresentationItem) {
compactRepresentationItem.data()->setProperty("visible", false);
}
if (compactRepresentationExpanderItem) {
compactRepresentationExpanderItem.data()->setProperty("compactRepresentation", QVariant());
compactRepresentationExpanderItem.data()->setProperty("fullRepresentation", QVariant());
}
currentRepresentationItem = item;
connectLayoutAttached(item);
}
//Icon
} else {
QQuickItem *compactItem = qobject_cast<QQuickItem *>(createCompactRepresentationItem());
if (compactItem) {
//set the root item as the main visible item
compactItem->setParentItem(q);
compactItem->setVisible(true);
{
//set anchors
QQmlExpression expr(QtQml::qmlContext(qmlObject->rootObject()), compactItem, "parent");
QQmlProperty prop(compactItem, "anchors.fill");
prop.write(expr.evaluate());
}
if (fullRepresentationItem) {
fullRepresentationItem.data()->setProperty("parent", QVariant());
}
if (compactRepresentationExpanderItem) {
compactRepresentationExpanderItem.data()->setProperty("compactRepresentation", QVariant::fromValue(compactItem));
compactRepresentationExpanderItem.data()->setProperty("fullRepresentation", QVariant::fromValue(createFullRepresentationItem()));
}
currentRepresentationItem = compactItem;
connectLayoutAttached(compactItem);
}
}
}
void AppletQuickItemPrivate::minimumWidthChanged()
{
propagateSizeHint("minimumWidth");
}
void AppletQuickItemPrivate::minimumHeightChanged()
{
propagateSizeHint("minimumHeight");
}
void AppletQuickItemPrivate::preferredWidthChanged()
{
propagateSizeHint("preferredWidth");
}
void AppletQuickItemPrivate::preferredHeightChanged()
{
propagateSizeHint("preferredHeight");
}
void AppletQuickItemPrivate::maximumWidthChanged()
{
propagateSizeHint("maximumWidth");
}
void AppletQuickItemPrivate::maximumHeightChanged()
{
propagateSizeHint("maximumHeight");
}
void AppletQuickItemPrivate::fillWidthChanged()
{
propagateSizeHint("fillWidth");
}
void AppletQuickItemPrivate::fillHeightChanged()
{
propagateSizeHint("fillHeight");
}
AppletQuickItem::AppletQuickItem(Plasma::Applet *applet, QQuickItem *parent)
: QQuickItem(parent),
d(new AppletQuickItemPrivate(applet, this))
{
if (d->applet) {
d->appletPackage = d->applet->package();
}
if (d->applet && d->applet->containment() && d->applet->containment()->corona()) {
d->coronaPackage = d->applet->containment()->corona()->package();
}
d->compactRepresentationCheckTimer.setSingleShot(true);
d->compactRepresentationCheckTimer.setInterval(250);
connect (&d->compactRepresentationCheckTimer, SIGNAL(timeout()),
this, SLOT(compactRepresentationCheck()));
d->compactRepresentationCheckTimer.start();
d->fullRepresentationResizeTimer.setSingleShot(true);
d->fullRepresentationResizeTimer.setInterval(250);
connect (&d->fullRepresentationResizeTimer, &QTimer::timeout,
[=]() {
KConfigGroup cg = d->applet->config();
cg = KConfigGroup(&cg, "PopupApplet");
cg.writeEntry("DialogWidth", d->fullRepresentationItem.data()->property("width").toInt());
cg.writeEntry("DialogHeight", d->fullRepresentationItem.data()->property("height").toInt());
}
);
d->qmlObject = new KDeclarative::QmlObject(this);
d->qmlObject->setInitializationDelayed(true);
// set the graphicObject dynamic property on applet
d->applet->setProperty("_plasma_graphicObject", QVariant::fromValue(this));
setProperty("_plasma_applet", QVariant::fromValue(applet));
}
AppletQuickItem::~AppletQuickItem()
{
//Here the order is important
delete d->compactRepresentationItem.data();
delete d->fullRepresentationItem.data();
delete d->compactRepresentationExpanderItem.data();
AppletQuickItemPrivate::s_rootObjects.remove(d->qmlObject->engine());
}
AppletQuickItem *AppletQuickItem::qmlAttachedProperties(QObject *object)
{
//at the moment of the attached object creation, the root item is the only one that hasn't a parent
//only way to avoid creation of this attached for everybody but the root item
if (!object->parent() && AppletQuickItemPrivate::s_rootObjects.contains(QtQml::qmlEngine(object))) {
return AppletQuickItemPrivate::s_rootObjects.value(QtQml::qmlEngine(object));
} else {
return 0;
}
}
Plasma::Applet *AppletQuickItem::applet() const
{
return d->applet;
}
void AppletQuickItem::init()
{
if (AppletQuickItemPrivate::s_rootObjects.contains(this)) {
return;
}
AppletQuickItemPrivate::s_rootObjects[d->qmlObject->engine()] = this;
Q_ASSERT(d->applet);
//Initialize the main QML file
QQmlEngine *engine = d->qmlObject->engine();
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(engine, d->applet->package());
interceptor->addAllowedPath(d->coronaPackage.path());
engine->setUrlInterceptor(interceptor);
d->qmlObject->setSource(QUrl::fromLocalFile(d->applet->package().filePath("mainscript")));
if (!engine || !engine->rootContext() || !engine->rootContext()->isValid() || d->qmlObject->mainComponent()->isError()) {
QString reason;
foreach (QQmlError error, d->qmlObject->mainComponent()->errors()) {
reason += error.toString()+'\n';
}
reason = i18n("Error loading QML file: %1", reason);
d->qmlObject->setSource(QUrl::fromLocalFile(d->coronaPackage.filePath("appleterror")));
d->qmlObject->completeInitialization();
//even the error message QML may fail
if (d->qmlObject->mainComponent()->isError()) {
return;
} else {
d->qmlObject->rootObject()->setProperty("reason", reason);
}
d->applet->setLaunchErrorMessage(reason);
}
engine->rootContext()->setContextProperty("plasmoid", this);
//initialize size, so an useless resize less
QVariantHash initialProperties;
initialProperties["width"] = width();
initialProperties["height"] = height();
d->qmlObject->completeInitialization(initialProperties);
//default fullrepresentation is our root main component, if none specified
if (!d->fullRepresentation) {
d->fullRepresentation = d->qmlObject->mainComponent();
d->fullRepresentationItem = d->qmlObject->rootObject();
emit fullRepresentationChanged(d->fullRepresentation.data());
}
//default d->compactRepresentation is a simple icon provided by the shell package
if (!d->compactRepresentation) {
d->compactRepresentation = new QQmlComponent(engine, this);
d->compactRepresentation.data()->loadUrl(QUrl::fromLocalFile(d->coronaPackage.filePath("defaultcompactrepresentation")));
emit compactRepresentationChanged(d->compactRepresentation.data());
}
//default d->compactRepresentationExpander is the popup in which fullRepresentation goes
if (!d->compactRepresentationExpander) {
d->compactRepresentationExpander = new QQmlComponent(engine, this);
d->compactRepresentationExpander.data()->loadUrl(QUrl::fromLocalFile(d->coronaPackage.filePath("compactapplet")));
}
}
Plasma::Package AppletQuickItem::appletPackage() const
{
return d->appletPackage;
}
void AppletQuickItem::setAppletPackage(const Plasma::Package &package)
{
d->appletPackage = package;
}
Plasma::Package AppletQuickItem::coronaPackage() const
{
return d->coronaPackage;
}
void AppletQuickItem::setCoronaPackage(const Plasma::Package &package)
{
d->coronaPackage = package;
}
int AppletQuickItem::switchWidth() const
{
return d->switchWidth;
}
void AppletQuickItem::setSwitchWidth(int width)
{
if (d->switchWidth == width) {
return;
}
d->switchWidth = width;
emit switchWidthChanged(width);
}
int AppletQuickItem::switchHeight() const
{
return d->switchHeight;
}
void AppletQuickItem::setSwitchHeight(int width)
{
if (d->switchHeight == width) {
return;
}
d->switchHeight = width;
emit switchHeightChanged(width);
}
QQmlComponent *AppletQuickItem::compactRepresentation()
{
return d->compactRepresentation.data();
}
void AppletQuickItem::setCompactRepresentation(QQmlComponent *component)
{
if (d->compactRepresentation.data() == component) {
return;
}
d->compactRepresentation = component;
emit compactRepresentationChanged(component);
}
QQmlComponent *AppletQuickItem::fullRepresentation()
{
return d->fullRepresentation.data();
}
void AppletQuickItem::setFullRepresentation(QQmlComponent *component)
{
if (d->fullRepresentation.data() == component) {
return;
}
d->fullRepresentation = component;
emit fullRepresentationChanged(component);
}
QQmlComponent *AppletQuickItem::preferredRepresentation()
{
return d->preferredRepresentation.data();
}
void AppletQuickItem::setPreferredRepresentation(QQmlComponent *component)
{
if (d->preferredRepresentation.data() == component) {
return;
}
d->preferredRepresentation = component;
emit preferredRepresentationChanged(component);
}
bool AppletQuickItem::isExpanded() const
{
return d->expanded;
}
void AppletQuickItem::setExpanded(bool expanded)
{
if (d->applet->isContainment()) {
expanded = true;
}
//if there is no compact representation it means it's always expanded
//Containnments are always expanded
if (d->expanded == expanded) {
return;
}
d->createFullRepresentationItem();
d->createCompactRepresentationExpanderItem();
d->expanded = expanded;
emit expandedChanged(expanded);
}
////////////Internals
KDeclarative::QmlObject *AppletQuickItem::qmlObject()
{
return d->qmlObject;
}
QObject *AppletQuickItem::compactRepresentationItem()
{
return d->compactRepresentationItem.data();
}
QObject *AppletQuickItem::fullRepresentationItem()
{
return d->fullRepresentationItem.data();
}
void AppletQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_UNUSED(oldGeometry)
QQuickItem::geometryChanged(newGeometry, oldGeometry);
d->compactRepresentationCheckTimer.start();
}
void AppletQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == QQuickItem::ItemSceneChange) {
//we have a window: create the representations if needed
if (value.window) {
init();
}
}
QQuickItem::itemChange(change, value);
}
#include "moc_appletquickitem.cpp"

View File

@ -0,0 +1,151 @@
/*
* Copyright 2014 Marco Martin <mart@kde.org>
*
* 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 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.
*/
#ifndef APPLETQUICKITEM_H
#define APPLETQUICKITEM_H
#include <QQuickItem>
#include <QWeakPointer>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QTimer>
#include <Plasma/Package>
#include <plasmaquick/plasmaquick_export.h>
namespace Plasma {
class Applet;
}
namespace KDeclarative {
class QmlObject;
}
class AppletQuickItemPrivate;
class PLASMAQUICK_EXPORT AppletQuickItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(int switchWidth READ switchWidth WRITE setSwitchWidth NOTIFY switchWidthChanged)
Q_PROPERTY(int switchHeight READ switchHeight WRITE setSwitchHeight NOTIFY switchHeightChanged)
Q_PROPERTY(QQmlComponent *compactRepresentation READ compactRepresentation WRITE setCompactRepresentation NOTIFY compactRepresentationChanged)
Q_PROPERTY(QObject *compactRepresentationItem READ compactRepresentationItem NOTIFY compactRepresentationItemChanged)
Q_PROPERTY(QQmlComponent *fullRepresentation READ fullRepresentation WRITE setFullRepresentation NOTIFY fullRepresentationChanged)
Q_PROPERTY(QObject *fullRepresentationItem READ fullRepresentationItem NOTIFY fullRepresentationItemChanged)
/**
* this is supposed to be either one between compactRepresentation or fullRepresentation
*/
Q_PROPERTY(QQmlComponent *preferredRepresentation READ preferredRepresentation WRITE setPreferredRepresentation NOTIFY preferredRepresentationChanged)
/**
* True when the applet is showing its full representation. either as the main only view, or in a popup.
* Setting it will open or close the popup if the plasmoid is iconified, however it won't have effect if the applet is open
*/
Q_PROPERTY(bool expanded WRITE setExpanded READ isExpanded NOTIFY expandedChanged)
public:
AppletQuickItem(Plasma::Applet *applet, QQuickItem *parent = 0);
~AppletQuickItem();
////API NOT SUPPOSED TO BE USED BY QML
Plasma::Applet *applet() const;
//Make the constructor lighter and delay the actual instantiation of the qml in the applet
virtual void init();
Plasma::Package appletPackage() const;
void setAppletPackage(const Plasma::Package &package);
Plasma::Package coronaPackage() const;
void setCoronaPackage(const Plasma::Package &package);
QObject *compactRepresentationItem();
QObject *fullRepresentationItem();
////PROPERTY ACCESSORS
int switchWidth() const;
void setSwitchWidth(int width);
int switchHeight() const;
void setSwitchHeight(int width);
QQmlComponent *compactRepresentation();
void setCompactRepresentation(QQmlComponent *component);
QQmlComponent *fullRepresentation();
void setFullRepresentation(QQmlComponent *component);
QQmlComponent *preferredRepresentation();
void setPreferredRepresentation(QQmlComponent *component);
bool isExpanded() const;
void setExpanded(bool expanded);
////NEEDED BY QML TO CREATE ATTACHED PROPERTIES
static AppletQuickItem *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
//Property signals
void switchWidthChanged(int width);
void switchHeightChanged(int height);
void expandedChanged(bool expanded);
void compactRepresentationChanged(QQmlComponent *compactRepresentation);
void fullRepresentationChanged(QQmlComponent *fullRepresentation);
void preferredRepresentationChanged(QQmlComponent *preferredRepresentation);
void compactRepresentationItemChanged(QObject *compactRepresentationItem);
void fullRepresentationItemChanged(QObject *fullRepresentationItem);
protected:
KDeclarative::QmlObject *qmlObject();
//Reimplementation
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
virtual void itemChange(ItemChange change, const ItemChangeData &value);
private:
AppletQuickItemPrivate *const d;
Q_PRIVATE_SLOT(d, void compactRepresentationCheck())
Q_PRIVATE_SLOT(d, void minimumWidthChanged())
Q_PRIVATE_SLOT(d, void minimumHeightChanged())
Q_PRIVATE_SLOT(d, void preferredWidthChanged())
Q_PRIVATE_SLOT(d, void preferredHeightChanged())
Q_PRIVATE_SLOT(d, void maximumWidthChanged())
Q_PRIVATE_SLOT(d, void maximumHeightChanged())
Q_PRIVATE_SLOT(d, void fillWidthChanged())
Q_PRIVATE_SLOT(d, void fillHeightChanged())
};
QML_DECLARE_TYPEINFO(AppletQuickItem, QML_HAS_ATTACHED_PROPERTIES)
#endif

View File

@ -92,7 +92,7 @@ void ConfigViewPrivate::init()
delete object;
}
q->engine()->rootContext()->setContextProperty("plasmoid", applet->property("graphicObject").value<QObject*>());
q->engine()->rootContext()->setContextProperty("plasmoid", applet->property("_plasma_graphicObject").value<QObject*>());
q->engine()->rootContext()->setContextProperty("configDialog", q);
component->completeCreate();
delete component;

View File

@ -67,7 +67,7 @@ void PlasmaQuickViewPrivate::setContainment(Plasma::Containment *cont)
if (containment) {
QObject::disconnect(containment.data(), 0, q, 0);
QObject *oldGraphicObject = containment.data()->property("graphicObject").value<QObject *>();
QObject *oldGraphicObject = containment.data()->property("_plasma_graphicObject").value<QObject *>();
if (oldGraphicObject) {
qDebug() << "Old graphics Object:" << oldGraphicObject << "Old containment" << containment.data();
//make sure the graphic object won't die with us
@ -100,7 +100,7 @@ void PlasmaQuickViewPrivate::setContainment(Plasma::Containment *cont)
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(containment.data()->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(containment.data()->property("_plasma_graphicObject").value<QObject *>());
if (graphicObject) {

View File

@ -0,0 +1,93 @@
/*
* Copyright 2014 Marco Martin <mart@kde.org>
*
* 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 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.
*/
#ifndef APPLETQUICKITEM_P_H
#define APPLETQUICKITEM_P_H
#include <QQmlComponent>
namespace Plasma {
class Applet;
}
namespace KDeclarative {
class QmlObject;
}
class AppletQuickItem;
class AppletQuickItemPrivate
{
public:
AppletQuickItemPrivate(Plasma::Applet *a, AppletQuickItem *item);
QObject *createCompactRepresentationItem();
QObject *createFullRepresentationItem();
QObject *createCompactRepresentationExpanderItem();
//look into item, and return the Layout attached property, if found
void connectLayoutAttached(QObject *item);
void propagateSizeHint(const QByteArray &layoutProperty);
//handlers of Layout signals, private slots
void compactRepresentationCheck();
void minimumWidthChanged();
void minimumHeightChanged();
void preferredWidthChanged();
void preferredHeightChanged();
void maximumWidthChanged();
void maximumHeightChanged();
void fillWidthChanged();
void fillHeightChanged();
AppletQuickItem *q;
int switchWidth;
int switchHeight;
QWeakPointer<QQmlComponent> compactRepresentation;
QWeakPointer<QQmlComponent> fullRepresentation;
QWeakPointer<QQmlComponent> preferredRepresentation;
QWeakPointer<QQmlComponent> compactRepresentationExpander;
QWeakPointer<QObject> compactRepresentationItem;
QWeakPointer<QObject> fullRepresentationItem;
QWeakPointer<QObject> compactRepresentationExpanderItem;
QWeakPointer<QObject> currentRepresentationItem;
//Attached layout objects: own and the representation's one
QWeakPointer<QObject> representationLayout;
QWeakPointer<QObject> ownLayout;
QTimer compactRepresentationCheckTimer;
QTimer fullRepresentationResizeTimer;
Plasma::Applet *applet;
KDeclarative::QmlObject *qmlObject;
Plasma::Package appletPackage;
Plasma::Package coronaPackage;
bool expanded : 1;
static QHash<QObject *, AppletQuickItem *> s_rootObjects;
};
#endif

View File

@ -8,6 +8,8 @@ endif()
#DECLARATIVE APPLET
set(declarative_appletscript_SRCS
plasmoid/declarativeappletscript.cpp
plasmoid/appletinterface.cpp
plasmoid/containmentinterface.cpp
plasmoid/declarativeappletscript.cpp

View File

@ -48,20 +48,18 @@
#include <kdeclarative/configpropertymap.h>
#include <kdeclarative/qmlobject.h>
#include <packageurlinterceptor.h>
Q_DECLARE_METATYPE(AppletInterface*)
AppletInterface::AppletInterface(DeclarativeAppletScript *script, QQuickItem *parent)
: QQuickItem(parent),
m_appletScriptEngine(script),
: AppletQuickItem(script->applet(), parent),
m_actionSignals(0),
m_appletScriptEngine(script),
m_backgroundHints(Plasma::Types::StandardBackground),
m_busy(false),
m_expanded(false),
m_hideOnDeactivate(true)
{
qmlRegisterType<AppletInterface>();
qmlRegisterType<QAction>();
connect(this, &AppletInterface::configNeedsSaving,
@ -74,80 +72,39 @@ AppletInterface::AppletInterface(DeclarativeAppletScript *script, QQuickItem *pa
connect(applet(), &Plasma::Applet::statusChanged,
this, &AppletInterface::statusChanged);
connect(m_appletScriptEngine, &DeclarativeAppletScript::formFactorChanged,
connect(appletScript(), &DeclarativeAppletScript::formFactorChanged,
this, &AppletInterface::formFactorChanged);
connect(m_appletScriptEngine, &DeclarativeAppletScript::locationChanged,
connect(appletScript(), &DeclarativeAppletScript::locationChanged,
this, &AppletInterface::locationChanged);
connect(m_appletScriptEngine, &DeclarativeAppletScript::contextChanged,
connect(appletScript(), &DeclarativeAppletScript::contextChanged,
this, &AppletInterface::contextChanged);
if (applet()->containment()) {
connect(applet()->containment(), &Plasma::Containment::screenChanged,
this, &ContainmentInterface::screenChanged);
}
m_qmlObject = new KDeclarative::QmlObject(this);
m_qmlObject->setInitializationDelayed(true);
m_collapseTimer = new QTimer(this);
m_collapseTimer->setSingleShot(true);
connect(m_collapseTimer, &QTimer::timeout, this, &AppletInterface::compactRepresentationCheck);
}
AppletInterface::~AppletInterface()
{
}
DeclarativeAppletScript *AppletInterface::appletScript() const
{
return m_appletScriptEngine;
}
void AppletInterface::init()
{
if (m_qmlObject->rootObject()) {
if (qmlObject()->rootObject() && m_configuration) {
return;
}
m_configuration = new KDeclarative::ConfigPropertyMap(applet()->configScheme(), this);
//use our own custom network access manager that will access Plasma packages and to manage security (i.e. deny access to remote stuff when the proper extension isn't enabled
QQmlEngine *engine = m_qmlObject->engine();
AppletQuickItem::init();
//Hook generic url resolution to the applet package as well
//TODO: same thing will have to be done for every qqmlengine: PackageUrlInterceptor is material for plasmaquick?
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(engine, m_appletScriptEngine->package());
interceptor->addAllowedPath(applet()->containment()->corona()->package().path());
engine->setUrlInterceptor(interceptor);
m_qmlObject->setSource(QUrl::fromLocalFile(m_appletScriptEngine->mainScript()));
if (!m_qmlObject->engine() || !m_qmlObject->engine()->rootContext() || !m_qmlObject->engine()->rootContext()->isValid() || m_qmlObject->mainComponent()->isError()) {
QString reason;
foreach (QQmlError error, m_qmlObject->mainComponent()->errors()) {
reason += error.toString()+'\n';
}
reason = i18n("Error loading QML file: %1", reason);
m_qmlObject->setSource(QUrl::fromLocalFile(applet()->containment()->corona()->package().filePath("appleterror")));
m_qmlObject->completeInitialization();
//even the error message QML may fail
if (m_qmlObject->mainComponent()->isError()) {
return;
} else {
m_qmlObject->rootObject()->setProperty("reason", reason);
}
m_appletScriptEngine->setLaunchErrorMessage(reason);
}
m_qmlObject->engine()->rootContext()->setContextProperty("plasmoid", this);
//initialize size, so an useless resize less
QVariantHash initialProperties;
initialProperties["width"] = width();
initialProperties["height"] = height();
m_qmlObject->completeInitialization(initialProperties);
qDebug() << "Graphic object created:" << applet() << applet()->property("graphicObject");
qDebug() << "Graphic object created:" << applet() << this;
geometryChanged(QRectF(), QRectF(x(), y(), width(), height()));
emit busyChanged();
@ -167,7 +124,11 @@ Plasma::Types::Location AppletInterface::location() const
QString AppletInterface::currentActivity() const
{
return applet()->containment()->activity();
if (applet()->containment()) {
return applet()->containment()->activity();
} else {
return QString();
}
}
QObject* AppletInterface::configuration() const
@ -212,7 +173,7 @@ void AppletInterface::setTitle(const QString &title)
bool AppletInterface::isBusy() const
{
return !m_qmlObject->rootObject() || m_busy;
return m_busy;
}
void AppletInterface::setBusy(bool busy)
@ -225,23 +186,6 @@ void AppletInterface::setBusy(bool busy)
emit busyChanged();
}
bool AppletInterface::isExpanded() const
{
return m_expanded;
}
void AppletInterface::setExpanded(bool expanded)
{
//if there is no compact representation it means it's always expanded
//Containnments are always expanded
if (!m_compactUiObject || qobject_cast<ContainmentInterface *>(this) || m_expanded == expanded) {
return;
}
m_expanded = expanded;
emit expandedChanged();
}
Plasma::Types::BackgroundHints AppletInterface::backgroundHints() const
{
return m_backgroundHints;
@ -259,7 +203,7 @@ void AppletInterface::setBackgroundHints(Plasma::Types::BackgroundHints hint)
void AppletInterface::setConfigurationRequired(bool needsConfiguring, const QString &reason)
{
m_appletScriptEngine->setConfigurationRequired(needsConfiguring, reason);
appletScript()->setConfigurationRequired(needsConfiguring, reason);
}
QString AppletInterface::activeConfig() const
@ -277,7 +221,7 @@ void AppletInterface::setActiveConfig(const QString &name)
Plasma::ConfigLoader *loader = m_configs.value(name, 0);
if (!loader) {
QString path = m_appletScriptEngine->filePath("config", name + ".xml");
QString path = appletScript()->filePath("config", name + ".xml");
if (path.isEmpty()) {
return;
}
@ -307,7 +251,7 @@ void AppletInterface::writeConfig(const QString &entry, const QVariant &value)
config->blockSignals(true);
config->writeConfig();
config->blockSignals(false);
m_appletScriptEngine->configNeedsSaving();
appletScript()->configNeedsSaving();
}
} else
qWarning() << "Couldn't find a configuration entry";
@ -333,12 +277,12 @@ QVariant AppletInterface::readConfig(const QString &entry) const
QString AppletInterface::file(const QString &fileType)
{
return m_appletScriptEngine->filePath(fileType, QString());
return appletScript()->filePath(fileType, QString());
}
QString AppletInterface::file(const QString &fileType, const QString &filePath)
{
return m_appletScriptEngine->filePath(fileType, filePath);
return appletScript()->filePath(fileType, filePath);
}
QList<QAction*> AppletInterface::contextualActions() const
@ -392,7 +336,7 @@ void AppletInterface::setAction(const QString &name, const QString &text, const
if (!m_actionSignals) {
m_actionSignals = new QSignalMapper(this);
connect(m_actionSignals, SIGNAL(mapped(QString)),
m_appletScriptEngine, SLOT(executeAction(QString)));
appletScript(), SLOT(executeAction(QString)));
}
connect(action, SIGNAL(triggered()), m_actionSignals, SLOT(map()));
@ -452,92 +396,6 @@ int AppletInterface::apiVersion() const
return offers.first()->property("X-KDE-PluginInfo-Version", QVariant::Int).toInt();
}
bool AppletInterface::fillWidth() const
{
if (!m_qmlObject->rootObject()) {
return false;
}
QVariant prop;
if (m_compactUiObject) {
prop = m_compactUiObject.data()->property("fillWidth");
} else {
prop = m_qmlObject->rootObject()->property("fillWidth");
}
if (prop.isValid() && prop.canConvert<bool>()) {
return prop.toBool();
} else {
return false;
}
}
bool AppletInterface::fillHeight() const
{
if (!m_qmlObject->rootObject()) {
return false;
}
QVariant prop;
if (m_compactUiObject) {
prop = m_compactUiObject.data()->property("fillHeight");
} else {
prop = m_qmlObject->rootObject()->property("fillHeight");
}
if (prop.isValid() && prop.canConvert<bool>()) {
return prop.toBool();
} else {
return false;
}
}
//private api, just an helper
qreal AppletInterface::readGraphicsObjectSizeHint(const char *hint) const
{
if (!m_qmlObject->rootObject()) {
return -1;
}
QVariant prop;
if (m_compactUiObject) {
prop = m_compactUiObject.data()->property(hint);
} else {
prop = m_qmlObject->rootObject()->property(hint);
}
if (prop.isValid() && prop.canConvert<qreal>()) {
return prop.toReal();
} else {
return -1;
}
}
qreal AppletInterface::minimumWidth() const
{
return readGraphicsObjectSizeHint("minimumWidth");
}
qreal AppletInterface::minimumHeight() const
{
return readGraphicsObjectSizeHint("minimumHeight");
}
qreal AppletInterface::maximumWidth() const
{
return readGraphicsObjectSizeHint("maximumWidth");
}
qreal AppletInterface::maximumHeight() const
{
return readGraphicsObjectSizeHint("maximumHeight");
}
void AppletInterface::setAssociatedApplication(const QString &string)
{
@ -601,245 +459,11 @@ QStringList AppletInterface::downloadedFiles() const
return dir.entryList(QDir::Files | QDir::NoSymLinks | QDir::Readable);
}
void AppletInterface::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
void AppletInterface::executeAction(const QString &name)
{
Q_UNUSED(oldGeometry)
QQuickItem::geometryChanged(newGeometry, oldGeometry);
m_collapseTimer->start(100);
}
void AppletInterface::compactRepresentationCheck()
{
if (width() <= 0 || height() <= 0 || !m_qmlObject->rootObject() ||
qobject_cast<ContainmentInterface *>(this)) {
return;
if (qmlObject()->rootObject()) {
QMetaObject::invokeMethod(qmlObject()->rootObject(), QString("action_" + name).toLatin1(), Qt::DirectConnection);
}
//Read the minimum width of the full representation, not our own, since we could be in collapsed mode
QSizeF minHint(-1, -1);
if (m_qmlObject->rootObject()->property("minimumWidth").canConvert<qreal>()) {
minHint.setWidth(m_qmlObject->rootObject()->property("minimumWidth").toReal());
}
if (m_qmlObject->rootObject()->property("minimumHeight").canConvert<qreal>()) {
minHint.setHeight(m_qmlObject->rootObject()->property("minimumHeight").toReal());
}
//Make it an icon
if (width() < minHint.width() || height() < minHint.height()) {
m_expanded = false;
//we are already an icon: nothing to do
if (m_compactUiObject) {
return;
}
m_compactUiObject = m_qmlObject->createObjectFromSource(QUrl::fromLocalFile(applet()->containment()->corona()->package().filePath("compactapplet")));
QObject *compactRepresentation = 0;
//build the icon representation
if (m_compactUiObject) {
QQmlComponent *compactComponent = m_qmlObject->rootObject()->property("compactRepresentation").value<QQmlComponent *>();
if (compactComponent) {
compactRepresentation = compactComponent->create(compactComponent->creationContext());
} else {
compactRepresentation = m_qmlObject->createObjectFromSource(QUrl::fromLocalFile(applet()->containment()->corona()->package().filePath("defaultcompactrepresentation")));
}
if (compactRepresentation && compactComponent) {
compactComponent->setParent(compactRepresentation);
} else {
delete compactComponent;
}
}
if (m_compactUiObject && compactRepresentation) {
//put compactRepresentation in the icon place
compactRepresentation->setProperty("parent", QVariant::fromValue(m_compactUiObject.data()));
m_compactUiObject.data()->setProperty("compactRepresentation", QVariant::fromValue(compactRepresentation));
//replace the full applet with the collapsed view
m_compactUiObject.data()->setProperty("visible", true);
m_compactUiObject.data()->setProperty("parent", QVariant::fromValue(this));
{
//set anchors
QQmlExpression expr(m_qmlObject->engine()->rootContext(), m_compactUiObject.data(), "parent");
QQmlProperty prop(m_compactUiObject.data(), "anchors.fill");
prop.write(expr.evaluate());
}
m_qmlObject->rootObject()->setProperty("parent", QVariant::fromValue(m_compactUiObject.data()));
{
//reset all the anchors
QQmlExpression expr(m_qmlObject->engine()->rootContext(), m_qmlObject->rootObject(), "anchors.fill=undefined;anchors.left=undefined;anchors.right=undefined;anchors.top=undefined;anchors.bottom=undefined;");
expr.evaluate();
}
KConfigGroup cg = applet()->config();
cg = KConfigGroup(&cg, "PopupApplet");
int width = cg.readEntry("DialogWidth", 0);
int height = cg.readEntry("DialogHeight", 0);
m_qmlObject->rootObject()->setProperty("width", width);
m_qmlObject->rootObject()->setProperty("height", height);
m_compactUiObject.data()->setProperty("applet", QVariant::fromValue(m_qmlObject->rootObject()));
//hook m_compactUiObject size hints to this size hint
//Here we have to use the old connect syntax, because we don't have access to the class type
if (m_qmlObject->rootObject()) {
disconnect(m_qmlObject->rootObject(), 0, this, 0);
}
//resize of the root object means popup resize when iconified
connect(m_qmlObject->rootObject(), SIGNAL(widthChanged()),
this, SLOT(updatePopupSize()));
connect(m_qmlObject->rootObject(), SIGNAL(heightChanged()),
this, SLOT(updatePopupSize()));
if (m_compactUiObject.data()->property("minimumWidth").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(minimumWidthChanged()),
this, SIGNAL(minimumWidthChanged()));
}
if (m_compactUiObject.data()->property("minimumHeight").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(minimumHeightChanged()),
this, SIGNAL(minimumHeightChanged()));
}
if (m_compactUiObject.data()->property("maximumWidth").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(maximumWidthChanged()),
this, SIGNAL(maximumWidthChanged()));
}
if (m_compactUiObject.data()->property("maximumHeight").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(maximumHeightChanged()),
this, SIGNAL(maximumHeightChanged()));
}
if (m_compactUiObject.data()->property("implicitWidth").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(implicitWidthChanged()),
this, SIGNAL(implicitWidthChanged()));
}
if (m_compactUiObject.data()->property("implicitHeight").isValid()) {
connect(m_compactUiObject.data(), SIGNAL(implicitHeightChanged()),
this, SIGNAL(implicitHeightChanged()));
}
emit fillWidthChanged();
emit fillHeightChanged();
emit minimumWidthChanged();
emit minimumHeightChanged();
emit implicitWidthChanged();
emit implicitHeightChanged();
emit maximumWidthChanged();
emit maximumHeightChanged();
//failed to create UI, don't do anything, return in expanded status
} else {
m_expanded = true;
}
emit expandedChanged();
//show the full UI
} else {
m_expanded = true;
emit expandedChanged();
//we are already expanded: nothing to do
if (m_compactUiObject) {
disconnect(m_compactUiObject.data(), 0, this, 0);
}
disconnect(m_qmlObject->rootObject(), SIGNAL(widthChanged()),
this, SLOT(updatePopupSize()));
disconnect(m_qmlObject->rootObject(), SIGNAL(heightChanged()),
this, SLOT(updatePopupSize()));
//Here we have to use the old connect syntax, because we don't have access to the class type
if (m_qmlObject->rootObject()->property("minimumWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(minimumWidthChanged()),
this, SIGNAL(minimumWidthChanged()));
}
if (m_qmlObject->rootObject()->property("minimumHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(minimumHeightChanged()),
this, SIGNAL(minimumHeightChanged()));
}
if (m_qmlObject->rootObject()->property("maximumWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(maximumWidthChanged()),
this, SIGNAL(maximumWidthChanged()));
}
if (m_qmlObject->rootObject()->property("maximumHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(maximumHeightChanged()),
this, SIGNAL(maximumHeightChanged()));
}
if (m_qmlObject->rootObject()->property("implicitWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(implicitWidthChanged()),
this, SLOT(updateImplicitWidth()));
}
if (m_qmlObject->rootObject()->property("implicitHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(implicitHeightChanged()),
this, SLOT(updateImplicitHeight()));
}
emit fillWidthChanged();
emit fillHeightChanged();
emit minimumWidthChanged();
emit minimumHeightChanged();
emit maximumWidthChanged();
emit maximumHeightChanged();
m_qmlObject->rootObject()->setProperty("parent", QVariant::fromValue(this));
if (m_compactUiObject) {
m_compactUiObject.data()->deleteLater();
}
//set anchors
QQmlExpression expr(m_qmlObject->engine()->rootContext(), m_qmlObject->rootObject(), "parent");
QQmlProperty prop(m_qmlObject->rootObject(), "anchors.fill");
prop.write(expr.evaluate());
}
}
void AppletInterface::updateImplicitWidth()
{
setImplicitWidth(readGraphicsObjectSizeHint("implicitWidth"));
}
void AppletInterface::updateImplicitHeight()
{
setImplicitHeight(readGraphicsObjectSizeHint("implicitHeight"));
}
void AppletInterface::updatePopupSize()
{
KConfigGroup cg = applet()->config();
cg = KConfigGroup(&cg, "PopupApplet");
cg.writeEntry("DialogWidth", m_qmlObject->rootObject()->property("width").toInt());
cg.writeEntry("DialogHeight", m_qmlObject->rootObject()->property("height").toInt());
}
void AppletInterface::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == QQuickItem::ItemSceneChange) {
//we have a window: create the
if (value.window && !m_qmlObject->rootObject()) {
init();
}
}
QQuickItem::itemChange(change, value);
}
KDeclarative::QmlObject *AppletInterface::qmlObject()
{
return m_qmlObject;
}
#include "moc_appletinterface.cpp"

View File

@ -29,6 +29,7 @@
#include <Plasma/Applet>
#include <Plasma/Theme>
#include <appletquickitem.h>
#include "declarativeappletscript.h"
class QAction;
@ -48,7 +49,7 @@ namespace Plasma
class ConfigLoader;
} // namespace Plasma
class AppletInterface : public QQuickItem
class AppletInterface : public AppletQuickItem
{
Q_OBJECT
@ -107,12 +108,6 @@ class AppletInterface : public QQuickItem
*/
Q_PROPERTY(bool busy WRITE setBusy READ isBusy NOTIFY busyChanged)
/**
* True when the applet is showing its full representation. either as the main only view, or in a popup.
* Setting it will open or close the popup if the plasmoid is iconified, however it won't have effect if the applet is open
*/
Q_PROPERTY(bool expanded WRITE setExpanded READ isExpanded NOTIFY expandedChanged)
/**
* How the applet wants its background to be drawn. The containment may chose to ignore this hint.
*/
@ -145,22 +140,6 @@ class AppletInterface : public QQuickItem
// would be preferrable if found.
Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
//Size hints. Note that the containments may chose to not respect them.
Q_PROPERTY(qreal minimumWidth READ minimumWidth NOTIFY minimumWidthChanged)
Q_PROPERTY(qreal minimumHeight READ minimumHeight NOTIFY minimumHeightChanged)
Q_PROPERTY(qreal maximumWidth READ maximumWidth NOTIFY maximumWidthChanged)
Q_PROPERTY(qreal maximumHeight READ maximumHeight NOTIFY maximumHeightChanged)
/**
* If the plasmoid is in a linear layout, such as a panel, it indicates to take as much horizontal space as possible
*/
Q_PROPERTY(bool fillWidth READ fillWidth NOTIFY fillWidthChanged)
/**
* If the plasmoid is in a linear layout, such as a panel, it indicates to take as much vertical space as possible
*/
Q_PROPERTY(bool fillHeight READ fillHeight NOTIFY fillHeightChanged)
/**
* Whether the dialog should be hidden when the dialog loses focus.
*
@ -174,11 +153,12 @@ public:
~AppletInterface();
//API not intended for the QML part
KDeclarative::QmlObject *qmlObject();
DeclarativeAppletScript *appletScript() const;
QList<QAction*> contextualActions() const;
inline Plasma::Applet *applet() const { return m_appletScriptEngine->applet(); }
void executeAction(const QString &name);
//QML API-------------------------------------------------------------------
@ -237,7 +217,11 @@ public:
* DEPRECATED: use plasmoid.configuration instead
*/
Q_INVOKABLE void writeConfig(const QString &entry, const QVariant &value);
static AppletInterface *qmlAttachedProperties(QObject *object)
{
return qobject_cast<AppletInterface *>(AppletQuickItem::qmlAttachedProperties(object));
}
//PROPERTY ACCESSORS-------------------------------------------------------------------
QString icon() const;
@ -259,9 +243,6 @@ public:
bool isBusy() const;
void setBusy(bool busy);
bool isExpanded() const;
void setExpanded(bool expanded);
Plasma::Types::BackgroundHints backgroundHints() const;
void setBackgroundHints(Plasma::Types::BackgroundHints hint);
@ -283,13 +264,6 @@ public:
bool hideOnWindowDeactivate() const;
void setHideOnWindowDeactivate(bool hide);
bool fillWidth() const;
bool fillHeight() const;
qreal minimumWidth() const;
qreal minimumHeight() const;
qreal maximumWidth() const;
qreal maximumHeight() const;
Q_SIGNALS:
/**
* somebody else, usually the containment sent some data to the applet
@ -311,36 +285,15 @@ Q_SIGNALS:
void statusChanged();
void backgroundHintsChanged();
void busyChanged();
void expandedChanged();
void screenChanged();
void hideOnWindowDeactivateChanged();
void minimumWidthChanged();
void minimumHeightChanged();
void maximumWidthChanged();
void maximumHeightChanged();
void fillWidthChanged();
void fillHeightChanged();
void userConfiguringChanged();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
void itemChange(ItemChange change, const ItemChangeData &value);
DeclarativeAppletScript *m_appletScriptEngine;
protected Q_SLOTS:
virtual void init();
private Q_SLOTS:
void compactRepresentationCheck();
void updatePopupSize();
void updateImplicitWidth();
void updateImplicitHeight();
private:
//Helper for minimumWidth etc.
qreal readGraphicsObjectSizeHint(const char *hint) const;
QStringList m_actions;
QSignalMapper *m_actionSignals;
@ -349,18 +302,17 @@ private:
KDeclarative::ConfigPropertyMap *m_configuration;
DeclarativeAppletScript *m_appletScriptEngine;
//UI-specific members ------------------
KDeclarative::QmlObject *m_qmlObject;
QWeakPointer<QObject> m_compactUiObject;
QTimer *m_collapseTimer;
Plasma::Types::BackgroundHints m_backgroundHints;
bool m_busy : 1;
bool m_expanded : 1;
bool m_hideOnDeactivate : 1;
friend class ContainmentInterface;
};
QML_DECLARE_TYPEINFO(AppletInterface, QML_HAS_ATTACHED_PROPERTIES)
#endif

View File

@ -59,8 +59,6 @@ ContainmentInterface::ContainmentInterface(DeclarativeAppletScript *parent)
{
setAcceptedMouseButtons(Qt::AllButtons);
qmlRegisterType<ContainmentInterface>();
connect(containment(), &Plasma::Containment::appletRemoved,
this, &ContainmentInterface::appletRemovedForward);
connect(containment(), &Plasma::Containment::appletAdded,
@ -117,15 +115,15 @@ void ContainmentInterface::init()
pkg.setPath("org.kde.desktoptoolbox");
}
PackageUrlInterceptor *interceptor = dynamic_cast<PackageUrlInterceptor *>(m_qmlObject->engine()->urlInterceptor());
PackageUrlInterceptor *interceptor = dynamic_cast<PackageUrlInterceptor *>(qmlObject()->engine()->urlInterceptor());
if (interceptor) {
interceptor->addAllowedPath(pkg.path());
}
if (pkg.isValid()) {
QObject *toolBoxObject = m_qmlObject->createObjectFromSource(QUrl::fromLocalFile(pkg.filePath("mainscript")));
QObject *toolBoxObject = qmlObject()->createObjectFromSource(QUrl::fromLocalFile(pkg.filePath("mainscript")));
QObject *containmentGraphicObject = m_qmlObject->rootObject();
QObject *containmentGraphicObject = qmlObject()->rootObject();
if (containmentGraphicObject && toolBoxObject) {
toolBoxObject->setProperty("parent", QVariant::fromValue(containmentGraphicObject));
@ -142,50 +140,14 @@ void ContainmentInterface::init()
//set parent, both as object hyerarchy and visually
//do this only for containments, applets will do it in compactrepresentationcheck
if (m_qmlObject->rootObject()) {
m_qmlObject->rootObject()->setProperty("parent", QVariant::fromValue(this));
if (qmlObject()->rootObject()) {
qmlObject()->rootObject()->setProperty("parent", QVariant::fromValue(this));
//set anchors
QQmlExpression expr(m_qmlObject->engine()->rootContext(), m_qmlObject->rootObject(), "parent");
QQmlProperty prop(m_qmlObject->rootObject(), "anchors.fill");
QQmlExpression expr(qmlObject()->engine()->rootContext(), qmlObject()->rootObject(), "parent");
QQmlProperty prop(qmlObject()->rootObject(), "anchors.fill");
prop.write(expr.evaluate());
}
if (m_qmlObject->rootObject()->property("minimumWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(minimumWidthChanged()),
this, SIGNAL(minimumWidthChanged()));
}
if (m_qmlObject->rootObject()->property("minimumHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(minimumHeightChanged()),
this, SIGNAL(minimumHeightChanged()));
}
if (m_qmlObject->rootObject()->property("maximumWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(maximumWidthChanged()),
this, SIGNAL(maximumWidthChanged()));
}
if (m_qmlObject->rootObject()->property("maximumHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(maximumHeightChanged()),
this, SIGNAL(maximumHeightChanged()));
}
if (m_qmlObject->rootObject()->property("implicitWidth").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(implicitWidthChanged()),
this, SIGNAL(implicitWidthChanged()));
}
if (m_qmlObject->rootObject()->property("implicitHeight").isValid()) {
connect(m_qmlObject->rootObject(), SIGNAL(implicitHeightChanged()),
this, SIGNAL(implicitHeightChanged()));
}
emit fillWidthChanged();
emit fillHeightChanged();
emit minimumWidthChanged();
emit minimumHeightChanged();
emit implicitWidthChanged();
emit implicitHeightChanged();
emit maximumWidthChanged();
emit maximumHeightChanged();
}
QList <QObject *> ContainmentInterface::applets()
@ -195,12 +157,12 @@ QList <QObject *> ContainmentInterface::applets()
Plasma::Types::ContainmentType ContainmentInterface::containmentType() const
{
return m_appletScriptEngine->containmentType();
return appletScript()->containmentType();
}
void ContainmentInterface::setContainmentType(Plasma::Types::ContainmentType type)
{
m_appletScriptEngine->setContainmentType(type);
appletScript()->setContainmentType(type);
}
void ContainmentInterface::lockWidgets(bool locked)
@ -242,7 +204,7 @@ Plasma::Applet *ContainmentInterface::addApplet(const QString &plugin, const QVa
if (applet) {
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
QObject *appletGraphicObject = applet->property("_plasma_graphicObject").value<QObject *>();
blockSignals(false);
@ -259,7 +221,7 @@ void ContainmentInterface::setAppletArgs(Plasma::Applet *applet, const QString &
return;
}
AppletInterface *appletInterface = applet->property("graphicObject").value<AppletInterface *>();
AppletInterface *appletInterface = applet->property("_plasma_graphicObject").value<AppletInterface *>();
if (appletInterface) {
emit appletInterface->externalData(mimetype, data);
}
@ -526,8 +488,8 @@ void ContainmentInterface::appletAddedForward(Plasma::Applet *applet)
return;
}
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
QObject *contGraphicObject = containment()->property("graphicObject").value<QObject *>();
QObject *appletGraphicObject = applet->property("_plasma_graphicObject").value<QObject *>();
QObject *contGraphicObject = containment()->property("_plasma_graphicObject").value<QObject *>();
qDebug() << "Applet added on containment:" << containment()->title() << contGraphicObject
<< "Applet: " << applet << applet->title() << appletGraphicObject;
@ -555,7 +517,7 @@ void ContainmentInterface::appletAddedForward(Plasma::Applet *applet)
void ContainmentInterface::appletRemovedForward(Plasma::Applet *applet)
{
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
QObject *appletGraphicObject = applet->property("_plasma_graphicObject").value<QObject *>();
m_appletInterfaces.removeAll(appletGraphicObject);
emit appletRemoved(appletGraphicObject);
emit appletsChanged();

View File

@ -70,7 +70,7 @@ class ContainmentInterface : public AppletInterface
public:
ContainmentInterface(DeclarativeAppletScript *parent);
//Not for QML
inline Plasma::Containment *containment() const { return static_cast<Plasma::Containment *>(m_appletScriptEngine->applet()->containment()); }
Plasma::Containment *containment() const { return static_cast<Plasma::Containment *>(appletScript()->applet()->containment()); }
inline WallpaperInterface *wallpaperInterface() const { return m_wallpaperInterface;}
@ -105,6 +105,11 @@ public:
*/
Q_INVOKABLE void processMimeData(QMimeData *data, int x, int y);
static ContainmentInterface *qmlAttachedProperties(QObject *object)
{
return qobject_cast<ContainmentInterface *>(AppletQuickItem::qmlAttachedProperties(object));
}
protected:
void init();
void mousePressEvent(QMouseEvent *event);
@ -159,4 +164,6 @@ private:
KActivities::Info *m_activityInfo;
};
QML_DECLARE_TYPEINFO(ContainmentInterface, QML_HAS_ATTACHED_PROPERTIES)
#endif

View File

@ -42,6 +42,7 @@
#include "plasmoid/appletinterface.h"
#include "plasmoid/containmentinterface.h"
#include "plasmoid/wallpaperinterface.h"
#include <kdeclarative/qmlobject.h>
#include <kdeclarative/configpropertymap.h>
@ -54,7 +55,18 @@ DeclarativeAppletScript::DeclarativeAppletScript(QObject *parent, const QVariant
: Plasma::AppletScript(parent),
m_interface(0)
{
qmlRegisterType<AppletInterface>();
//qmlRegisterType<AppletInterface>();
//FIXME: use this if/when will be possible to have properties of attached items subclasses on the left hand of expressions
/*qmlRegisterUncreatableType<AppletLoader>("org.kde.plasma.plasmoid", 2, 0, "Plasmoid",
QLatin1String("Do not create objects of type Plasmoid"));*/
qmlRegisterUncreatableType<AppletInterface>("org.kde.plasma.plasmoid", 2, 0, "Plasmoid",
QLatin1String("Do not create objects of type Plasmoid"));
qmlRegisterUncreatableType<ContainmentInterface>("org.kde.plasma.plasmoid", 2, 0, "Containment",
QLatin1String("Do not create objects of type Containment"));
qmlRegisterUncreatableType<WallpaperInterface>("org.kde.plasma.plasmoid", 2, 0, "Wallpaper",
QLatin1String("Do not create objects of type Wallpaper"));
qmlRegisterType<KDeclarative::ConfigPropertyMap>();
Q_UNUSED(args);
}
@ -81,8 +93,6 @@ bool DeclarativeAppletScript::init()
}
m_interface->setParent(this);
// set the graphicObject dynamic property on applet
a->setProperty("graphicObject", QVariant::fromValue(m_interface));
return true;
}
@ -109,9 +119,7 @@ void DeclarativeAppletScript::constraintsEvent(Plasma::Types::Constraints constr
void DeclarativeAppletScript::executeAction(const QString &name)
{
if (m_interface->qmlObject()->rootObject()) {
QMetaObject::invokeMethod(m_interface->qmlObject()->rootObject(), QString("action_" + name).toLatin1(), Qt::DirectConnection);
}
m_interface->executeAction(name);
}
QList<QAction*> DeclarativeAppletScript::contextualActions()

View File

@ -56,6 +56,7 @@ Q_SIGNALS:
private:
AppletInterface *m_interface;
friend class AppletLoader;
friend class AppletInterface;
friend class ContainmentInterface;
};

View File

@ -36,6 +36,8 @@
#include <Plasma/ConfigLoader>
#include <Plasma/PluginLoader>
QHash<QObject *, WallpaperInterface *> WallpaperInterface::s_rootObjects = QHash<QObject *, WallpaperInterface *>();
WallpaperInterface::WallpaperInterface(ContainmentInterface *parent)
: QQuickItem(parent),
m_containmentInterface(parent),
@ -55,7 +57,9 @@ WallpaperInterface::WallpaperInterface(ContainmentInterface *parent)
}
WallpaperInterface::~WallpaperInterface()
{}
{
s_rootObjects.remove(m_qmlObject->engine());
}
KPluginInfo::List WallpaperInterface::listWallpaperInfoForMimetype(const QString &mimetype, const QString &formFactor)
{
@ -109,6 +113,7 @@ void WallpaperInterface::syncWallpaperPackage()
if (!m_qmlObject) {
m_qmlObject = new KDeclarative::QmlObject(this);
s_rootObjects[m_qmlObject->engine()] = this;
m_qmlObject->setInitializationDelayed(true);
}
@ -142,6 +147,7 @@ void WallpaperInterface::syncWallpaperPackage()
} else if (m_qmlObject->mainComponent()) {
qWarning() << "Error loading the wallpaper" << m_qmlObject->mainComponent()->errors();
s_rootObjects.remove(m_qmlObject->engine());
m_qmlObject->deleteLater();
m_qmlObject = 0;

View File

@ -21,6 +21,7 @@
#define WALLPAPERINTERFACE_H
#include <QQuickItem>
#include <QQmlEngine>
#include <Plasma/Package>
@ -78,6 +79,17 @@ public:
Q_INVOKABLE QAction *action(QString name) const;
static WallpaperInterface *qmlAttachedProperties(QObject *object)
{
//at the moment of the attached object creation, the root item is the only one that hasn't a parent
//only way to avoid creation of this attached for everybody but the root item
if (!object->parent() && s_rootObjects.contains(QtQml::qmlEngine(object))) {
return s_rootObjects.value(QtQml::qmlEngine(object));
} else {
return 0;
}
}
Q_SIGNALS:
void packageChanged();
void configurationChanged();
@ -95,6 +107,10 @@ private:
Plasma::ConfigLoader *m_configLoader;
KActionCollection *m_actions;
QSignalMapper *m_actionSignals;
static QHash<QObject *, WallpaperInterface *> s_rootObjects;
};
QML_DECLARE_TYPEINFO(WallpaperInterface, QML_HAS_ATTACHED_PROPERTIES)
#endif

View File

@ -182,7 +182,7 @@ void Panel::setOffset(int pixels)
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;
@ -222,7 +222,7 @@ int Panel::length() const
if (!c) {
return 0;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return 0;
@ -242,7 +242,7 @@ void Panel::setLength(int pixels)
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;
@ -279,7 +279,7 @@ int Panel::height() const
return 0;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return 0;
@ -296,7 +296,7 @@ void Panel::setHeight(int height)
return;
}
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("graphicObject").value<QObject *>());
QQuickItem *graphicObject = qobject_cast<QQuickItem *>(c->property("_plasma_graphicObject").value<QObject *>());
if (!graphicObject) {
return;

View File

@ -138,5 +138,19 @@ for FS in `find $PWD -name '*.h' -o -name '*.cpp'`; do
perl -p -i -e 's/Plasma\:\:AcceptingInputStatus/Plasma::Types::AcceptingInputStatus/g' $FS
done
# make compactrepresentation come from Plasmoid.*
# size hints come from Layout
for FS in `find $PWD -type f -name '*.qml'`; do
perl -p -i -e 's/property Component compactRepresentation/Plasmoid.compactRepresentation/g' $FS
perl -p -i -e 's/property int minimumWidth/Layout.minimumWidth/g' $FS
perl -p -i -e 's/property int minimumHeight/Layout.minimumHeight/g' $FS
perl -p -i -e 's/property int maximumWidth/Layout.maximumWidth/g' $FS
perl -p -i -e 's/property int maximumHeight/Layout.maximumHeight/g' $FS
perl -p -i -e 's/property bool fillWidth/Layout.fillWidth/g' $FS
perl -p -i -e 's/property bool fillHeight/Layout.fillHeight/g' $FS
done
for FS in `find $PWD -type f -name '*main.qml'`; do
perl -p -i -e 's/QtQuick 2.0/QtQuick 2.0\nimport org.kde.plasma.plasmoid 2.0/g' $FS
done