Merge lp:~renatofilho/buteo-syncfw-qml/initial-code into lp:~renatofilho/buteo-syncfw-qml/trunk
- initial-code
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Renato Araujo Oliveira Filho |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2 |
Proposed branch: | lp:~renatofilho/buteo-syncfw-qml/initial-code |
Merge into: | lp:~renatofilho/buteo-syncfw-qml/trunk |
Diff against target: |
1073 lines (+979/-0) 18 files modified
.bzr-builddeb/default.conf (+2/-0) Buteo/CMakeLists.txt (+39/-0) Buteo/buteo-sync-qml.cpp (+204/-0) Buteo/buteo-sync-qml.h (+181/-0) Buteo/plugin.cpp (+27/-0) Buteo/plugin.h (+31/-0) Buteo/qmldir (+2/-0) CMakeLists.txt (+30/-0) cmake_uninstall.cmake.in (+21/-0) debian/changelog (+5/-0) debian/compat (+1/-0) debian/control (+34/-0) debian/copyright (+19/-0) debian/rules (+9/-0) tests/CMakeLists.txt (+1/-0) tests/qml/CMakeLists.txt (+36/-0) tests/qml/buteo-syncfw.py (+163/-0) tests/qml/tst_ButeoSyncFW.qml (+174/-0) |
To merge this branch: | bzr merge lp:~renatofilho/buteo-syncfw-qml/initial-code |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Sheldon (community) | Approve | ||
Ken VanDine (community) | Needs Fixing | ||
Renato Araujo Oliveira Filho | Pending | ||
Review via email: mp+264160@code.launchpad.net |
Commit message
Implemented QML bindings for buteo syncfw DBUS service.
Description of the change
Server implementation can be found here: https:/
Michael Sheldon (michael-sheldon) wrote : | # |
Ken VanDine (ken-vandine) wrote : | # |
I pushed a few packaging fixes to lp:~ken-vandine/buteo-syncfw-qml/packaging_tweaks
Ken VanDine (ken-vandine) wrote : | # |
> Not sure if "gnome" is the best section for the package?
Agreed, but those sections aren't really all that useful these days. It seems all the apps with a GUI tend to go in "gnome", not opposed to changing that but also not really concerned.
Michael Sheldon (michael-sheldon) wrote : | # |
I'm not sure the reinitialization that's done after an owner change will work, see the diff comment for details
Michael Sheldon (michael-sheldon) wrote : | # |
Ah, no my mistake; presumably a call to deinitialize() will happen when the original owner is lost, which then calls reset on m_iface, so when the new owner appears it is null again.
Michael Sheldon (michael-sheldon) wrote : | # |
One small in-line comment added about one of the copyright statements, but otherwise the code for this all looks good to me.
Michael Sheldon (michael-sheldon) wrote : | # |
Looks good :)
- 2. By Renato Araujo Oliveira Filho
-
Implemented QML bindings for buteo syncfw DBUS service.
Preview Diff
1 | === added directory '.bzr-builddeb' | |||
2 | === added file '.bzr-builddeb/default.conf' | |||
3 | --- .bzr-builddeb/default.conf 1970-01-01 00:00:00 +0000 | |||
4 | +++ .bzr-builddeb/default.conf 2015-07-09 14:03:36 +0000 | |||
5 | @@ -0,0 +1,2 @@ | |||
6 | 1 | [BUILDDEB] | ||
7 | 2 | split = True | ||
8 | 0 | 3 | ||
9 | === added directory 'Buteo' | |||
10 | === added file 'Buteo/CMakeLists.txt' | |||
11 | --- Buteo/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
12 | +++ Buteo/CMakeLists.txt 2015-07-09 14:03:36 +0000 | |||
13 | @@ -0,0 +1,39 @@ | |||
14 | 1 | set(BUTEO_SYNC_QML_PLUGIN "buteo-syncfw-qml") | ||
15 | 2 | |||
16 | 3 | set(BUTEO_SYNC_QML_PLUGIN_SRCS | ||
17 | 4 | buteo-sync-qml.cpp | ||
18 | 5 | buteo-sync-qml.h | ||
19 | 6 | plugin.h | ||
20 | 7 | plugin.cpp | ||
21 | 8 | ) | ||
22 | 9 | |||
23 | 10 | set(BUTEO_SYNC_QML_PLUGIN_FILES | ||
24 | 11 | qmldir | ||
25 | 12 | ) | ||
26 | 13 | |||
27 | 14 | add_library(${BUTEO_SYNC_QML_PLUGIN} MODULE | ||
28 | 15 | ${BUTEO_SYNC_QML_PLUGIN_SRCS} | ||
29 | 16 | ) | ||
30 | 17 | |||
31 | 18 | target_link_libraries(${BUTEO_SYNC_QML_PLUGIN} | ||
32 | 19 | Qt5::Core | ||
33 | 20 | Qt5::Qml | ||
34 | 21 | Qt5::DBus | ||
35 | 22 | Qt5::Xml | ||
36 | 23 | ) | ||
37 | 24 | |||
38 | 25 | #copy qml files to build dir to make it possible to run without install | ||
39 | 26 | add_custom_target(buteo_components_QmlFiles ALL SOURCES ${BUTEO_SYNC_QML_PLUGIN_FILES}) | ||
40 | 27 | if(NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) | ||
41 | 28 | add_custom_command(TARGET buteo_components_QmlFiles PRE_BUILD | ||
42 | 29 | COMMAND ${CMAKE_COMMAND} -E | ||
43 | 30 | copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/) | ||
44 | 31 | endif() | ||
45 | 32 | |||
46 | 33 | execute_process( | ||
47 | 34 | COMMAND qmake -query QT_INSTALL_QML | ||
48 | 35 | OUTPUT_VARIABLE QT_IMPORTS_DIR | ||
49 | 36 | OUTPUT_STRIP_TRAILING_WHITESPACE | ||
50 | 37 | ) | ||
51 | 38 | install(TARGETS ${BUTEO_SYNC_QML_PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/Buteo/) | ||
52 | 39 | install(FILES ${BUTEO_SYNC_QML_PLUGIN_FILES} DESTINATION ${QT_IMPORTS_DIR}/Buteo/) | ||
53 | 0 | 40 | ||
54 | === added file 'Buteo/buteo-sync-qml.cpp' | |||
55 | --- Buteo/buteo-sync-qml.cpp 1970-01-01 00:00:00 +0000 | |||
56 | +++ Buteo/buteo-sync-qml.cpp 2015-07-09 14:03:36 +0000 | |||
57 | @@ -0,0 +1,204 @@ | |||
58 | 1 | /* | ||
59 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
60 | 3 | * | ||
61 | 4 | * This program is free software; you can redistribute it and/or modify | ||
62 | 5 | * it under the terms of the GNU General Public License as published by | ||
63 | 6 | * the Free Software Foundation; version 3. | ||
64 | 7 | * | ||
65 | 8 | * This program is distributed in the hope that it will be useful, | ||
66 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
67 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
68 | 11 | * GNU General Public License for more details. | ||
69 | 12 | * | ||
70 | 13 | * You should have received a copy of the GNU General Public License | ||
71 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
72 | 15 | */ | ||
73 | 16 | |||
74 | 17 | #include "buteo-sync-qml.h" | ||
75 | 18 | |||
76 | 19 | #include <QtCore/QDebug> | ||
77 | 20 | #include <QtDBus/QDBusInterface> | ||
78 | 21 | #include <QtDBus/QDBusReply> | ||
79 | 22 | #include <QtXml/QDomDocument> | ||
80 | 23 | |||
81 | 24 | #define BUTEO_DBUS_SERVICE_NAME "com.meego.msyncd" | ||
82 | 25 | #define BUTEO_DBUS_OBJECT_PATH "/synchronizer" | ||
83 | 26 | #define BUTEO_DBUS_INTERFACE "com.meego.msyncd" | ||
84 | 27 | |||
85 | 28 | ButeoSyncFW::ButeoSyncFW(QObject *parent) | ||
86 | 29 | : QObject(parent) | ||
87 | 30 | { | ||
88 | 31 | } | ||
89 | 32 | |||
90 | 33 | bool ButeoSyncFW::syncing() const | ||
91 | 34 | { | ||
92 | 35 | return !(getRunningSyncList().isEmpty()); | ||
93 | 36 | } | ||
94 | 37 | |||
95 | 38 | QStringList ButeoSyncFW::visibleSyncProfiles() const | ||
96 | 39 | { | ||
97 | 40 | if (m_iface) { | ||
98 | 41 | QDBusReply<QStringList> result = m_iface->call("allVisibleSyncProfiles"); | ||
99 | 42 | return result.value(); | ||
100 | 43 | } | ||
101 | 44 | return QStringList(); | ||
102 | 45 | } | ||
103 | 46 | |||
104 | 47 | void ButeoSyncFW::classBegin() | ||
105 | 48 | { | ||
106 | 49 | } | ||
107 | 50 | |||
108 | 51 | void ButeoSyncFW::componentComplete() | ||
109 | 52 | { | ||
110 | 53 | m_serviceWatcher.reset(new QDBusServiceWatcher(BUTEO_DBUS_SERVICE_NAME, | ||
111 | 54 | QDBusConnection::sessionBus(), | ||
112 | 55 | QDBusServiceWatcher::WatchForOwnerChange, | ||
113 | 56 | this)); | ||
114 | 57 | connect(m_serviceWatcher.data(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), | ||
115 | 58 | this, SLOT(serviceOwnerChanged(QString,QString,QString))); | ||
116 | 59 | |||
117 | 60 | initialize(); | ||
118 | 61 | } | ||
119 | 62 | |||
120 | 63 | void ButeoSyncFW::initialize() | ||
121 | 64 | { | ||
122 | 65 | if (!m_iface.isNull()) { | ||
123 | 66 | return; | ||
124 | 67 | } | ||
125 | 68 | |||
126 | 69 | m_iface.reset(new QDBusInterface(BUTEO_DBUS_SERVICE_NAME, | ||
127 | 70 | BUTEO_DBUS_OBJECT_PATH, | ||
128 | 71 | BUTEO_DBUS_INTERFACE)); | ||
129 | 72 | |||
130 | 73 | if (!m_iface->isValid()) { | ||
131 | 74 | m_iface.reset(); | ||
132 | 75 | qWarning() << "Fail to connect with syncfw"; | ||
133 | 76 | return; | ||
134 | 77 | } | ||
135 | 78 | |||
136 | 79 | connect(m_iface.data(), | ||
137 | 80 | SIGNAL(syncStatus(QString, int, QString, int)), | ||
138 | 81 | SIGNAL(syncStatus(QString, int, QString, int)), Qt::QueuedConnection); | ||
139 | 82 | connect(m_iface.data(), | ||
140 | 83 | SIGNAL(signalProfileChanged(QString, int, QString)), | ||
141 | 84 | SIGNAL(profileChanged(QString, int, QString)), Qt::QueuedConnection); | ||
142 | 85 | |||
143 | 86 | // notify changes on properties | ||
144 | 87 | emit syncStatus("", 0, "", 0); | ||
145 | 88 | emit profileChanged("", 0, ""); | ||
146 | 89 | } | ||
147 | 90 | |||
148 | 91 | bool ButeoSyncFW::startSync(const QString &aProfileId) const | ||
149 | 92 | { | ||
150 | 93 | if (m_iface) { | ||
151 | 94 | QDBusReply<bool> result = m_iface->call("startSync", aProfileId); | ||
152 | 95 | return result.value(); | ||
153 | 96 | } | ||
154 | 97 | return false; | ||
155 | 98 | } | ||
156 | 99 | |||
157 | 100 | bool ButeoSyncFW::startSyncByCategory(const QString &category) const | ||
158 | 101 | { | ||
159 | 102 | foreach(const QString &profile, syncProfilesByCategory(category)) { | ||
160 | 103 | if (!startSync(profile)) { | ||
161 | 104 | return false; | ||
162 | 105 | } | ||
163 | 106 | } | ||
164 | 107 | return true; | ||
165 | 108 | } | ||
166 | 109 | |||
167 | 110 | void ButeoSyncFW::abortSync(const QString &aProfileId) const | ||
168 | 111 | { | ||
169 | 112 | if (m_iface) { | ||
170 | 113 | m_iface->call("abortSync", aProfileId); | ||
171 | 114 | } | ||
172 | 115 | } | ||
173 | 116 | |||
174 | 117 | QStringList ButeoSyncFW::getRunningSyncList() const | ||
175 | 118 | { | ||
176 | 119 | if (m_iface) { | ||
177 | 120 | QDBusReply<QStringList> syncList = m_iface->call("runningSyncs"); | ||
178 | 121 | return syncList; | ||
179 | 122 | } | ||
180 | 123 | return QStringList(); | ||
181 | 124 | } | ||
182 | 125 | |||
183 | 126 | QStringList ButeoSyncFW::syncProfilesByCategory(const QString &category) const | ||
184 | 127 | { | ||
185 | 128 | if (m_iface) { | ||
186 | 129 | QDBusReply<QStringList> profiles = m_iface->call("syncProfilesByKey", "category", category); | ||
187 | 130 | // extract ids | ||
188 | 131 | QStringList ids; | ||
189 | 132 | foreach(const QString &profile, profiles.value()) { | ||
190 | 133 | QDomDocument doc; | ||
191 | 134 | QString errorMsg; | ||
192 | 135 | int errorLine; | ||
193 | 136 | int errorColumn; | ||
194 | 137 | if (doc.setContent(profile, &errorMsg, &errorLine, &errorColumn)) { | ||
195 | 138 | QDomNodeList profileElements = doc.elementsByTagName("profile"); | ||
196 | 139 | if (!profileElements.isEmpty()) { | ||
197 | 140 | //check if is enabled | ||
198 | 141 | QDomElement e = profileElements.item(0).toElement(); | ||
199 | 142 | QDomNodeList values = e.elementsByTagName("key"); | ||
200 | 143 | bool enabled = true; | ||
201 | 144 | for(int i = 0; i < values.count(); i++) { | ||
202 | 145 | QDomElement v = values.at(i).toElement(); | ||
203 | 146 | if ((v.attribute("name") == "enabled") && | ||
204 | 147 | (v.attribute("value") == "false")) { | ||
205 | 148 | enabled = false; | ||
206 | 149 | continue; | ||
207 | 150 | } | ||
208 | 151 | } | ||
209 | 152 | if (!enabled) { | ||
210 | 153 | continue; | ||
211 | 154 | } | ||
212 | 155 | QString profileName = e.attribute("name", ""); | ||
213 | 156 | if (!profileName.isEmpty()) { | ||
214 | 157 | ids << profileName; | ||
215 | 158 | } else { | ||
216 | 159 | qWarning() << "Profile name is empty in:" << profile; | ||
217 | 160 | } | ||
218 | 161 | } else { | ||
219 | 162 | qWarning() << "Profile not found in:" << profile; | ||
220 | 163 | } | ||
221 | 164 | } else { | ||
222 | 165 | qWarning() << "Fail to parse profile:" << profile; | ||
223 | 166 | qWarning() << "Error:" << errorMsg << errorLine << errorColumn; | ||
224 | 167 | } | ||
225 | 168 | } | ||
226 | 169 | return ids; | ||
227 | 170 | } | ||
228 | 171 | return QStringList(); | ||
229 | 172 | } | ||
230 | 173 | |||
231 | 174 | bool ButeoSyncFW::removeProfile(const QString &profileId) const | ||
232 | 175 | { | ||
233 | 176 | if (m_iface) { | ||
234 | 177 | QDBusReply<bool> result = m_iface->call("removeProfile", profileId); | ||
235 | 178 | return result; | ||
236 | 179 | } | ||
237 | 180 | return false; | ||
238 | 181 | } | ||
239 | 182 | |||
240 | 183 | void ButeoSyncFW::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) | ||
241 | 184 | { | ||
242 | 185 | Q_UNUSED(oldOwner); | ||
243 | 186 | |||
244 | 187 | if (name == BUTEO_DBUS_SERVICE_NAME) { | ||
245 | 188 | if (!newOwner.isEmpty()) { | ||
246 | 189 | // service appear | ||
247 | 190 | initialize(); | ||
248 | 191 | } else if (!m_iface.isNull()) { | ||
249 | 192 | // lost service | ||
250 | 193 | deinitialize(); | ||
251 | 194 | } | ||
252 | 195 | } | ||
253 | 196 | } | ||
254 | 197 | |||
255 | 198 | void ButeoSyncFW::deinitialize() | ||
256 | 199 | { | ||
257 | 200 | m_iface.reset(); | ||
258 | 201 | // notify changes on properties | ||
259 | 202 | emit syncStatus("", 0, "", 0); | ||
260 | 203 | emit profileChanged("", 0, ""); | ||
261 | 204 | } | ||
262 | 0 | 205 | ||
263 | === added file 'Buteo/buteo-sync-qml.h' | |||
264 | --- Buteo/buteo-sync-qml.h 1970-01-01 00:00:00 +0000 | |||
265 | +++ Buteo/buteo-sync-qml.h 2015-07-09 14:03:36 +0000 | |||
266 | @@ -0,0 +1,181 @@ | |||
267 | 1 | /* | ||
268 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
269 | 3 | * | ||
270 | 4 | * This program is free software; you can redistribute it and/or modify | ||
271 | 5 | * it under the terms of the GNU General Public License as published by | ||
272 | 6 | * the Free Software Foundation; version 3. | ||
273 | 7 | * | ||
274 | 8 | * This program is distributed in the hope that it will be useful, | ||
275 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
276 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
277 | 11 | * GNU General Public License for more details. | ||
278 | 12 | * | ||
279 | 13 | * You should have received a copy of the GNU General Public License | ||
280 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
281 | 15 | */ | ||
282 | 16 | |||
283 | 17 | #include <QtCore/QObject> | ||
284 | 18 | #include <QtQml/QQmlParserStatus> | ||
285 | 19 | #include <QtDBus/QDBusInterface> | ||
286 | 20 | #include <QtDBus/QDBusServiceWatcher> | ||
287 | 21 | |||
288 | 22 | class ButeoSyncFW : public QObject, public QQmlParserStatus | ||
289 | 23 | { | ||
290 | 24 | Q_OBJECT | ||
291 | 25 | Q_INTERFACES(QQmlParserStatus) | ||
292 | 26 | |||
293 | 27 | Q_PROPERTY(bool syncing READ syncing NOTIFY syncStatus) | ||
294 | 28 | Q_PROPERTY(QStringList visibleSyncProfiles READ visibleSyncProfiles NOTIFY profileChanged) | ||
295 | 29 | |||
296 | 30 | public: | ||
297 | 31 | ButeoSyncFW(QObject *parent = 0); | ||
298 | 32 | |||
299 | 33 | bool syncing() const; | ||
300 | 34 | QStringList visibleSyncProfiles() const; | ||
301 | 35 | |||
302 | 36 | // QQmlParserStatus | ||
303 | 37 | void classBegin(); | ||
304 | 38 | void componentComplete(); | ||
305 | 39 | |||
306 | 40 | //! \brief Enum to indicate the change type of the Profile Operation | ||
307 | 41 | enum ProfileChangeType | ||
308 | 42 | { | ||
309 | 43 | //! a New Profile has been added | ||
310 | 44 | ProfileAdded = 0, | ||
311 | 45 | //! a Existing Profile has been modified | ||
312 | 46 | ProfileModified, | ||
313 | 47 | //! Profile has been Removed | ||
314 | 48 | ProfileRemoved, | ||
315 | 49 | //! Profile log file Modified. | ||
316 | 50 | ProfileLogsModified | ||
317 | 51 | }; | ||
318 | 52 | Q_ENUMS(ProfileChangeType) | ||
319 | 53 | |||
320 | 54 | //! \brief Enum to indicate the change type of the Profile Operation | ||
321 | 55 | enum SyncStatus | ||
322 | 56 | { | ||
323 | 57 | //! Sync request has been queued | ||
324 | 58 | SyncQueued = 0, | ||
325 | 59 | //! Sync session has been started | ||
326 | 60 | SyncStarted, | ||
327 | 61 | //! Sync session is progressing | ||
328 | 62 | SyncProgress, | ||
329 | 63 | //! Sync session has encountered an error | ||
330 | 64 | SyncError, | ||
331 | 65 | //! Sync session was successfully completed | ||
332 | 66 | SyncDone, | ||
333 | 67 | //! Sync session was aborted | ||
334 | 68 | SyncAborted | ||
335 | 69 | }; | ||
336 | 70 | Q_ENUMS(SyncStatus) | ||
337 | 71 | |||
338 | 72 | signals: | ||
339 | 73 | /*! \brief Notifies about a change in profile. | ||
340 | 74 | * | ||
341 | 75 | * This signal is sent when the profile data is modified or when a profile | ||
342 | 76 | * is added or deleted in msyncd. | ||
343 | 77 | * \param aProfileId Id of the changed profile. | ||
344 | 78 | * \param aChangeType | ||
345 | 79 | * 0 (ADDITION): Profile was added. | ||
346 | 80 | * 1 (MODIFICATION): Profile was modified. | ||
347 | 81 | * 2 (DELETION): Profile was deleted. | ||
348 | 82 | * \param aChangedProfile changed sync profie as XMl string. | ||
349 | 83 | * | ||
350 | 84 | */ | ||
351 | 85 | void profileChanged(QString aProfileId,int aChangeType, QString aChangedProfile); | ||
352 | 86 | |||
353 | 87 | /*! | ||
354 | 88 | * \brief Notifies about a change in synchronization status. | ||
355 | 89 | * | ||
356 | 90 | * \param aProfileId Id of the profile used in the sync session whose | ||
357 | 91 | * status has changed. | ||
358 | 92 | * \param aStatus The new status. One of the following: | ||
359 | 93 | * 0 (QUEUED): Sync request has been queued or was already in the | ||
360 | 94 | * queue when sync start was requested. | ||
361 | 95 | * 1 (STARTED): Sync session has been started. | ||
362 | 96 | * 2 (PROGRESS): Sync session is progressing. | ||
363 | 97 | * 3 (ERROR): Sync session has encountered an error and has been stopped, | ||
364 | 98 | * or the session could not be started at all. | ||
365 | 99 | * 4 (DONE): Sync session was successfully completed. | ||
366 | 100 | * 5 (ABORTED): Sync session was aborted. | ||
367 | 101 | * Statuses 3-5 are final, no more status changes will be sent from the | ||
368 | 102 | * same sync session. | ||
369 | 103 | * \param aMessage A message describing the status change in detail. This | ||
370 | 104 | * can for example be shown to the user or written to a log | ||
371 | 105 | * \param aStatusDetails | ||
372 | 106 | * When aStatus is ERROR, this parameter contains a specific error code. | ||
373 | 107 | * When aStatus is PROGRESS, this parameter contains more details about the progress | ||
374 | 108 | * \see SyncCommonDefs::SyncProgressDetails | ||
375 | 109 | */ | ||
376 | 110 | void syncStatus(QString aProfileId, int aStatus, | ||
377 | 111 | QString aMessage, int aStatusDetails); | ||
378 | 112 | |||
379 | 113 | public slots: | ||
380 | 114 | /*! | ||
381 | 115 | * \brief Requests to starts synchronizing using a profile Id | ||
382 | 116 | * | ||
383 | 117 | * A status change signal (QUEUED, STARTED or ERROR) will be sent by the | ||
384 | 118 | * daemon when the request is processed. If there is a sync already in | ||
385 | 119 | * progress using the same resources that are needed by the given profile, | ||
386 | 120 | * adds the sync request to a sync queue. Otherwise a sync session is | ||
387 | 121 | * started immediately. | ||
388 | 122 | * | ||
389 | 123 | * \param aProfileId Id of the profile to use in sync. | ||
390 | 124 | * \return True if a profile with the Id was found. Otherwise | ||
391 | 125 | * false and no status change signals will follow from this request. | ||
392 | 126 | */ | ||
393 | 127 | bool startSync(const QString &aProfileId) const; | ||
394 | 128 | |||
395 | 129 | /*! | ||
396 | 130 | * \brief Requests to starts synchronizing using a profile category | ||
397 | 131 | * | ||
398 | 132 | * \param category Category name of the profile. | ||
399 | 133 | * \return True if a profile with the Id was found. Otherwise | ||
400 | 134 | * false and no status change signals will follow from this request. | ||
401 | 135 | * | ||
402 | 136 | * \see ButeoSyncFW::startSync | ||
403 | 137 | */ | ||
404 | 138 | bool startSyncByCategory(const QString &category) const; | ||
405 | 139 | |||
406 | 140 | /*! | ||
407 | 141 | * \brief Stops synchronizing the profile with the given Id. | ||
408 | 142 | * | ||
409 | 143 | * If the sync request is still in queue and not yet started, the queue | ||
410 | 144 | * entry is removed. | ||
411 | 145 | * | ||
412 | 146 | * \param aProfileId Id of the profile to stop syncing. | ||
413 | 147 | */ | ||
414 | 148 | void abortSync(const QString &aProfileId) const; | ||
415 | 149 | |||
416 | 150 | /*! | ||
417 | 151 | * \brief Gets the list of profile names of currently running syncs. | ||
418 | 152 | * | ||
419 | 153 | * \return Profile name list. | ||
420 | 154 | */ | ||
421 | 155 | QStringList getRunningSyncList() const; | ||
422 | 156 | |||
423 | 157 | /*! \brief Gets enabled profiles matching the profile category. | ||
424 | 158 | * | ||
425 | 159 | * \param category Category name of the profile. | ||
426 | 160 | * \return The sync profile ids as string list. | ||
427 | 161 | */ | ||
428 | 162 | QStringList syncProfilesByCategory(const QString &category) const; | ||
429 | 163 | |||
430 | 164 | /*! | ||
431 | 165 | * \brief This function should be called when sync profile has to be deleted | ||
432 | 166 | * | ||
433 | 167 | * \param aProfileId Id of the profile to be deleted. | ||
434 | 168 | * \return status of the remove operation | ||
435 | 169 | */ | ||
436 | 170 | bool removeProfile(const QString &profileId) const; | ||
437 | 171 | |||
438 | 172 | private slots: | ||
439 | 173 | void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); | ||
440 | 174 | |||
441 | 175 | private: | ||
442 | 176 | QScopedPointer<QDBusInterface> m_iface; | ||
443 | 177 | QScopedPointer<QDBusServiceWatcher> m_serviceWatcher; | ||
444 | 178 | |||
445 | 179 | void initialize(); | ||
446 | 180 | void deinitialize(); | ||
447 | 181 | }; | ||
448 | 0 | 182 | ||
449 | === added file 'Buteo/plugin.cpp' | |||
450 | --- Buteo/plugin.cpp 1970-01-01 00:00:00 +0000 | |||
451 | +++ Buteo/plugin.cpp 2015-07-09 14:03:36 +0000 | |||
452 | @@ -0,0 +1,27 @@ | |||
453 | 1 | /* | ||
454 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
455 | 3 | * | ||
456 | 4 | * This program is free software; you can redistribute it and/or modify | ||
457 | 5 | * it under the terms of the GNU General Public License as published by | ||
458 | 6 | * the Free Software Foundation; version 3. | ||
459 | 7 | * | ||
460 | 8 | * This program is distributed in the hope that it will be useful, | ||
461 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
462 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
463 | 11 | * GNU General Public License for more details. | ||
464 | 12 | * | ||
465 | 13 | * You should have received a copy of the GNU General Public License | ||
466 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
467 | 15 | */ | ||
468 | 16 | |||
469 | 17 | #include "plugin.h" | ||
470 | 18 | #include "buteo-sync-qml.h" | ||
471 | 19 | |||
472 | 20 | #include <QtQml/qqml.h> | ||
473 | 21 | |||
474 | 22 | |||
475 | 23 | void ButeoSyncQmlPlugin::registerTypes(const char *uri) | ||
476 | 24 | { | ||
477 | 25 | // @uri Buteo.ButeoSync | ||
478 | 26 | qmlRegisterType<ButeoSyncFW>(uri, 0, 1, "ButeoSync"); | ||
479 | 27 | } | ||
480 | 0 | 28 | ||
481 | === added file 'Buteo/plugin.h' | |||
482 | --- Buteo/plugin.h 1970-01-01 00:00:00 +0000 | |||
483 | +++ Buteo/plugin.h 2015-07-09 14:03:36 +0000 | |||
484 | @@ -0,0 +1,31 @@ | |||
485 | 1 | /* | ||
486 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
487 | 3 | * | ||
488 | 4 | * This program is free software; you can redistribute it and/or modify | ||
489 | 5 | * it under the terms of the GNU General Public License as published by | ||
490 | 6 | * the Free Software Foundation; version 3. | ||
491 | 7 | * | ||
492 | 8 | * This program is distributed in the hope that it will be useful, | ||
493 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
494 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
495 | 11 | * GNU General Public License for more details. | ||
496 | 12 | * | ||
497 | 13 | * You should have received a copy of the GNU General Public License | ||
498 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
499 | 15 | */ | ||
500 | 16 | |||
501 | 17 | #ifndef BUTE_SYNC_FW_QML_PLUGIN_H | ||
502 | 18 | #define BUTE_SYNC_FW_QML_PLUGIN_H | ||
503 | 19 | |||
504 | 20 | #include <QQmlExtensionPlugin> | ||
505 | 21 | |||
506 | 22 | class ButeoSyncQmlPlugin : public QQmlExtensionPlugin | ||
507 | 23 | { | ||
508 | 24 | Q_OBJECT | ||
509 | 25 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") | ||
510 | 26 | |||
511 | 27 | public: | ||
512 | 28 | void registerTypes(const char *uri); | ||
513 | 29 | }; | ||
514 | 30 | |||
515 | 31 | #endif //BUTE_SYNC_FW_QML_PLUGIN_H | ||
516 | 0 | 32 | ||
517 | === added file 'Buteo/qmldir' | |||
518 | --- Buteo/qmldir 1970-01-01 00:00:00 +0000 | |||
519 | +++ Buteo/qmldir 2015-07-09 14:03:36 +0000 | |||
520 | @@ -0,0 +1,2 @@ | |||
521 | 1 | module Buteo | ||
522 | 2 | plugin buteo-syncfw-qml | ||
523 | 0 | 3 | ||
524 | === added file 'CMakeLists.txt' | |||
525 | --- CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
526 | +++ CMakeLists.txt 2015-07-09 14:03:36 +0000 | |||
527 | @@ -0,0 +1,30 @@ | |||
528 | 1 | project(buteo-sync-qml) | ||
529 | 2 | |||
530 | 3 | cmake_minimum_required(VERSION 2.8.9) | ||
531 | 4 | |||
532 | 5 | # Find includes in corresponding build directories | ||
533 | 6 | set(CMAKE_INCLUDE_CURRENT_DIR ON) | ||
534 | 7 | |||
535 | 8 | # Instruct CMake to run moc automatically when needed. | ||
536 | 9 | set(CMAKE_AUTOMOC ON) | ||
537 | 10 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQT_QML_DEBUG") | ||
538 | 11 | |||
539 | 12 | # Standard install paths | ||
540 | 13 | include(GNUInstallDirs) | ||
541 | 14 | |||
542 | 15 | find_package(PkgConfig REQUIRED) | ||
543 | 16 | find_package(Qt5Core REQUIRED) | ||
544 | 17 | find_package(Qt5Qml REQUIRED) | ||
545 | 18 | find_package(Qt5DBus REQUIRED) | ||
546 | 19 | find_package(Qt5Xml REQUIRED) | ||
547 | 20 | |||
548 | 21 | enable_testing() | ||
549 | 22 | add_subdirectory(Buteo) | ||
550 | 23 | add_subdirectory(tests) | ||
551 | 24 | |||
552 | 25 | # uninstall target | ||
553 | 26 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" | ||
554 | 27 | "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" | ||
555 | 28 | IMMEDIATE @ONLY) | ||
556 | 29 | add_custom_target(uninstall "${CMAKE_COMMAND}" | ||
557 | 30 | -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") | ||
558 | 0 | 31 | ||
559 | === added file 'cmake_uninstall.cmake.in' | |||
560 | --- cmake_uninstall.cmake.in 1970-01-01 00:00:00 +0000 | |||
561 | +++ cmake_uninstall.cmake.in 2015-07-09 14:03:36 +0000 | |||
562 | @@ -0,0 +1,21 @@ | |||
563 | 1 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") | ||
564 | 2 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") | ||
565 | 3 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") | ||
566 | 4 | |||
567 | 5 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) | ||
568 | 6 | STRING(REGEX REPLACE "\n" ";" files "${files}") | ||
569 | 7 | FOREACH(file ${files}) | ||
570 | 8 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") | ||
571 | 9 | IF(EXISTS "$ENV{DESTDIR}${file}") | ||
572 | 10 | EXEC_PROGRAM( | ||
573 | 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" | ||
574 | 12 | OUTPUT_VARIABLE rm_out | ||
575 | 13 | RETURN_VALUE rm_retval | ||
576 | 14 | ) | ||
577 | 15 | IF(NOT "${rm_retval}" STREQUAL 0) | ||
578 | 16 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") | ||
579 | 17 | ENDIF(NOT "${rm_retval}" STREQUAL 0) | ||
580 | 18 | ELSE(EXISTS "$ENV{DESTDIR}${file}") | ||
581 | 19 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") | ||
582 | 20 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") | ||
583 | 21 | ENDFOREACH(file) | ||
584 | 0 | 22 | ||
585 | === added directory 'debian' | |||
586 | === added file 'debian/changelog' | |||
587 | --- debian/changelog 1970-01-01 00:00:00 +0000 | |||
588 | +++ debian/changelog 2015-07-09 14:03:36 +0000 | |||
589 | @@ -0,0 +1,5 @@ | |||
590 | 1 | buteo-syncfw-qml (0.1-0ubuntu1) vivid; urgency=medium | ||
591 | 2 | |||
592 | 3 | * New package | ||
593 | 4 | |||
594 | 5 | -- Renato Araujo Oliveira Filho <renato.filho@canonical.com> Wed, 08 Jul 2015 12:01:34 -0300 | ||
595 | 0 | 6 | ||
596 | === added file 'debian/compat' | |||
597 | --- debian/compat 1970-01-01 00:00:00 +0000 | |||
598 | +++ debian/compat 2015-07-09 14:03:36 +0000 | |||
599 | @@ -0,0 +1,1 @@ | |||
600 | 1 | 9 | ||
601 | 0 | 2 | ||
602 | === added file 'debian/control' | |||
603 | --- debian/control 1970-01-01 00:00:00 +0000 | |||
604 | +++ debian/control 2015-07-09 14:03:36 +0000 | |||
605 | @@ -0,0 +1,34 @@ | |||
606 | 1 | Source: buteo-syncfw-qml | ||
607 | 2 | Section: libs | ||
608 | 3 | Priority: optional | ||
609 | 4 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> | ||
610 | 5 | Build-Depends: cmake, | ||
611 | 6 | dbus-test-runner, | ||
612 | 7 | debhelper (>= 9), | ||
613 | 8 | pkg-config, | ||
614 | 9 | qml-module-qttest, | ||
615 | 10 | qtchooser, | ||
616 | 11 | qt5-default, | ||
617 | 12 | qtbase5-dev, | ||
618 | 13 | qtdeclarative5-dev, | ||
619 | 14 | Standards-Version: 3.9.5 | ||
620 | 15 | Homepage: https://launchpad.net/buteo-syncfw-qml | ||
621 | 16 | # if you don't have have commit access to this branch but would like to upload | ||
622 | 17 | # directly to Ubuntu, don't worry: your changes will be merged back into the | ||
623 | 18 | # upstream branch | ||
624 | 19 | Vcs-Bzr: lp:buteo-syncfw-qml | ||
625 | 20 | X-Ubuntu-Use-Langpack: yes | ||
626 | 21 | |||
627 | 22 | Package: qtdeclarative5-buteo-syncfw0.1 | ||
628 | 23 | Architecture: any | ||
629 | 24 | Multi-Arch: same | ||
630 | 25 | Pre-Depends: ${misc:Pre-Depends} | ||
631 | 26 | Depends: ${misc:Depends}, | ||
632 | 27 | ${shlibs:Depends}, | ||
633 | 28 | buteo-syncfw-qt5, | ||
634 | 29 | Description: Buteo sync framework client - QML bindings | ||
635 | 30 | buteo-syncfw manages data synchronization | ||
636 | 31 | . | ||
637 | 32 | This package contains the QML plugin providing the features from the buteo | ||
638 | 33 | to applications. | ||
639 | 34 | |||
640 | 0 | 35 | ||
641 | === added file 'debian/copyright' | |||
642 | --- debian/copyright 1970-01-01 00:00:00 +0000 | |||
643 | +++ debian/copyright 2015-07-09 14:03:36 +0000 | |||
644 | @@ -0,0 +1,19 @@ | |||
645 | 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | ||
646 | 2 | Source: https://launchpad.net/buteo-syncfw-qml | ||
647 | 3 | Upstream-Name: buteo-syncfw-qml | ||
648 | 4 | |||
649 | 5 | Files: * | ||
650 | 6 | Copyright: 2015 Canonical Ltd. | ||
651 | 7 | License: GPL-3 | ||
652 | 8 | This program is free software: you can redistribute it and/or modify | ||
653 | 9 | it under the terms of the GNU General Public License version 3 as | ||
654 | 10 | published by the Free Software Foundation. | ||
655 | 11 | . | ||
656 | 12 | This program is distributed in the hope that it will be useful, | ||
657 | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
658 | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
659 | 15 | GNU General Public License for more details. | ||
660 | 16 | . | ||
661 | 17 | On Debian systems, the full text of the GNU General Public | ||
662 | 18 | License version 3 can be found in the file | ||
663 | 19 | `/usr/share/common-licenses/GPL-3'. | ||
664 | 0 | 20 | ||
665 | === added file 'debian/rules' | |||
666 | --- debian/rules 1970-01-01 00:00:00 +0000 | |||
667 | +++ debian/rules 2015-07-09 14:03:36 +0000 | |||
668 | @@ -0,0 +1,9 @@ | |||
669 | 1 | #!/usr/bin/make -f | ||
670 | 2 | # -*- makefile -*- | ||
671 | 3 | export DPKG_GENSYMBOLS_CHECK_LEVEL=4 | ||
672 | 4 | |||
673 | 5 | # Uncomment this to turn on verbose mode. | ||
674 | 6 | #export DH_VERBOSE=1 | ||
675 | 7 | |||
676 | 8 | %: | ||
677 | 9 | dh $@ --parallel --fail-missing | ||
678 | 0 | 10 | ||
679 | === added directory 'tests' | |||
680 | === added file 'tests/CMakeLists.txt' | |||
681 | --- tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
682 | +++ tests/CMakeLists.txt 2015-07-09 14:03:36 +0000 | |||
683 | @@ -0,0 +1,1 @@ | |||
684 | 1 | add_subdirectory(qml) | ||
685 | 0 | 2 | ||
686 | === added directory 'tests/qml' | |||
687 | === added file 'tests/qml/CMakeLists.txt' | |||
688 | --- tests/qml/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
689 | +++ tests/qml/CMakeLists.txt 2015-07-09 14:03:36 +0000 | |||
690 | @@ -0,0 +1,36 @@ | |||
691 | 1 | find_program(QMLTESTRUNNER_BIN | ||
692 | 2 | NAMES qmltestrunner | ||
693 | 3 | PATHS /usr/lib/*/qt5/bin | ||
694 | 4 | NO_DEFAULT_PATH | ||
695 | 5 | ) | ||
696 | 6 | |||
697 | 7 | find_program(DBUS_RUNNER_BIN dbus-test-runner) | ||
698 | 8 | macro(DECLARE_QML_TEST TST_NAME TST_QML_FILE) | ||
699 | 9 | set(TEST_COMMAND "") | ||
700 | 10 | add_test(NAME ${TST_NAME} | ||
701 | 11 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | ||
702 | 12 | COMMAND ${DBUS_RUNNER_BIN} | ||
703 | 13 | --task ${CMAKE_CURRENT_SOURCE_DIR}/buteo-syncfw.py -r -n buteo-syncfw | ||
704 | 14 | --task ${QMLTESTRUNNER_BIN} | ||
705 | 15 | -p -input -p ${CMAKE_CURRENT_SOURCE_DIR}/${TST_QML_FILE} | ||
706 | 16 | -p -import -p ${CMAKE_BINARY_DIR} | ||
707 | 17 | -p -platform -p offscreen | ||
708 | 18 | --wait-for=com.meego.msyncd | ||
709 | 19 | -n ${TST_NAME} | ||
710 | 20 | ) | ||
711 | 21 | endmacro() | ||
712 | 22 | |||
713 | 23 | if(QMLTESTRUNNER_BIN AND DBUS_RUNNER_BIN) | ||
714 | 24 | declare_qml_test("buteo_syncfw_component" tst_ButeoSyncFW.qml) | ||
715 | 25 | else() | ||
716 | 26 | if (NOT QMLTESTRUNNER_BIN) | ||
717 | 27 | message(WARNING "Qml tests disabled: qmltestrunner not found") | ||
718 | 28 | else() | ||
719 | 29 | message(WARNING "Qml tests disabled: dbus-test-runner not found") | ||
720 | 30 | endif() | ||
721 | 31 | endif() | ||
722 | 32 | |||
723 | 33 | set(QML_TST_FILES | ||
724 | 34 | tst_ButeoSyncFW.qml | ||
725 | 35 | ) | ||
726 | 36 | add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES}) | ||
727 | 0 | 37 | ||
728 | === added file 'tests/qml/buteo-syncfw.py' | |||
729 | --- tests/qml/buteo-syncfw.py 1970-01-01 00:00:00 +0000 | |||
730 | +++ tests/qml/buteo-syncfw.py 2015-07-09 14:03:36 +0000 | |||
731 | @@ -0,0 +1,163 @@ | |||
732 | 1 | #!/usr/bin/python3 | ||
733 | 2 | |||
734 | 3 | '''buteo syncfw mock template | ||
735 | 4 | |||
736 | 5 | This creates the expected methods and properties of the main | ||
737 | 6 | com.meego.msyncd object. You can specify D-BUS property values | ||
738 | 7 | ''' | ||
739 | 8 | |||
740 | 9 | # This program is free software; you can redistribute it and/or modify it under | ||
741 | 10 | # the terms of the GNU Lesser General Public License as published by the Free | ||
742 | 11 | # Software Foundation; either version 3 of the License, or (at your option) any | ||
743 | 12 | # later version. See http://www.gnu.org/copyleft/lgpl.html for the full text | ||
744 | 13 | # of the license. | ||
745 | 14 | |||
746 | 15 | __author__ = 'Renato Araujo Oliveira Filho' | ||
747 | 16 | __email__ = 'renatofilho@canonical.com' | ||
748 | 17 | __copyright__ = '(c) 2015 Canonical Ltd.' | ||
749 | 18 | __license__ = 'LGPL 3+' | ||
750 | 19 | |||
751 | 20 | import dbus | ||
752 | 21 | from gi.repository import GObject | ||
753 | 22 | |||
754 | 23 | import dbus | ||
755 | 24 | import dbus.service | ||
756 | 25 | import dbus.mainloop.glib | ||
757 | 26 | |||
758 | 27 | BUS_NAME = 'com.meego.msyncd' | ||
759 | 28 | MAIN_OBJ = '/synchronizer' | ||
760 | 29 | MAIN_IFACE = 'com.meego.msyncd' | ||
761 | 30 | SYSTEM_BUS = False | ||
762 | 31 | |||
763 | 32 | class ButeoSyncFw(dbus.service.Object): | ||
764 | 33 | PROFILES = [ | ||
765 | 34 | """<?xml version=\"1.0\" encoding=\"UTF-8\"?> | ||
766 | 35 | <profile type=\"sync\" name=\"test-profile\"> | ||
767 | 36 | <key value=\"45\" name=\"accountid\"/> | ||
768 | 37 | <key value=\"contacts\" name=\"category\"/> | ||
769 | 38 | <key value=\"google.Contacts-\" name=\"displayname\"/> | ||
770 | 39 | <key value=\"true\" name=\"enabled\"/> | ||
771 | 40 | <key value=\"true\" name=\"hidden\"/> | ||
772 | 41 | <key value=\"30\" name=\"sync_since_days_past\"/> | ||
773 | 42 | <key value=\"true\" name=\"use_accounts\"/> | ||
774 | 43 | <profile type=\"client\" name=\"googlecontacts\"> | ||
775 | 44 | <key value=\"two-way\" name=\"Sync Direction\"/> | ||
776 | 45 | </profile> | ||
777 | 46 | <schedule time=\"05:00:00\" days=\"4,5,2,3,1,6,7\" syncconfiguredtime=\"\" interval=\"0\" enabled=\"true\"> | ||
778 | 47 | <rush end=\"\" externalsync=\"false\" days=\"\" interval=\"15\" begin=\"\" enabled=\"false\"/> | ||
779 | 48 | </schedule> | ||
780 | 49 | </profile>""", | ||
781 | 50 | """<?xml version=\"1.0\" encoding=\"UTF-8\"?> | ||
782 | 51 | <profile type=\"sync\" name=\"testsync-ovi\"> | ||
783 | 52 | <key value=\"calendar\" name=\"category\"/> | ||
784 | 53 | <schedule syncconfiguredtime=\"\" interval=\"0\" days=\"\" externalsync=\"true\" time=\"\" enabled=\"false\"> | ||
785 | 54 | <rush interval=\"0\" days=\"\" externalsync=\"false\" begin=\"\" enabled=\"false\" end=\"\"/> | ||
786 | 55 | </schedule> | ||
787 | 56 | </profile>""", | ||
788 | 57 | """<?xml version=\"1.0\" encoding=\"UTF-8\"?> | ||
789 | 58 | <profile name=\"63807467\" type=\"sync\"> | ||
790 | 59 | <key value=\"110\" name=\"accountid\"/> | ||
791 | 60 | <key value=\"contacts\" name=\"category\"/> | ||
792 | 61 | <key value=\"online\" name=\"destinationtype\"/> | ||
793 | 62 | <key value=\"google-contacts-renato.teste2@gmail.com\" name=\"displayname\"/> | ||
794 | 63 | <key value=\"true\" name=\"enabled\"/> | ||
795 | 64 | <key value=\"true\" name=\"hidden\"/> | ||
796 | 65 | <key value=\"false\" name=\"scheduled\"/> | ||
797 | 66 | <key value=\"true\" name=\"sync_always_up_to_date\"/> | ||
798 | 67 | <key value=\"true\" name=\"sync_on_change\"/> | ||
799 | 68 | <key value=\"30\" name=\"sync_since_days_past\"/> | ||
800 | 69 | <key value=\"true\" name=\"use_accounts\"/> | ||
801 | 70 | <profile name=\"googlecontacts\" type=\"client\"> | ||
802 | 71 | <key value=\"two-way\" name=\"Sync Direction\"/> | ||
803 | 72 | <key value=\"gdata\" name=\"Sync Protocol\"/> | ||
804 | 73 | <key value=\"HTTP\" name=\"Sync Transport\"/> | ||
805 | 74 | <key value=\"prefer remote\" name=\"conflictpolicy\"/> | ||
806 | 75 | <key value=\"true\" name=\"sync_on_change\"/> | ||
807 | 76 | </profile> | ||
808 | 77 | <schedule syncconfiguredtime=\"\" days=\"5,4,7,6,1,3,2\" interval=\"60\" enabled=\"false\" time=\"\"> | ||
809 | 78 | <rush begin=\"00:00:00\" end=\"00:00:00\" days=\"\" interval=\"60\" enabled=\"false\" externalsync=\"false\"/> | ||
810 | 79 | </schedule> | ||
811 | 80 | </profile>""", | ||
812 | 81 | """<?xml version=\"1.0\" encoding=\"UTF-8\"?> | ||
813 | 82 | <profile type=\"sync\" name=\"template-profile\"> | ||
814 | 83 | <key value=\"contacts\" name=\"category\"/> | ||
815 | 84 | <key value=\"false\" name=\"enabled\"/> | ||
816 | 85 | <schedule syncconfiguredtime=\"\" interval=\"0\" days=\"\" externalsync=\"true\" time=\"\" enabled=\"false\"> | ||
817 | 86 | <rush interval=\"0\" days=\"\" externalsync=\"false\" begin=\"\" enabled=\"false\" end=\"\"/> | ||
818 | 87 | </schedule> | ||
819 | 88 | </profile>""" | ||
820 | 89 | ] | ||
821 | 90 | |||
822 | 91 | def __init__(self, object_path): | ||
823 | 92 | dbus.service.Object.__init__(self, dbus.SessionBus(), object_path) | ||
824 | 93 | self._activeSync = [] | ||
825 | 94 | self._profiles = ButeoSyncFw.PROFILES | ||
826 | 95 | |||
827 | 96 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
828 | 97 | in_signature='', out_signature='as') | ||
829 | 98 | def allVisibleSyncProfiles(self): | ||
830 | 99 | return self._profiles | ||
831 | 100 | |||
832 | 101 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
833 | 102 | in_signature='ss', out_signature='as') | ||
834 | 103 | def syncProfilesByKey(self, key, value): | ||
835 | 104 | print ("syncProfilesByKey:", key, value) | ||
836 | 105 | if key == 'category': | ||
837 | 106 | if value == 'contacts': | ||
838 | 107 | return [ButeoSyncFw.PROFILES[0], ButeoSyncFw.PROFILES[2], ButeoSyncFw.PROFILES[3]] | ||
839 | 108 | if value == 'calendar': | ||
840 | 109 | return [ButeoSyncFw.PROFILES[1]] | ||
841 | 110 | return [] | ||
842 | 111 | |||
843 | 112 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
844 | 113 | in_signature='s', out_signature='') | ||
845 | 114 | def abortSync(self, profileId): | ||
846 | 115 | if profileId in self._activeSync: | ||
847 | 116 | self._activeSync.remove(profileId) | ||
848 | 117 | self.syncStatus(profileId, 5, 'aborted by the user', 0) | ||
849 | 118 | return | ||
850 | 119 | |||
851 | 120 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
852 | 121 | in_signature='s', out_signature='b') | ||
853 | 122 | def startSync(self, profileId): | ||
854 | 123 | if profileId in ['63807467', 'testsync-ovi', 'test-profile']: | ||
855 | 124 | self._activeSync.append(profileId) | ||
856 | 125 | self.syncStatus(profileId, 1, '', 0) | ||
857 | 126 | return True | ||
858 | 127 | return False | ||
859 | 128 | |||
860 | 129 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
861 | 130 | in_signature='', out_signature='as') | ||
862 | 131 | def runningSyncs(self): | ||
863 | 132 | return self._activeSync | ||
864 | 133 | |||
865 | 134 | @dbus.service.signal(dbus_interface=MAIN_IFACE, | ||
866 | 135 | signature='sisi') | ||
867 | 136 | def syncStatus(self, profileId, status, message, statusDetails): | ||
868 | 137 | print("SyncStatus called") | ||
869 | 138 | |||
870 | 139 | @dbus.service.signal(dbus_interface=MAIN_IFACE, | ||
871 | 140 | signature='sis') | ||
872 | 141 | def signalProfileChanged(self, profileId, status, changedProfile): | ||
873 | 142 | print("profileChanged called") | ||
874 | 143 | |||
875 | 144 | @dbus.service.method(dbus_interface=MAIN_IFACE, | ||
876 | 145 | in_signature='s', out_signature='b') | ||
877 | 146 | def removeProfile(self, profileId): | ||
878 | 147 | if int(profileId) < len(self._profiles): | ||
879 | 148 | self._profiles.remove(self._profiles[int(profileId)]) | ||
880 | 149 | self.signalProfileChanged(profileId, 2, 'deleted') | ||
881 | 150 | return True | ||
882 | 151 | else: | ||
883 | 152 | return False | ||
884 | 153 | |||
885 | 154 | |||
886 | 155 | |||
887 | 156 | if __name__ == '__main__': | ||
888 | 157 | dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | ||
889 | 158 | |||
890 | 159 | name = dbus.service.BusName(BUS_NAME) | ||
891 | 160 | mainloop = GObject.MainLoop() | ||
892 | 161 | buteo = ButeoSyncFw(MAIN_OBJ) | ||
893 | 162 | mainloop.run() | ||
894 | 163 | |||
895 | 0 | 164 | ||
896 | === added file 'tests/qml/tst_ButeoSyncFW.qml' | |||
897 | --- tests/qml/tst_ButeoSyncFW.qml 1970-01-01 00:00:00 +0000 | |||
898 | +++ tests/qml/tst_ButeoSyncFW.qml 2015-07-09 14:03:36 +0000 | |||
899 | @@ -0,0 +1,174 @@ | |||
900 | 1 | /* | ||
901 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
902 | 3 | * | ||
903 | 4 | * This program is free software; you can redistribute it and/or modify | ||
904 | 5 | * it under the terms of the GNU General Public License as published by | ||
905 | 6 | * the Free Software Foundation; version 3. | ||
906 | 7 | * | ||
907 | 8 | * This program is distributed in the hope that it will be useful, | ||
908 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
909 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
910 | 11 | * GNU General Public License for more details. | ||
911 | 12 | * | ||
912 | 13 | * You should have received a copy of the GNU General Public License | ||
913 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
914 | 15 | */ | ||
915 | 16 | |||
916 | 17 | import QtQuick 2.2 | ||
917 | 18 | import Buteo 0.1 | ||
918 | 19 | import QtTest 1.0 | ||
919 | 20 | |||
920 | 21 | Item { | ||
921 | 22 | id: root | ||
922 | 23 | |||
923 | 24 | property var buteoComponent | ||
924 | 25 | |||
925 | 26 | TestCase { | ||
926 | 27 | id: vcardParser | ||
927 | 28 | name: 'ButeoSyncFWTestCase' | ||
928 | 29 | |||
929 | 30 | function init() | ||
930 | 31 | { | ||
931 | 32 | buteoComponent = Qt.createQmlObject('import Buteo 0.1; ButeoSync{ }', root); | ||
932 | 33 | } | ||
933 | 34 | |||
934 | 35 | function cleanup() | ||
935 | 36 | { | ||
936 | 37 | if (buteoComponent) { | ||
937 | 38 | var activeProfiles = buteoComponent.getRunningSyncList() | ||
938 | 39 | for (var i in activeProfiles) { | ||
939 | 40 | buteoComponent.abortSync(activeProfiles[i]) | ||
940 | 41 | } | ||
941 | 42 | activeProfiles = buteoComponent.getRunningSyncList() | ||
942 | 43 | compare(activeProfiles.length, 0) | ||
943 | 44 | |||
944 | 45 | buteoComponent.destroy() | ||
945 | 46 | buteoComponent = null | ||
946 | 47 | } | ||
947 | 48 | } | ||
948 | 49 | |||
949 | 50 | function test_start_sync() | ||
950 | 51 | { | ||
951 | 52 | var spy = Qt.createQmlObject('import QtTest 1.0; SignalSpy{ }', root); | ||
952 | 53 | spy.target = buteoComponent | ||
953 | 54 | spy.signalName = "syncStatus" | ||
954 | 55 | |||
955 | 56 | compare(buteoComponent.startSync('1234'), false) | ||
956 | 57 | compare(buteoComponent.startSync('63807467'), true) | ||
957 | 58 | |||
958 | 59 | tryCompare(spy, "count", 1) | ||
959 | 60 | compare(spy.signalArguments[0][0], '63807467') | ||
960 | 61 | compare(spy.signalArguments[0][1], ButeoSync.SyncStarted) | ||
961 | 62 | compare(spy.signalArguments[0][2], '') | ||
962 | 63 | } | ||
963 | 64 | |||
964 | 65 | function test_abort_sync() | ||
965 | 66 | { | ||
966 | 67 | var spy = Qt.createQmlObject('import QtTest 1.0; SignalSpy{ }', root); | ||
967 | 68 | spy.target = buteoComponent | ||
968 | 69 | spy.signalName = "syncStatus" | ||
969 | 70 | |||
970 | 71 | compare(buteoComponent.startSync('63807467'), true) | ||
971 | 72 | tryCompare(spy, "count", 1) | ||
972 | 73 | |||
973 | 74 | var spy2 = Qt.createQmlObject('import QtTest 1.0; SignalSpy{ }', root); | ||
974 | 75 | spy2.target = buteoComponent | ||
975 | 76 | spy2.signalName = "syncStatus" | ||
976 | 77 | |||
977 | 78 | buteoComponent.abortSync('63807467') | ||
978 | 79 | |||
979 | 80 | tryCompare(spy2, "count", 1) | ||
980 | 81 | compare(spy2.signalArguments[0][0], '63807467') | ||
981 | 82 | compare(spy2.signalArguments[0][1], ButeoSync.SyncAborted) | ||
982 | 83 | compare(spy2.signalArguments[0][2], 'aborted by the user') | ||
983 | 84 | } | ||
984 | 85 | |||
985 | 86 | function test_syncing_property() | ||
986 | 87 | { | ||
987 | 88 | // check if no sync is running | ||
988 | 89 | compare(buteoComponent.syncing, false) | ||
989 | 90 | |||
990 | 91 | // start a new sync and check if the property changed to true | ||
991 | 92 | buteoComponent.startSync('63807467') | ||
992 | 93 | tryCompare(buteoComponent, 'syncing', true) | ||
993 | 94 | |||
994 | 95 | // abort current sync and check if sync property changed to false | ||
995 | 96 | buteoComponent.abortSync('63807467') | ||
996 | 97 | tryCompare(buteoComponent, 'syncing', false) | ||
997 | 98 | } | ||
998 | 99 | |||
999 | 100 | function test_visibleSyncProfiles_property() | ||
1000 | 101 | { | ||
1001 | 102 | compare(buteoComponent.visibleSyncProfiles.length, 4) | ||
1002 | 103 | var spy = Qt.createQmlObject('import QtTest 1.0; SignalSpy{ }', root); | ||
1003 | 104 | spy.target = buteoComponent | ||
1004 | 105 | spy.signalName = "profileChanged" | ||
1005 | 106 | |||
1006 | 107 | buteoComponent.removeProfile('3') | ||
1007 | 108 | tryCompare(spy, "count", 1) | ||
1008 | 109 | compare(spy.signalArguments[0][0], '3') | ||
1009 | 110 | compare(spy.signalArguments[0][1], ButeoSync.ProfileRemoved) | ||
1010 | 111 | compare(spy.signalArguments[0][2], 'deleted') | ||
1011 | 112 | compare(buteoComponent.visibleSyncProfiles.length, 3) | ||
1012 | 113 | spy.clear() | ||
1013 | 114 | |||
1014 | 115 | buteoComponent.removeProfile('2') | ||
1015 | 116 | tryCompare(spy, "count", 1) | ||
1016 | 117 | compare(spy.signalArguments[0][0], '2') | ||
1017 | 118 | compare(spy.signalArguments[0][1], ButeoSync.ProfileRemoved) | ||
1018 | 119 | compare(spy.signalArguments[0][2], 'deleted') | ||
1019 | 120 | compare(buteoComponent.visibleSyncProfiles.length, 2) | ||
1020 | 121 | spy.clear() | ||
1021 | 122 | |||
1022 | 123 | buteoComponent.removeProfile('1') | ||
1023 | 124 | tryCompare(spy, "count", 1) | ||
1024 | 125 | compare(spy.signalArguments[0][0], '1') | ||
1025 | 126 | compare(spy.signalArguments[0][1], ButeoSync.ProfileRemoved) | ||
1026 | 127 | compare(spy.signalArguments[0][2], 'deleted') | ||
1027 | 128 | compare(buteoComponent.visibleSyncProfiles.length, 1) | ||
1028 | 129 | spy.clear() | ||
1029 | 130 | |||
1030 | 131 | buteoComponent.removeProfile('0') | ||
1031 | 132 | tryCompare(spy, "count", 1) | ||
1032 | 133 | compare(spy.signalArguments[0][0], '0') | ||
1033 | 134 | compare(spy.signalArguments[0][1], ButeoSync.ProfileRemoved) | ||
1034 | 135 | compare(spy.signalArguments[0][2], 'deleted') | ||
1035 | 136 | compare(buteoComponent.visibleSyncProfiles.length, 0) | ||
1036 | 137 | spy.clear() | ||
1037 | 138 | } | ||
1038 | 139 | |||
1039 | 140 | function test_sync_by_profile_by_category() | ||
1040 | 141 | { | ||
1041 | 142 | var profiles = buteoComponent.syncProfilesByCategory('contacts') | ||
1042 | 143 | compare(profiles.length, 2) | ||
1043 | 144 | compare(profiles[0], 'test-profile') | ||
1044 | 145 | compare(profiles[1], '63807467') | ||
1045 | 146 | } | ||
1046 | 147 | |||
1047 | 148 | function test_sync_by_category() | ||
1048 | 149 | { | ||
1049 | 150 | var spy = Qt.createQmlObject('import QtTest 1.0; SignalSpy{ }', root); | ||
1050 | 151 | spy.target = buteoComponent | ||
1051 | 152 | spy.signalName = "syncStatus" | ||
1052 | 153 | |||
1053 | 154 | compare(buteoComponent.startSyncByCategory('contacts'), true) | ||
1054 | 155 | |||
1055 | 156 | // wait for two signals (since we have two contacts profiles) | ||
1056 | 157 | tryCompare(spy, "count", 2) | ||
1057 | 158 | // first profile | ||
1058 | 159 | compare(spy.signalArguments[0][0], 'test-profile') | ||
1059 | 160 | compare(spy.signalArguments[0][1], ButeoSync.SyncStarted) | ||
1060 | 161 | compare(spy.signalArguments[0][2], '') | ||
1061 | 162 | |||
1062 | 163 | // secound profile | ||
1063 | 164 | compare(spy.signalArguments[1][0], '63807467') | ||
1064 | 165 | compare(spy.signalArguments[1][1], ButeoSync.SyncStarted) | ||
1065 | 166 | compare(spy.signalArguments[1][2], '') | ||
1066 | 167 | |||
1067 | 168 | var activeProfiles = buteoComponent.getRunningSyncList() | ||
1068 | 169 | compare(activeProfiles.length, 2) | ||
1069 | 170 | compare(activeProfiles[0], 'test-profile') | ||
1070 | 171 | compare(activeProfiles[1], '63807467') | ||
1071 | 172 | } | ||
1072 | 173 | } | ||
1073 | 174 | } |
Not sure if "gnome" is the best section for the package?