Merge lp:~super-friends/qml-friends/raring into lp:qml-friends

Proposed by Ken VanDine
Status: Merged
Approved by: Ken VanDine
Approved revision: 38
Merged at revision: 34
Proposed branch: lp:~super-friends/qml-friends/raring
Merge into: lp:qml-friends
Diff against target: 1000 lines (+538/-149)
19 files modified
debian/changelog (+15/-0)
debian/control (+7/-0)
examples/README (+95/-0)
examples/streamview.qml (+0/-121)
friends.pro (+3/-0)
modules/Friends/plugin/friendsdispatcher.cpp (+8/-0)
modules/Friends/plugin/friendsdispatcher.h (+2/-0)
modules/Friends/plugin/friendsutils.cpp (+0/-2)
modules/Friends/plugin/friendsutils.h (+1/-6)
modules/Friends/plugin/plugin.cpp (+9/-11)
modules/Friends/plugin/plugin.h (+2/-3)
modules/Friends/plugin/plugin.pro (+8/-6)
modules/Friends/plugin/streammodel.cpp (+176/-0)
modules/Friends/plugin/streammodel.h (+46/-0)
tests/tests.pro (+4/-0)
tests/unit/main.cpp (+2/-0)
tests/unit/run.sh (+7/-0)
tests/unit/tst_test.qml (+140/-0)
tests/unit/unit.pro (+13/-0)
To merge this branch: bzr merge lp:~super-friends/qml-friends/raring
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Ken VanDine Approve
Review via email: mp+154367@code.launchpad.net

Commit message

  * Added StreamModel
    - Filters available for stream, service, and account (LP: #1156941)
  * Added Refresh
  * Added tests
  * Updated for the schema changes in friends
  * debian/control
    - build depend on libdee-qt5-dev
    - Added build depends for running tests: dbus-test-runner, xvfb,
      qtdeclarative5-qtquick2-plugin, and qtdeclarative5-test-plugin
    - build depend on friends-dispatcher (>= 0.1.2daily13.03.14)

Description of the change

Merged queued changes for raring now that the FFe is approved

To post a comment you must log in.
Revision history for this message
Ken VanDine (ken-vandine) wrote :

These changes have been reviewed before merging into the raring branch

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-03-07 16:38:08 +0000
3+++ debian/changelog 2013-03-20 13:31:31 +0000
4@@ -1,3 +1,18 @@
5+qml-friends (0.1.1-0ubuntu1) UNRELEASED; urgency=low
6+
7+ * Added StreamModel
8+ - Filters available for stream, service, and account (LP: #1156941)
9+ * Added Refresh
10+ * Added tests
11+ * Updated for the schema changes in friends
12+ * debian/control
13+ - build depend on libdee-qt5-dev
14+ - Added build depends for running tests: dbus-test-runner, xvfb,
15+ qtdeclarative5-qtquick2-plugin, and qtdeclarative5-test-plugin
16+ - build depend on friends-dispatcher (>= 0.1.2daily13.03.14)
17+
18+ -- Ken VanDine <ken.vandine@canonical.com> Mon, 18 Mar 2013 22:49:02 -0400
19+
20 qml-friends (0.1.0bzr13.03.07-0ubuntu1) raring; urgency=low
21
22 * Use the correct callback for likeAsync
23
24=== modified file 'debian/control'
25--- debian/control 2013-03-05 18:52:53 +0000
26+++ debian/control 2013-03-20 13:31:31 +0000
27@@ -11,7 +11,14 @@
28 qt5-qmake,
29 qtbase5-dev,
30 qtdeclarative5-dev,
31+ qtdeclarative5-test-plugin,
32+ libdee-qt5-dev,
33+ friends-dispatcher (>= 0.1.2daily13.03.14),
34 libfriends-dev (>= 0.1.1bzr13.02.07-0ubuntu1),
35+ dbus-test-runner,
36+ xvfb,
37+ qtdeclarative5-qtquick2-plugin,
38+ qtdeclarative5-test-plugin,
39 Standards-Version: 3.9.3
40 Section: libs
41 Homepage: https://launchpad.net/qml-friends
42
43=== added file 'examples/README'
44--- examples/README 1970-01-01 00:00:00 +0000
45+++ examples/README 2013-03-20 13:31:31 +0000
46@@ -0,0 +1,95 @@
47+Code examples for qml-friends
48+
49+All the dependencies can be installed from ppa:super-friends/ppa
50+
51+Installing the qtdeclarative5-friends-plugin package should bring in the necessary dependencies
52+
53+/* Sending
54+ http://bazaar.launchpad.net/~super-friends/qml-friends/raring/view/head:/examples/poster.qml */
55+
56+import Friends 0.1
57+
58+FriendsDispatcher {
59+ id: friends
60+ // use this to check if the send was successfull
61+ onSendComplete: {
62+ if (success) {
63+ console.log ("Send completed successfully");
64+ } else {
65+ console.log ("Send failed: " + errorMessage);
66+ }
67+ }
68+}
69+
70+Button {
71+ id: sendButton
72+ text: i18n.tr("Send")
73+ onClicked: {
74+ /* async method to send, connect to onSendComplete for success/failure */
75+ friends.sendAsync(entry.text);
76+ }
77+}
78+
79+Getting a model of the data from Friends
80+http://bazaar.launchpad.net/~super-friends/qml-friends/raring/view/head:/examples/streamview.qml
81+
82+/* To get a model of all posts, suitable for use in a ListView,
83+ Repeater, etc */
84+StreamModel {
85+ id: streamModel
86+}
87+
88+/* The roleNames provided from streamModel isn't all that intuitive right now.
89+ service: column_0
90+ account_id: column_1
91+ message_id: column_2
92+ stream: column_3
93+ sender: column_4
94+ sender_id: column_5
95+ sender_nick: column_6
96+ from_me: column_7
97+ timestamp: column_8
98+ message: column_9
99+ icon_uri: column_10
100+ url: column_11
101+ likes: column_12
102+ liked: column_13
103+ link_picture: column_14
104+ link_name: column_15
105+ link_url: column_16
106+ link_desc: column_17
107+ link_caption: column_18
108+ link_icon: column_19
109+ location: column_20
110+ latitude: column_21
111+ longitude: column_22
112+*/
113+
114+/* To get a model of all images */
115+StreamModel {
116+ stream: "images"
117+}
118+
119+/* To get a model of content from twitter */
120+StreamModel {
121+ service: "twitter"
122+}
123+
124+/* To get a model of content from accountId 2 */
125+StreamModel {
126+ account: 2
127+}
128+
129+/* To get a model of threads on a post */
130+StreamModel {
131+ stream: "reply_to/"+messageId
132+}
133+
134+/* convenience function for converting timestamps into time delta
135+ strings, like "2 hours ago" */
136+FriendsUtils {
137+ id: friendsUtils
138+}
139+
140+friendsUtils.createTimeString(column_8)
141+
142
143=== added file 'examples/streamview.qml'
144--- examples/streamview.qml 1970-01-01 00:00:00 +0000
145+++ examples/streamview.qml 2013-03-20 13:31:31 +0000
146@@ -0,0 +1,128 @@
147+/*
148+ * Copyright (C) 2013 Canonical, Ltd.
149+ *
150+ * This program is free software; you can redistribute it and/or modify
151+ * it under the terms of the GNU General Public License as published by
152+ * the Free Software Foundation; version 3.
153+ *
154+ * This program is distributed in the hope that it will be useful,
155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
157+ * GNU General Public License for more details.
158+ *
159+ * You should have received a copy of the GNU General Public License
160+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
161+ */
162+
163+import QtQuick 2.0
164+import Ubuntu.Components 0.1
165+import Ubuntu.Components.ListItems 0.1
166+import Friends 0.1
167+
168+MainView {
169+ width: units.gu(50)
170+ height: units.gu(100)
171+
172+ FriendsUtils {
173+ id: friendsUtils
174+ }
175+
176+ ListView {
177+ id: listView
178+ anchors {
179+ fill: parent
180+ }
181+ snapMode: ListView.SnapToItem
182+ /* Reverse ListView order */
183+ verticalLayoutDirection: ListView.BottomToTop
184+ cacheBuffer: parent.height
185+ model: StreamModel {
186+ //stream: "messages"
187+ //service: "facebook"
188+ /* account Id from libaccounts */
189+ //account: 1
190+ }
191+ populate: Transition {
192+ ScriptAction { script: listView.positionViewAtEnd() }
193+ }
194+
195+ delegate: Item {
196+ id: tile
197+ height: status_update_content.height
198+ width: parent.width
199+ anchors {
200+ margins: units.gu(1)
201+ }
202+
203+ UbuntuShape {
204+ id: avatarImage
205+ radius: "medium"
206+ height: units.dp(48)
207+ width: units.dp(48)
208+ anchors {
209+ left: parent.left
210+ top: parent.top
211+ leftMargin: units.gu(1)
212+ topMargin: units.gu(1)
213+ }
214+ image: Image {
215+ anchors.fill: parent
216+ source: Qt.resolvedUrl(column_10)
217+ asynchronous: true
218+ fillMode: Image.PreserveAspectFit
219+ }
220+ }
221+
222+ Item {
223+ id: status_update_content
224+ anchors {
225+ left: avatarImage.right
226+ right: parent.right
227+ top: parent.top
228+ topMargin: units.gu(1)
229+ leftMargin: units.gu(1)
230+ bottomMargin: units.gu(1)
231+ rightMargin: units.gu(1)
232+ }
233+ height: childrenRect.height + units.gu(2)
234+ Column {
235+ spacing: units.gu(1)
236+ anchors {
237+ left: parent.left;
238+ right: parent.right
239+ bottomMargin: units.gu(2)
240+ }
241+ Label {
242+ id: sender
243+ text: column_4
244+ fontSize: "medium"
245+ font.bold: true
246+ font.family: "Ubuntu"
247+ width: parent.width
248+ }
249+ Label {
250+ id: message
251+ text: column_9
252+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
253+ width: parent.width - units.gu(3)
254+ font.family: "Ubuntu"
255+ }
256+ }
257+ Row {
258+ anchors.right: parent.right
259+ anchors.rightMargin: units.gu(1)
260+ anchors.top: parent.top
261+ spacing: units.gu(1)
262+
263+ Label {
264+ id: time
265+ text: friendsUtils.createTimeString(column_8)
266+ fontSize: "small"
267+ font.family: "Ubuntu"
268+ }
269+ }
270+ }
271+ ThinDivider {}
272+ }
273+ }
274+}
275
276=== removed file 'examples/streamview.qml'
277--- examples/streamview.qml 2013-03-08 15:19:38 +0000
278+++ examples/streamview.qml 1970-01-01 00:00:00 +0000
279@@ -1,121 +0,0 @@
280-/*
281- * Copyright (C) 2013 Canonical, Ltd.
282- *
283- * This program is free software; you can redistribute it and/or modify
284- * it under the terms of the GNU General Public License as published by
285- * the Free Software Foundation; version 3.
286- *
287- * This program is distributed in the hope that it will be useful,
288- * but WITHOUT ANY WARRANTY; without even the implied warranty of
289- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290- * GNU General Public License for more details.
291- *
292- * You should have received a copy of the GNU General Public License
293- * along with this program. If not, see <http://www.gnu.org/licenses/>.
294- */
295-
296-import QtQuick 2.0
297-import Ubuntu.Components 0.1
298-import Ubuntu.Components.ListItems 0.1
299-import Dee 3.0
300-import Friends 0.1
301-
302-MainView {
303- width: units.gu(50)
304- height: units.gu(100)
305-
306- FriendsUtils {
307- id: friendsUtils
308- }
309-
310- ListView {
311- id: listView
312- anchors {
313- fill: parent
314- }
315- snapMode: ListView.SnapToItem
316- verticalLayoutDirection: ListView.BottomToTop
317- cacheBuffer: parent.height
318-
319- model: DeeListModel { name: "com.canonical.Friends.Streams" }
320-
321- delegate: Item {
322- id: tile
323- height: status_update_content.height
324- width: parent.width
325- anchors {
326- margins: units.gu(1)
327- }
328-
329- UbuntuShape {
330- id: avatarImage
331- radius: "medium"
332- height: units.dp(48)
333- width: units.dp(48)
334- anchors {
335- left: parent.left
336- top: parent.top
337- leftMargin: units.gu(1)
338- topMargin: units.gu(1)
339- }
340- image: Image {
341- anchors.fill: parent
342- source: Qt.resolvedUrl(column_8)
343- asynchronous: true
344- fillMode: Image.PreserveAspectFit
345- }
346- }
347-
348- Item {
349- id: status_update_content
350- anchors {
351- left: avatarImage.right
352- right: parent.right
353- top: parent.top
354- topMargin: units.gu(1)
355- leftMargin: units.gu(1)
356- bottomMargin: units.gu(1)
357- rightMargin: units.gu(1)
358- }
359- height: childrenRect.height + units.gu(2)
360- Column {
361- spacing: units.gu(1)
362- anchors {
363- left: parent.left;
364- right: parent.right
365- bottomMargin: units.gu(2)
366- }
367- Label {
368- id: sender
369- text: column_2
370- fontSize: "medium"
371- font.bold: true
372- font.family: "Ubuntu"
373- width: parent.width
374- }
375- Label {
376- id: message
377- text: column_7
378- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
379- width: parent.width - units.gu(3)
380- font.family: "Ubuntu"
381- }
382- }
383- Row {
384- anchors.right: parent.right
385- anchors.rightMargin: units.gu(1)
386- anchors.top: parent.top
387- spacing: units.gu(1)
388-
389- Label {
390- id: time
391- text: friendsUtils.createTimeString(column_6)
392- fontSize: "small"
393- font.family: "Ubuntu"
394- }
395- }
396- }
397- ThinDivider {}
398- }
399- }
400-}
401
402=== modified file 'friends.pro'
403--- friends.pro 2013-01-15 19:49:40 +0000
404+++ friends.pro 2013-03-20 13:31:31 +0000
405@@ -15,3 +15,6 @@
406 dist.depends = distclean
407
408 QMAKE_EXTRA_TARGETS += dist
409+
410+SUBDIRS += \
411+ tests
412
413=== modified file 'modules/Friends/plugin/friendsdispatcher.cpp'
414--- modules/Friends/plugin/friendsdispatcher.cpp 2013-03-06 17:51:39 +0000
415+++ modules/Friends/plugin/friendsdispatcher.cpp 2013-03-20 13:31:31 +0000
416@@ -299,3 +299,11 @@
417 &sendReplyCompleteCallback, (gpointer) this);
418 }
419
420+void FriendsDispatcherQml::refresh() const
421+{
422+ GError* error = NULL;
423+ friends_dispatcher_refresh(m_dispatcher, &error);
424+
425+ if (error != NULL)
426+ g_error_free (error);
427+}
428
429=== modified file 'modules/Friends/plugin/friendsdispatcher.h'
430--- modules/Friends/plugin/friendsdispatcher.h 2013-02-14 15:26:37 +0000
431+++ modules/Friends/plugin/friendsdispatcher.h 2013-03-20 13:31:31 +0000
432@@ -46,6 +46,8 @@
433 void likeAsync(const int& account_id, const QString& message_id) const;
434 void unlike(const int& account_id, const QString& message_id) const;
435 void unlikeAsync(const int& account_id, const QString& message_id) const;
436+ void refresh() const;
437+
438
439 Q_SIGNALS:
440 void uploadComplete(QString resultUrl, bool success, QString errorMessage);
441
442=== modified file 'modules/Friends/plugin/friendsutils.cpp'
443--- modules/Friends/plugin/friendsutils.cpp 2012-11-28 18:22:36 +0000
444+++ modules/Friends/plugin/friendsutils.cpp 2013-03-20 13:31:31 +0000
445@@ -17,9 +17,7 @@
446
447 #include "friendsutils.h"
448
449-#include <QGuiApplication>
450 #include <QtQuick/QQuickView>
451-#include <QtQuick/QQuickItem>
452
453 #include <glib-object.h>
454
455
456=== modified file 'modules/Friends/plugin/friendsutils.h'
457--- modules/Friends/plugin/friendsutils.h 2012-11-28 18:22:36 +0000
458+++ modules/Friends/plugin/friendsutils.h 2013-03-20 13:31:31 +0000
459@@ -18,14 +18,9 @@
460 #ifndef FRIENDSUTILS_H
461 #define FRIENDSUTILS_H
462
463-#include <QtCore/QObject>
464-#include <QtQuick/QQuickView>
465+#include <QObject>
466 #include <friends.h>
467
468-class QQuickItem;
469-class QQmlEngine;
470-class QJSEngine;
471-
472 class FriendsUtilsQml : public QObject
473 {
474 Q_OBJECT
475
476=== modified file 'modules/Friends/plugin/plugin.cpp'
477--- modules/Friends/plugin/plugin.cpp 2013-02-09 15:33:54 +0000
478+++ modules/Friends/plugin/plugin.cpp 2013-03-20 13:31:31 +0000
479@@ -14,25 +14,23 @@
480 * along with this program. If not, see <http://www.gnu.org/licenses/>.
481 */
482
483-#include <QtQml>
484-#include <QtQml/QQmlContext>
485-
486-#include "plugin.h"
487 #include "friendsutils.h"
488 #include "friendsdispatcher.h"
489-
490-#include <glib-object.h>
491-#include <friends.h>
492+#include "streammodel.h"
493+#include "plugin.h"
494+
495+#include <QDebug>
496+#include <QQmlComponent>
497+
498
499 void FriendsPlugin::registerTypes(const char *uri)
500 {
501 Q_ASSERT(uri == QLatin1String("Friends"));
502
503+ qDebug() << Q_FUNC_INFO << uri;
504+
505 qmlRegisterType<FriendsUtilsQml>(uri, 0, 1, "FriendsUtils");
506 qmlRegisterType<FriendsDispatcherQml>(uri, 0, 1, "FriendsDispatcher");
507+ qmlRegisterType<StreamModel>(uri, 0, 1, "StreamModel");
508 }
509
510-void FriendsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
511-{
512- QQmlExtensionPlugin::initializeEngine(engine, uri);
513-}
514
515=== modified file 'modules/Friends/plugin/plugin.h'
516--- modules/Friends/plugin/plugin.h 2012-11-28 18:22:36 +0000
517+++ modules/Friends/plugin/plugin.h 2013-03-20 13:31:31 +0000
518@@ -17,8 +17,7 @@
519 #ifndef FRIENDS_PLUGIN_H
520 #define FRIENDS_PLUGIN_H
521
522-#include <QtQml/QQmlEngine>
523-#include <QtQml/QQmlExtensionPlugin>
524+#include <QQmlExtensionPlugin>
525
526 class FriendsPlugin : public QQmlExtensionPlugin
527 {
528@@ -27,7 +26,7 @@
529
530 public:
531 void registerTypes(const char *uri);
532- void initializeEngine(QQmlEngine *engine, const char *uri);
533 };
534+
535 #endif // FRIENDS_PLUGIN_H
536
537
538=== modified file 'modules/Friends/plugin/plugin.pro'
539--- modules/Friends/plugin/plugin.pro 2013-02-09 15:33:54 +0000
540+++ modules/Friends/plugin/plugin.pro 2013-03-20 13:31:31 +0000
541@@ -2,26 +2,28 @@
542
543 TEMPLATE = lib
544 TARGET = ../Friends
545-QT += qml quick
546+QT += qml
547 CONFIG += qt plugin no_keywords link_pkgconfig
548-PKGCONFIG += friends-0.1 gobject-2.0
549-
550+PKGCONFIG += friends-0.1 gobject-2.0 libdee-qt5
551 #comment in the following line to disable traces
552 #DEFINES += QT_NO_DEBUG_OUTPUT
553
554+QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
555+
556 TARGET = $$qtLibraryTarget($$TARGET)
557 uri = Friends
558
559 HEADERS += plugin.h \
560 friendsutils.h \
561- friendsdispatcher.h
562+ friendsdispatcher.h \
563+ streammodel.h
564
565 SOURCES += plugin.cpp \
566 friendsutils.cpp \
567- friendsdispatcher.cpp
568+ friendsdispatcher.cpp \
569+ streammodel.cpp
570
571 # deployment rules for the plugin
572 installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /)
573 target.path = $$installPath
574 INSTALLS += target
575-
576
577=== added file 'modules/Friends/plugin/streammodel.cpp'
578--- modules/Friends/plugin/streammodel.cpp 1970-01-01 00:00:00 +0000
579+++ modules/Friends/plugin/streammodel.cpp 2013-03-20 13:31:31 +0000
580@@ -0,0 +1,176 @@
581+#include <glib-object.h>
582+#include "streammodel.h"
583+#include <QDebug>
584+#include <QProcessEnvironment>
585+
586+class StreamModelPrivate: public DeeListModel
587+{
588+ Q_DECLARE_PUBLIC(StreamModel)
589+
590+public:
591+ StreamModelPrivate(StreamModel *model);
592+ ~StreamModelPrivate();
593+ static void onModelReady(GObject* parent, GParamSpec *pspec, StreamModelPrivate *q);
594+ void updateResults(StreamModelPrivate *d);
595+
596+private:
597+ mutable StreamModel *q_ptr;
598+ QString streamId = NULL;
599+ QString serviceId = NULL;
600+ uint accountId = 0;
601+ DeeModel* m_resultsModel;
602+ DeeModel* m_sharedModel;
603+ DeeModel* m_sortedModel;
604+};
605+
606+StreamModelPrivate::StreamModelPrivate(StreamModel *model):
607+ DeeListModel(model),
608+ q_ptr(model)
609+{
610+ qDebug() << Q_FUNC_INFO;
611+ QString modelName = "com.canonical.Friends.Streams";
612+ /* read environment variables */
613+ QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
614+ if (environment.contains(QLatin1String("FRIENDS_STREAMS_MODEL")))
615+ {
616+ modelName = environment.value(QLatin1String("FRIENDS_STREAMS_MODEL"));
617+ }
618+
619+ qDebug() << "MODEL: " << modelName;
620+
621+ m_sharedModel = dee_shared_model_new (modelName.toUtf8());
622+ m_resultsModel = m_sharedModel;
623+ m_sortedModel = dee_sequence_model_new ();
624+ g_signal_connect(m_sharedModel, "notify::synchronized", G_CALLBACK(onModelReady), this);
625+}
626+
627+void
628+StreamModelPrivate::onModelReady(GObject* parent __attribute__ ((unused)), GParamSpec *pspec, StreamModelPrivate *d)
629+{
630+ qDebug() << Q_FUNC_INFO;
631+ DeeModel *model = (DeeModel*)parent;
632+ DeeFilter _sort_filter;
633+ dee_filter_new_collator (8, &_sort_filter);
634+ d->m_sortedModel = dee_filter_model_new (model, &_sort_filter);
635+ qDebug() << Q_FUNC_INFO << " " << dee_model_get_n_rows (d->m_sortedModel);
636+ d->updateResults(d);
637+}
638+
639+void StreamModelPrivate::updateResults(StreamModelPrivate *d)
640+{
641+ /* Only updateResults if the model is populated */
642+ if (dee_model_get_n_rows (d->m_sortedModel) < 1) return;
643+
644+ if (d->streamId != NULL)
645+ {
646+ DeeFilter _key_filter;
647+ dee_filter_new_for_key_column (3, d->streamId.toUtf8().data(), &_key_filter);
648+ d->m_resultsModel = dee_filter_model_new (d->m_sortedModel, &_key_filter);
649+ } else
650+ {
651+ GRegex *regex;
652+ regex = g_regex_new ("^((?!reply_to).)*$", G_REGEX_FIRSTLINE, G_REGEX_MATCH_PARTIAL, NULL);
653+ DeeFilter _regex_filter;
654+ dee_filter_new_regex (3, regex, &_regex_filter);
655+ g_regex_unref (regex);
656+ d->m_resultsModel = dee_filter_model_new (d->m_sortedModel, &_regex_filter);
657+ }
658+ qDebug () << "STREAM: " << d->streamId << " ROWS: " << dee_model_get_n_rows (d->m_resultsModel);
659+
660+ if (d->serviceId != NULL)
661+ {
662+ DeeFilter _service_filter;
663+ dee_filter_new_for_key_column (0, d->serviceId.toUtf8().data(), &_service_filter);
664+ d->m_resultsModel = dee_filter_model_new (d->m_resultsModel, &_service_filter);
665+ }
666+ qDebug () << "SERVICE: " << d->serviceId << " ROWS: " << dee_model_get_n_rows (d->m_resultsModel);
667+
668+ if (d->accountId != 0)
669+ {
670+ DeeFilter _account_filter;
671+ dee_filter_new_for_any_column (1, g_variant_new_uint64(d->accountId), &_account_filter);
672+ d->m_resultsModel = dee_filter_model_new (d->m_resultsModel, &_account_filter);
673+ qDebug () << "ACCOUNT: " << d->accountId << " ROWS: " << dee_model_get_n_rows (d->m_resultsModel);
674+ }
675+
676+ q_ptr->setModel(m_resultsModel);
677+ Q_EMIT q_ptr->streamChanged();
678+}
679+
680+StreamModelPrivate::~StreamModelPrivate()
681+{
682+}
683+
684+StreamModel::StreamModel(DeeListModel *parent) :
685+ DeeListModel(parent),
686+ d_ptr(new StreamModelPrivate(this))
687+{
688+}
689+
690+StreamModel::~StreamModel()
691+{
692+}
693+
694+
695+void StreamModel::classBegin()
696+{
697+}
698+
699+void StreamModel::componentComplete()
700+{
701+}
702+
703+void StreamModel::setStream(const QString& streamId)
704+{
705+ Q_D(StreamModel);
706+ if (streamId == d->streamId) return;
707+ d->streamId = streamId;
708+ d->updateResults(d);
709+}
710+
711+/*!
712+ * \qmlproperty string StreamModel::stream
713+ * If set, the model will include only this stream
714+ */
715+QString StreamModel::stream() const
716+{
717+ Q_D(const StreamModel);
718+ return d->streamId;
719+}
720+
721+void StreamModel::setService(const QString& serviceId)
722+{
723+ Q_D(StreamModel);
724+ if (serviceId == d->serviceId) return;
725+ d->serviceId = serviceId;
726+ d->updateResults(d);
727+}
728+
729+/*!
730+ * \qmlproperty string StreamModel::service
731+ * If set, the model will include only this service
732+ */
733+QString StreamModel::service() const
734+{
735+ Q_D(const StreamModel);
736+ return d->serviceId;
737+}
738+
739+void StreamModel::setAccount(uint account)
740+{
741+ Q_D(StreamModel);
742+ if (account == d->accountId) return;
743+ d->accountId = account;
744+ d->updateResults(d);
745+ qDebug() << "Account: " << account;
746+}
747+
748+/*!
749+ * \qmlproperty string StreamModel::account
750+ * If set, the model will include only this account
751+ */
752+uint StreamModel::account() const
753+{
754+ Q_D(const StreamModel);
755+ return d->accountId;
756+}
757
758=== added file 'modules/Friends/plugin/streammodel.h'
759--- modules/Friends/plugin/streammodel.h 1970-01-01 00:00:00 +0000
760+++ modules/Friends/plugin/streammodel.h 2013-03-20 13:31:31 +0000
761@@ -0,0 +1,46 @@
762+#ifndef StreamModel_H
763+#define StreamModel_H
764+
765+
766+#include <QObject>
767+#include <QString>
768+#include <QQmlParserStatus>
769+#include <QQmlListProperty>
770+#include "deelistmodel.h"
771+#include <dee-1.0/dee.h>
772+
773+class StreamModelPrivate;
774+class StreamModel : public DeeListModel, public QQmlParserStatus
775+{
776+ Q_OBJECT
777+ Q_INTERFACES(QQmlParserStatus)
778+ Q_PROPERTY(QString stream READ stream WRITE setStream NOTIFY streamChanged)
779+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged)
780+ Q_PROPERTY(uint account READ account WRITE setAccount NOTIFY accountChanged)
781+
782+public:
783+ explicit StreamModel(DeeListModel *parent = 0);
784+ ~StreamModel();
785+
786+ void setStream(const QString& streamId);
787+ QString stream() const;
788+ void setService(const QString& serviceId);
789+ QString service() const;
790+ void setAccount(uint account);
791+ uint account() const;
792+ void classBegin();
793+ void componentComplete();
794+
795+
796+Q_SIGNALS:
797+ void streamChanged();
798+ void serviceChanged();
799+ void accountChanged();
800+
801+private:
802+ StreamModelPrivate* const d_ptr;
803+ Q_DECLARE_PRIVATE(StreamModel)
804+
805+};
806+
807+#endif // StreamModel_H
808
809=== added directory 'tests'
810=== added file 'tests/tests.pro'
811--- tests/tests.pro 1970-01-01 00:00:00 +0000
812+++ tests/tests.pro 2013-03-20 13:31:31 +0000
813@@ -0,0 +1,4 @@
814+TEMPLATE = subdirs
815+
816+SUBDIRS += \
817+ unit
818
819=== added directory 'tests/unit'
820=== added file 'tests/unit/main.cpp'
821--- tests/unit/main.cpp 1970-01-01 00:00:00 +0000
822+++ tests/unit/main.cpp 2013-03-20 13:31:31 +0000
823@@ -0,0 +1,2 @@
824+#include <QtQuickTest/quicktest.h>
825+QUICK_TEST_MAIN(unit)
826
827=== added file 'tests/unit/run.sh'
828--- tests/unit/run.sh 1970-01-01 00:00:00 +0000
829+++ tests/unit/run.sh 2013-03-20 13:31:31 +0000
830@@ -0,0 +1,7 @@
831+#!/bin/sh
832+
833+export FRIENDS_STREAMS_MODEL=com.canonical.Friends.TestSharedModel
834+export QML2_IMPORT_PATH=../../modules
835+
836+xvfb-run -a dbus-test-runner -t friends-dispatcher -p --test \
837+ --task-name FriendsService --ignore-return -t ./unit -m 120
838
839=== added file 'tests/unit/tst_test.qml'
840--- tests/unit/tst_test.qml 1970-01-01 00:00:00 +0000
841+++ tests/unit/tst_test.qml 2013-03-20 13:31:31 +0000
842@@ -0,0 +1,140 @@
843+import QtQuick 2.0
844+import QtTest 1.0
845+import Friends 0.1
846+
847+// See more details @ http://qt-project.org/doc/qt-5.0/qtquick/qml-testcase.html
848+
849+Item {
850+ // The objects
851+
852+ FriendsDispatcher {
853+ id: friends
854+ }
855+
856+ SignalSpy {
857+ id: signalSpy
858+ target: friends
859+ }
860+ TestCase {
861+ name: "testFriendsDispatcher"
862+
863+ function test_features () {
864+ var input = ["facebook"]
865+ var res = friends.featuresForProtocol (input[0]);
866+ compare (res, input);
867+ }
868+
869+ function test_uploadForAccountAsync () {
870+ var acct = 1;
871+ var uri = "file:///tmp/foo.png";
872+ var desc = "Something interesting to say";
873+ signalSpy.clear ();
874+ signalSpy.signalName = "onUploadComplete"
875+ friends.uploadForAccountAsync (acct, uri, desc)
876+ signalSpy.wait ();
877+ compare(1, signalSpy.count, "onUploadComplete emitted");
878+ }
879+
880+ function test_sendforAccountAsync () {
881+ var acct = 1;
882+ var msg = "Something interesting to say";
883+ signalSpy.clear ();
884+ signalSpy.signalName = "onSendComplete"
885+ friends.sendForAccountAsync (acct, msg)
886+ signalSpy.wait ();
887+ compare(1, signalSpy.count, "onSendComplete emitted");
888+ }
889+
890+ function test_sendAsync () {
891+ var msg = "Something interesting to say";
892+ signalSpy.clear ();
893+ signalSpy.signalName = "onSendComplete"
894+ friends.sendAsync (msg)
895+ signalSpy.wait ();
896+ compare(1, signalSpy.count, "onSendComplete emitted");
897+ }
898+
899+ function test_sendReplyAsync () {
900+ var acct = 1;
901+ var msgId = "10";
902+ var msg = "Something interesting to say";
903+ signalSpy.clear ();
904+ signalSpy.signalName = "onSendComplete"
905+ friends.sendReplyAsync (acct, msgId, msg)
906+ signalSpy.wait ();
907+ compare(1, signalSpy.count, "onSendComplete emitted");
908+ }
909+
910+ function test_retweetAsync () {
911+ var acct = 1;
912+ var msgId = "10";
913+ signalSpy.clear ();
914+ signalSpy.signalName = "onRetweetComplete"
915+ friends.retweetAsync (acct, msgId)
916+ signalSpy.wait ();
917+ compare(1, signalSpy.count, "onRetweetComplete emitted");
918+ }
919+
920+ function test_likeAsync () {
921+ var acct = 1;
922+ var msgId = "10";
923+ signalSpy.clear ();
924+ signalSpy.signalName = "onLikeComplete"
925+ friends.likeAsync (acct, msgId)
926+ signalSpy.wait ();
927+ compare(1, signalSpy.count, "onLikeComplete emitted");
928+ }
929+
930+ function test_unlikeAsync () {
931+ var acct = 1;
932+ var msgId = "10";
933+ signalSpy.clear ();
934+ signalSpy.signalName = "onUnlikeComplete"
935+ friends.unlikeAsync (acct, msgId)
936+ signalSpy.wait ();
937+ compare(1, signalSpy.count, "onUnlikeComplete emitted");
938+ }
939+ }
940+
941+ StreamModel {
942+ id: streamModel
943+ }
944+
945+ TestCase {
946+ name: "testStreamModel"
947+
948+ function init() {
949+ console.debug(">> init");
950+ console.debug("<< init");
951+ }
952+
953+ function cleanup() {
954+ console.debug(">> cleanup");
955+ console.debug("<< cleanup");
956+ }
957+
958+ function initTestCase() {
959+ console.debug(">> initTestCase");
960+ console.debug("<< initTestCase");
961+ }
962+
963+ function cleanupTestCase() {
964+ console.debug(">> cleanupTestCase");
965+ console.debug("<< cleanupTestCase");
966+ }
967+
968+ function test_streamModelStream() {
969+ streamModel.stream = "messages";
970+ compare(0, streamModel.count, "Test StreamModel row count filtered by stream");
971+ }
972+
973+ function test_streamModelService() {
974+ streamModel.service = "twitter";
975+ compare(0, streamModel.count, "Test StreamModel row count filtered by service");
976+ }
977+ function test_streamModelAccount() {
978+ streamModel.account = 1;
979+ compare(0, streamModel.count, "Test StreamModel row count filtered by account");
980+ }
981+ }
982+}
983
984=== added file 'tests/unit/unit.pro'
985--- tests/unit/unit.pro 1970-01-01 00:00:00 +0000
986+++ tests/unit/unit.pro 2013-03-20 13:31:31 +0000
987@@ -0,0 +1,13 @@
988+TEMPLATE = app
989+QT += qml quick qmltest
990+CONFIG += no_keywords
991+
992+TARGET = unit
993+SOURCES += main.cpp
994+
995+OTHER_FILES += $$system(ls *.qml)
996+check.commands = "sh run.sh"
997+check.depends = $${TARGET}
998+QMAKE_EXTRA_TARGETS += check
999+
1000+#system(cp $$PWD/*.qml $$OUT_PWD)

Subscribers

People subscribed via source and target branches

to all changes: