summaryrefslogtreecommitdiff
path: root/libsowatch/declarativewatchlet.cpp
blob: 34a1d2a3818f59e38588c7a88834b91eba990733 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <QtCore/QDebug>
#include <QtDeclarative/QtDeclarative>
#include "watchserver.h"
#include "declarativewatchwrapper.h"
#include "declarativewatchlet.h"

using namespace sowatch;

bool DeclarativeWatchlet::_registered = false;

DeclarativeWatchlet::DeclarativeWatchlet(WatchServer* server, const QString& id) :
	GraphicsWatchlet(server, id),
	_engine(0),
	_component(0),
	_item(0),
	_wrapper(0)
{
	setScene(new QGraphicsScene(this));

	if (!_registered) {
		qmlRegisterUncreatableType<DeclarativeWatchWrapper>("com.javispedro.sowatch", 1, 0,
			"Watch", "Watch is only available via the 'watch' object");
		_registered = true;
	}

	_engine = new QDeclarativeEngine(this);
	_wrapper = new DeclarativeWatchWrapper(server, server->watch(), this);

	_engine->rootContext()->setContextProperty("watch", _wrapper);
}

DeclarativeWatchlet::~DeclarativeWatchlet()
{

}

void DeclarativeWatchlet::setSource(const QUrl &url)
{
	if (_item) {
		scene()->removeItem(_item);
		delete _item;
		_item = 0;
	}
	if (_component) {
		delete _component;
		_component = 0;
	}
	if (!url.isEmpty()) {
		_component = new QDeclarativeComponent(_engine, url, this);
		connect(_component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
				SLOT(handleComponentStatus(QDeclarativeComponent::Status)));
		if (!_component->isLoading()) {
			/* No signals are going to be generated for this. */
			handleComponentStatus(_component->status());
		} else {
			connect(_component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
					this, SLOT(handleComponentStatus(QDeclarativeComponent::Status)));
		}
	}
}

QDeclarativeEngine* DeclarativeWatchlet::engine()
{
	return _engine;
}

QDeclarativeContext* DeclarativeWatchlet::rootContext()
{
	return _engine->rootContext();
}

QDeclarativeItem* DeclarativeWatchlet::rootObject()
{
	return _item;
}

void DeclarativeWatchlet::activate()
{
	GraphicsWatchlet::activate();
	_wrapper->activate();
}

void DeclarativeWatchlet::deactivate()
{
	_wrapper->deactivate();
	GraphicsWatchlet::deactivate();
}

void DeclarativeWatchlet::setRootObject(QDeclarativeItem *item)
{
	Q_ASSERT(_item == 0); /* This function should not be called with a current object. */
	if (!item) {
		qWarning() << "QML root object is not a declarative item?";
		return;
	}

	_item = item;
	// TODO Resize _item
	scene()->addItem(_item);
}

void DeclarativeWatchlet::handleComponentStatus(QDeclarativeComponent::Status status)
{
	QObject *obj;
	disconnect(_component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
			   this, SLOT(handleComponentStatus(QDeclarativeComponent::Status)));
	switch (status) {
	case QDeclarativeComponent::Null:
	case QDeclarativeComponent::Loading:
		/* Nothing to do */
		break;
	case QDeclarativeComponent::Ready:
		obj = _component->create();
		if (_component->isError()) {
			qWarning() << "QML has errors found while creating:";
			qWarning() <<  _component->errors();
			return;
		}
		setRootObject(qobject_cast<QDeclarativeItem*>(obj));
		break;
	case QDeclarativeComponent::Error:
		qWarning() << "QML has errors found while loading:";
		qWarning() <<  _component->errors();
		break;
	}
}