2014-01-28 22:55:02 +01:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
#include "appletquickitem.h"
|
2014-02-05 18:00:05 +01:00
|
|
|
#include "private/appletquickitem_p.h"
|
2014-01-28 22:55:02 +01:00
|
|
|
|
|
|
|
#include <QQmlComponent>
|
|
|
|
#include <QQmlExpression>
|
|
|
|
#include <QQmlEngine>
|
|
|
|
#include <QQmlProperty>
|
|
|
|
#include <QQmlContext>
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
2014-01-29 16:20:39 +01:00
|
|
|
#include <klocalizedstring.h>
|
|
|
|
|
2014-01-28 22:55:02 +01:00
|
|
|
#include <Plasma/Applet>
|
|
|
|
#include <Plasma/Containment>
|
|
|
|
#include <Plasma/Corona>
|
|
|
|
#include <kdeclarative/qmlobject.h>
|
|
|
|
#include <plasma/scripting/appletscript.h>
|
|
|
|
|
2014-01-29 16:20:39 +01:00
|
|
|
#include <packageurlinterceptor.h>
|
2014-01-28 22:55:02 +01:00
|
|
|
|
2014-02-19 19:37:30 +01:00
|
|
|
namespace PlasmaQuick
|
|
|
|
{
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
QHash<QObject *, AppletQuickItem *> AppletQuickItemPrivate::s_rootObjects = QHash<QObject *, AppletQuickItem *>();
|
|
|
|
|
2014-02-05 16:02:28 +01:00
|
|
|
AppletQuickItemPrivate::AppletQuickItemPrivate(Plasma::Applet *a, AppletQuickItem *item)
|
|
|
|
: q(item),
|
|
|
|
switchWidth(-1),
|
2014-02-05 14:54:22 +01:00
|
|
|
switchHeight(-1),
|
|
|
|
applet(a),
|
|
|
|
expanded(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:02:28 +01:00
|
|
|
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() &&
|
2014-04-26 01:45:47 +02:00
|
|
|
child->property("preferredWidth").isValid() && child->property("preferredHeight").isValid() &&
|
|
|
|
child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() &&
|
|
|
|
child->property("fillWidth").isValid() && child->property("fillHeight").isValid()
|
|
|
|
) {
|
2014-02-05 16:02:28 +01:00
|
|
|
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() &&
|
2014-04-26 01:45:47 +02:00
|
|
|
child->property("preferredWidth").isValid() && child->property("preferredHeight").isValid() &&
|
|
|
|
child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() &&
|
|
|
|
child->property("fillWidth").isValid() && child->property("fillHeight").isValid()
|
|
|
|
) {
|
2014-02-05 16:02:28 +01:00
|
|
|
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()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(minimumWidthChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
QObject::connect(layout, SIGNAL(minimumHeightChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(minimumHeightChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
|
|
|
|
QObject::connect(layout, SIGNAL(preferredWidthChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(preferredWidthChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
QObject::connect(layout, SIGNAL(preferredHeightChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(preferredHeightChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
|
|
|
|
QObject::connect(layout, SIGNAL(maximumWidthChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(maximumWidthChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
QObject::connect(layout, SIGNAL(maximumHeightChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(maximumHeightChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
|
|
|
|
QObject::connect(layout, SIGNAL(fillWidthChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(fillWidthChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
QObject::connect(layout, SIGNAL(fillHeightChanged()),
|
2014-04-26 01:45:47 +02:00
|
|
|
q, SLOT(fillHeightChanged()));
|
2014-02-05 16:02:28 +01:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2014-02-25 13:52:19 +01:00
|
|
|
if (fullRepresentation && fullRepresentation.data() != qmlObject->mainComponent()) {
|
2014-02-05 16:02:28 +01:00
|
|
|
fullRepresentationItem = qmlObject->createObjectFromComponent(fullRepresentation.data(), QtQml::qmlContext(qmlObject->rootObject()));
|
|
|
|
} else {
|
|
|
|
fullRepresentation = qmlObject->mainComponent();
|
|
|
|
fullRepresentationItem = qmlObject->rootObject();
|
|
|
|
emit q->fullRepresentationChanged(fullRepresentation.data());
|
|
|
|
}
|
|
|
|
|
2014-02-25 13:52:19 +01:00
|
|
|
if (!fullRepresentationItem) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:02:28 +01:00
|
|
|
QQuickItem *graphicsObj = qobject_cast<QQuickItem *>(fullRepresentationItem.data());
|
2014-03-06 15:57:37 +01:00
|
|
|
|
2014-04-26 01:45:47 +02:00
|
|
|
QObject::connect(graphicsObj, &QQuickItem::widthChanged, [ = ]() {
|
2014-02-05 16:02:28 +01:00
|
|
|
fullRepresentationResizeTimer.start();
|
|
|
|
});
|
2014-04-26 01:45:47 +02:00
|
|
|
QObject::connect(graphicsObj, &QQuickItem::heightChanged, [ = ]() {
|
2014-02-05 16:02:28 +01:00
|
|
|
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()));
|
|
|
|
|
2014-02-11 11:11:34 +01:00
|
|
|
if (!compactRepresentationExpanderItem) {
|
|
|
|
return 0;
|
|
|
|
}
|
2014-02-05 16:02:28 +01:00
|
|
|
|
|
|
|
compactRepresentationExpanderItem.data()->setProperty("compactRepresentation", QVariant::fromValue(createCompactRepresentationItem()));
|
|
|
|
|
|
|
|
return compactRepresentationExpanderItem.data();
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:23:57 +01:00
|
|
|
void AppletQuickItemPrivate::compactRepresentationCheck()
|
|
|
|
{
|
2014-05-08 15:48:41 +02:00
|
|
|
if (!qmlObject->mainComponent() || qmlObject->mainComponent()->status() != QQmlComponent::Ready) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:23:57 +01:00
|
|
|
//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;
|
2014-04-26 01:45:47 +02:00
|
|
|
//if a size to switch wasn't set, determine what representation to always chose
|
2014-02-05 16:23:57 +01:00
|
|
|
} else {
|
|
|
|
//preferred representation set?
|
|
|
|
if (preferredRepresentation) {
|
|
|
|
full = preferredRepresentation.data() == fullRepresentation.data();
|
2014-04-26 01:45:47 +02:00
|
|
|
//Otherwise, base on FormFactor
|
2014-02-05 16:23:57 +01:00
|
|
|
} else {
|
|
|
|
full = (applet->formFactor() != Plasma::Types::Horizontal && applet->formFactor() != Plasma::Types::Vertical);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((full && fullRepresentationItem && fullRepresentationItem.data() == currentRepresentationItem.data()) ||
|
2014-04-26 01:45:47 +02:00
|
|
|
(!full && compactRepresentationItem && compactRepresentationItem.data() == currentRepresentationItem.data())
|
|
|
|
) {
|
2014-02-05 16:23:57 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Expanded
|
|
|
|
if (full) {
|
|
|
|
QQuickItem *item = qobject_cast<QQuickItem *>(createFullRepresentationItem());
|
|
|
|
|
|
|
|
if (item) {
|
2014-02-07 12:19:58 +01:00
|
|
|
//unwire with the expander
|
|
|
|
if (compactRepresentationExpanderItem) {
|
|
|
|
compactRepresentationExpanderItem.data()->setProperty("fullRepresentation", QVariant());
|
2014-03-24 17:07:30 +01:00
|
|
|
compactRepresentationExpanderItem.data()->setProperty("compactRepresentation", QVariant());
|
2014-02-07 12:19:58 +01:00
|
|
|
compactRepresentationExpanderItem.data()->setProperty("visible", false);
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:23:57 +01:00
|
|
|
item->setParentItem(q);
|
|
|
|
{
|
|
|
|
//set anchors
|
|
|
|
QQmlExpression expr(QtQml::qmlContext(qmlObject->rootObject()), item, "parent");
|
|
|
|
QQmlProperty prop(item, "anchors.fill");
|
|
|
|
prop.write(expr.evaluate());
|
|
|
|
}
|
2014-02-07 12:19:58 +01:00
|
|
|
|
2014-02-05 16:23:57 +01:00
|
|
|
if (compactRepresentationItem) {
|
|
|
|
compactRepresentationItem.data()->setProperty("visible", false);
|
|
|
|
}
|
2014-02-07 12:19:58 +01:00
|
|
|
|
2014-02-05 16:23:57 +01:00
|
|
|
currentRepresentationItem = item;
|
|
|
|
connectLayoutAttached(item);
|
2014-02-06 13:57:53 +01:00
|
|
|
expanded = true;
|
|
|
|
emit q->expandedChanged(true);
|
2014-02-05 16:23:57 +01:00
|
|
|
}
|
|
|
|
|
2014-04-26 01:45:47 +02:00
|
|
|
//Icon
|
2014-02-05 16:23:57 +01:00
|
|
|
} else {
|
|
|
|
QQuickItem *compactItem = qobject_cast<QQuickItem *>(createCompactRepresentationItem());
|
2014-02-07 12:19:58 +01:00
|
|
|
QQuickItem *compactExpanderItem = qobject_cast<QQuickItem *>(createCompactRepresentationExpanderItem());
|
2014-02-05 16:23:57 +01:00
|
|
|
|
2014-02-07 12:19:58 +01:00
|
|
|
if (compactItem && compactExpanderItem) {
|
2014-02-05 16:23:57 +01:00
|
|
|
//set the root item as the main visible item
|
|
|
|
compactItem->setVisible(true);
|
2014-02-07 16:19:11 +01:00
|
|
|
compactExpanderItem->setParentItem(q);
|
|
|
|
compactExpanderItem->setVisible(true);
|
2014-02-05 16:23:57 +01:00
|
|
|
{
|
|
|
|
//set anchors
|
2014-02-07 16:19:11 +01:00
|
|
|
QQmlExpression expr(QtQml::qmlContext(qmlObject->rootObject()), compactExpanderItem, "parent");
|
|
|
|
QQmlProperty prop(compactExpanderItem, "anchors.fill");
|
2014-02-05 16:23:57 +01:00
|
|
|
prop.write(expr.evaluate());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fullRepresentationItem) {
|
|
|
|
fullRepresentationItem.data()->setProperty("parent", QVariant());
|
|
|
|
}
|
|
|
|
|
2014-02-07 12:19:58 +01:00
|
|
|
compactExpanderItem->setProperty("compactRepresentation", QVariant::fromValue(compactItem));
|
|
|
|
//The actual full representation will be connected when created
|
|
|
|
compactExpanderItem->setProperty("fullRepresentation", QVariant::fromValue(QVariant()));
|
2014-02-05 16:23:57 +01:00
|
|
|
|
|
|
|
currentRepresentationItem = compactItem;
|
|
|
|
connectLayoutAttached(compactItem);
|
2014-04-26 01:45:47 +02:00
|
|
|
|
2014-02-06 13:57:53 +01:00
|
|
|
expanded = false;
|
|
|
|
emit q->expandedChanged(false);
|
2014-02-05 16:23:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-05 16:02:28 +01:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2014-05-08 15:48:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
AppletQuickItem::AppletQuickItem(Plasma::Applet *applet, QQuickItem *parent)
|
2014-01-28 22:55:02 +01:00
|
|
|
: QQuickItem(parent),
|
2014-02-05 16:02:28 +01:00
|
|
|
d(new AppletQuickItemPrivate(applet, this))
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
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();
|
2014-02-04 16:43:47 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->compactRepresentationCheckTimer.setSingleShot(true);
|
|
|
|
d->compactRepresentationCheckTimer.setInterval(250);
|
2014-04-26 01:45:47 +02:00
|
|
|
connect(&d->compactRepresentationCheckTimer, SIGNAL(timeout()),
|
|
|
|
this, SLOT(compactRepresentationCheck()));
|
2014-02-05 14:54:22 +01:00
|
|
|
d->compactRepresentationCheckTimer.start();
|
2014-01-28 22:55:02 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->fullRepresentationResizeTimer.setSingleShot(true);
|
|
|
|
d->fullRepresentationResizeTimer.setInterval(250);
|
2014-04-26 01:45:47 +02:00
|
|
|
connect(&d->fullRepresentationResizeTimer, &QTimer::timeout,
|
|
|
|
[ = ]() {
|
|
|
|
if (!d->applet->isContainment()) {
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
});
|
2014-01-28 22:55:02 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->qmlObject = new KDeclarative::QmlObject(this);
|
|
|
|
d->qmlObject->setInitializationDelayed(true);
|
2014-02-05 12:51:31 +01:00
|
|
|
|
|
|
|
// set the graphicObject dynamic property on applet
|
2014-02-05 14:54:22 +01:00
|
|
|
d->applet->setProperty("_plasma_graphicObject", QVariant::fromValue(this));
|
2014-02-05 12:51:31 +01:00
|
|
|
setProperty("_plasma_applet", QVariant::fromValue(applet));
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
AppletQuickItem::~AppletQuickItem()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-01-29 17:09:43 +01:00
|
|
|
//Here the order is important
|
2014-02-05 14:54:22 +01:00
|
|
|
delete d->compactRepresentationItem.data();
|
|
|
|
delete d->fullRepresentationItem.data();
|
|
|
|
delete d->compactRepresentationExpanderItem.data();
|
2014-01-29 17:09:43 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
AppletQuickItemPrivate::s_rootObjects.remove(d->qmlObject->engine());
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-04-26 01:45:47 +02:00
|
|
|
AppletQuickItem *AppletQuickItem::qmlAttachedProperties(QObject *object)
|
2014-02-05 17:23:52 +01:00
|
|
|
{
|
|
|
|
//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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
Plasma::Applet *AppletQuickItem::applet() const
|
2014-02-05 12:51:31 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->applet;
|
2014-02-05 12:51:31 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::init()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-25 13:52:19 +01:00
|
|
|
if (AppletQuickItemPrivate::s_rootObjects.contains(d->qmlObject->engine())) {
|
2014-01-29 17:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
AppletQuickItemPrivate::s_rootObjects[d->qmlObject->engine()] = this;
|
2014-01-29 16:20:39 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
Q_ASSERT(d->applet);
|
2014-01-29 16:20:39 +01:00
|
|
|
|
|
|
|
//Initialize the main QML file
|
2014-02-05 14:54:22 +01:00
|
|
|
QQmlEngine *engine = d->qmlObject->engine();
|
2014-01-29 16:20:39 +01:00
|
|
|
|
2014-04-02 18:59:47 +02:00
|
|
|
if (d->applet->package().isValid()) {
|
|
|
|
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(engine, d->applet->package());
|
|
|
|
interceptor->addAllowedPath(d->coronaPackage.path());
|
|
|
|
engine->setUrlInterceptor(interceptor);
|
|
|
|
}
|
2014-01-29 16:20:39 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->qmlObject->setSource(QUrl::fromLocalFile(d->applet->package().filePath("mainscript")));
|
2014-01-29 16:20:39 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
if (!engine || !engine->rootContext() || !engine->rootContext()->isValid() || d->qmlObject->mainComponent()->isError()) {
|
2014-01-29 16:20:39 +01:00
|
|
|
QString reason;
|
2014-04-02 18:59:47 +02:00
|
|
|
if (d->applet->package().isValid()) {
|
|
|
|
foreach (QQmlError error, d->qmlObject->mainComponent()->errors()) {
|
2014-04-26 01:45:47 +02:00
|
|
|
reason += error.toString() + '\n';
|
2014-04-02 18:59:47 +02:00
|
|
|
}
|
|
|
|
reason = i18n("Error loading QML file: %1", reason);
|
|
|
|
} else {
|
|
|
|
reason = i18n("Error loading Applet: package inexistent. %1", applet()->launchErrorMessage());
|
2014-01-29 16:20:39 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->qmlObject->setSource(QUrl::fromLocalFile(d->coronaPackage.filePath("appleterror")));
|
|
|
|
d->qmlObject->completeInitialization();
|
2014-01-29 16:20:39 +01:00
|
|
|
|
|
|
|
//even the error message QML may fail
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->qmlObject->mainComponent()->isError()) {
|
2014-01-29 16:20:39 +01:00
|
|
|
return;
|
|
|
|
} else {
|
2014-02-05 14:54:22 +01:00
|
|
|
d->qmlObject->rootObject()->setProperty("reason", reason);
|
2014-01-29 16:20:39 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->applet->setLaunchErrorMessage(reason);
|
2014-01-29 16:20:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
engine->rootContext()->setContextProperty("plasmoid", this);
|
|
|
|
|
|
|
|
//initialize size, so an useless resize less
|
|
|
|
QVariantHash initialProperties;
|
|
|
|
initialProperties["width"] = width();
|
|
|
|
initialProperties["height"] = height();
|
2014-02-05 14:54:22 +01:00
|
|
|
d->qmlObject->completeInitialization(initialProperties);
|
2014-01-29 17:09:43 +01:00
|
|
|
|
2014-05-08 15:48:41 +02:00
|
|
|
|
2014-01-29 20:07:29 +01:00
|
|
|
//default fullrepresentation is our root main component, if none specified
|
2014-02-05 14:54:22 +01:00
|
|
|
if (!d->fullRepresentation) {
|
|
|
|
d->fullRepresentation = d->qmlObject->mainComponent();
|
|
|
|
d->fullRepresentationItem = d->qmlObject->rootObject();
|
2014-03-06 15:57:37 +01:00
|
|
|
|
|
|
|
if (d->qmlObject->rootObject()) {
|
|
|
|
QQuickItem *graphicsObj = qobject_cast<QQuickItem *>(d->fullRepresentationItem.data());
|
2014-04-26 01:45:47 +02:00
|
|
|
QObject::connect(graphicsObj, &QQuickItem::widthChanged, [ = ]() {
|
2014-03-06 15:57:37 +01:00
|
|
|
d->fullRepresentationResizeTimer.start();
|
|
|
|
});
|
2014-04-26 01:45:47 +02:00
|
|
|
QObject::connect(graphicsObj, &QQuickItem::heightChanged, [ = ]() {
|
2014-03-06 15:57:37 +01:00
|
|
|
d->fullRepresentationResizeTimer.start();
|
|
|
|
});
|
|
|
|
}
|
2014-02-05 14:54:22 +01:00
|
|
|
emit fullRepresentationChanged(d->fullRepresentation.data());
|
2014-01-29 20:07:29 +01:00
|
|
|
}
|
2014-01-29 16:20:39 +01:00
|
|
|
|
2014-05-08 15:48:41 +02:00
|
|
|
//default compactRepresentation is a simple icon provided by the shell package
|
2014-02-05 14:54:22 +01:00
|
|
|
if (!d->compactRepresentation) {
|
|
|
|
d->compactRepresentation = new QQmlComponent(engine, this);
|
|
|
|
d->compactRepresentation.data()->loadUrl(QUrl::fromLocalFile(d->coronaPackage.filePath("defaultcompactrepresentation")));
|
|
|
|
emit compactRepresentationChanged(d->compactRepresentation.data());
|
2014-01-29 16:20:39 +01:00
|
|
|
}
|
|
|
|
|
2014-05-08 15:48:41 +02:00
|
|
|
//default compactRepresentationExpander is the popup in which fullRepresentation goes
|
2014-02-05 14:54:22 +01:00
|
|
|
if (!d->compactRepresentationExpander) {
|
|
|
|
d->compactRepresentationExpander = new QQmlComponent(engine, this);
|
|
|
|
d->compactRepresentationExpander.data()->loadUrl(QUrl::fromLocalFile(d->coronaPackage.filePath("compactapplet")));
|
2014-01-29 16:20:39 +01:00
|
|
|
}
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-05-08 15:48:41 +02:00
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
Plasma::Package AppletQuickItem::appletPackage() const
|
2014-02-05 13:51:41 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->appletPackage;
|
2014-02-05 13:51:41 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setAppletPackage(const Plasma::Package &package)
|
2014-02-05 13:51:41 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
d->appletPackage = package;
|
2014-02-05 13:51:41 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
Plasma::Package AppletQuickItem::coronaPackage() const
|
2014-02-05 13:51:41 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->coronaPackage;
|
2014-02-05 13:51:41 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setCoronaPackage(const Plasma::Package &package)
|
2014-02-05 13:51:41 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
d->coronaPackage = package;
|
2014-02-05 13:51:41 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
int AppletQuickItem::switchWidth() const
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->switchWidth;
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setSwitchWidth(int width)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->switchWidth == width) {
|
2014-01-28 22:55:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->switchWidth = width;
|
2014-01-28 22:55:02 +01:00
|
|
|
emit switchWidthChanged(width);
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
int AppletQuickItem::switchHeight() const
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->switchHeight;
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setSwitchHeight(int width)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->switchHeight == width) {
|
2014-01-28 22:55:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->switchHeight = width;
|
2014-01-28 22:55:02 +01:00
|
|
|
emit switchHeightChanged(width);
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
QQmlComponent *AppletQuickItem::compactRepresentation()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->compactRepresentation.data();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setCompactRepresentation(QQmlComponent *component)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->compactRepresentation.data() == component) {
|
2014-01-28 22:55:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->compactRepresentation = component;
|
2014-01-28 22:55:02 +01:00
|
|
|
emit compactRepresentationChanged(component);
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
QQmlComponent *AppletQuickItem::fullRepresentation()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->fullRepresentation.data();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setFullRepresentation(QQmlComponent *component)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->fullRepresentation.data() == component) {
|
2014-01-28 22:55:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->fullRepresentation = component;
|
2014-01-28 22:55:02 +01:00
|
|
|
emit fullRepresentationChanged(component);
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
QQmlComponent *AppletQuickItem::preferredRepresentation()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->preferredRepresentation.data();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setPreferredRepresentation(QQmlComponent *component)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->preferredRepresentation.data() == component) {
|
2014-01-28 22:55:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->preferredRepresentation = component;
|
2014-01-28 22:55:02 +01:00
|
|
|
emit preferredRepresentationChanged(component);
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
bool AppletQuickItem::isExpanded() const
|
2014-01-29 17:09:43 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->expanded;
|
2014-01-29 17:09:43 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::setExpanded(bool expanded)
|
2014-01-29 17:09:43 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->applet->isContainment()) {
|
2014-01-29 17:09:43 +01:00
|
|
|
expanded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//if there is no compact representation it means it's always expanded
|
|
|
|
//Containnments are always expanded
|
2014-02-05 14:54:22 +01:00
|
|
|
if (d->expanded == expanded) {
|
2014-01-29 17:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-10 18:14:11 +01:00
|
|
|
if (expanded) {
|
|
|
|
d->createFullRepresentationItem();
|
2014-04-08 20:14:06 +02:00
|
|
|
if (!d->applet->isContainment() &&
|
2014-04-26 01:45:47 +02:00
|
|
|
(!d->preferredRepresentation ||
|
|
|
|
d->preferredRepresentation.data() != d->fullRepresentation.data())) {
|
2014-04-08 20:14:06 +02:00
|
|
|
d->createCompactRepresentationExpanderItem();
|
|
|
|
}
|
2014-03-06 15:57:37 +01:00
|
|
|
|
|
|
|
KConfigGroup cg = d->applet->config();
|
|
|
|
cg = KConfigGroup(&cg, "PopupApplet");
|
|
|
|
const int width = cg.readEntry("DialogWidth", -1);
|
|
|
|
const int height = cg.readEntry("DialogHeight", -1);
|
|
|
|
if (width > 0 && height > 0) {
|
|
|
|
d->fullRepresentationItem.data()->setProperty("width", width);
|
|
|
|
d->fullRepresentationItem.data()->setProperty("height", height);
|
|
|
|
}
|
|
|
|
|
2014-04-08 20:14:06 +02:00
|
|
|
if (d->compactRepresentationExpanderItem) {
|
|
|
|
d->compactRepresentationExpanderItem.data()->setProperty("fullRepresentation", QVariant::fromValue(d->createFullRepresentationItem()));
|
|
|
|
} else {
|
|
|
|
d->fullRepresentationItem.data()->setProperty("parent", QVariant::fromValue(this));
|
|
|
|
}
|
2014-02-10 18:14:11 +01:00
|
|
|
}
|
2014-01-29 17:09:43 +01:00
|
|
|
|
2014-02-05 14:54:22 +01:00
|
|
|
d->expanded = expanded;
|
2014-01-30 22:38:44 +01:00
|
|
|
emit expandedChanged(expanded);
|
2014-01-29 17:09:43 +01:00
|
|
|
}
|
2014-01-28 22:55:02 +01:00
|
|
|
|
|
|
|
////////////Internals
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
KDeclarative::QmlObject *AppletQuickItem::qmlObject()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->qmlObject;
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
QObject *AppletQuickItem::compactRepresentationItem()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->compactRepresentationItem.data();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
QObject *AppletQuickItem::fullRepresentationItem()
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
2014-02-05 14:54:22 +01:00
|
|
|
return d->fullRepresentationItem.data();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-05-09 13:12:38 +02:00
|
|
|
QObject *AppletQuickItem::rootItem()
|
|
|
|
{
|
|
|
|
return d->qmlObject->rootObject();
|
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
|
|
|
Q_UNUSED(oldGeometry)
|
|
|
|
|
|
|
|
QQuickItem::geometryChanged(newGeometry, oldGeometry);
|
2014-02-05 14:54:22 +01:00
|
|
|
d->compactRepresentationCheckTimer.start();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
void AppletQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
|
2014-01-28 22:55:02 +01:00
|
|
|
{
|
|
|
|
if (change == QQuickItem::ItemSceneChange) {
|
|
|
|
//we have a window: create the representations if needed
|
|
|
|
if (value.window) {
|
2014-01-29 16:20:39 +01:00
|
|
|
init();
|
2014-01-28 22:55:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QQuickItem::itemChange(change, value);
|
|
|
|
}
|
|
|
|
|
2014-02-19 19:37:30 +01:00
|
|
|
}
|
2014-01-28 22:55:02 +01:00
|
|
|
|
2014-02-05 14:19:39 +01:00
|
|
|
#include "moc_appletquickitem.cpp"
|
2014-01-28 22:55:02 +01:00
|
|
|
|