Merge lp:~mandel/ubuntu-download-manager/stop-when-empty into lp:ubuntu-download-manager

Proposed by Manuel de la Peña
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 99
Merged at revision: 100
Proposed branch: lp:~mandel/ubuntu-download-manager/stop-when-empty
Merge into: lp:ubuntu-download-manager
Diff against target: 1125 lines (+649/-39)
23 files modified
libubuntudownloadmanager/download.cpp (+3/-2)
libubuntudownloadmanager/download_daemon.cpp (+52/-2)
libubuntudownloadmanager/download_daemon.h (+9/-1)
libubuntudownloadmanager/download_manager.cpp (+9/-4)
libubuntudownloadmanager/download_manager.h (+2/-1)
libubuntudownloadmanager/download_queue.cpp (+20/-22)
libubuntudownloadmanager/download_queue.h (+1/-1)
libubuntudownloadmanager/libubuntudownloadmanager.pro (+4/-2)
libubuntudownloadmanager/timer.cpp (+99/-0)
libubuntudownloadmanager/timer.h (+45/-0)
ubuntu-download-manager-tests/fake_download_manager.cpp (+32/-0)
ubuntu-download-manager-tests/fake_download_manager.h (+37/-0)
ubuntu-download-manager-tests/fake_download_queue.cpp (+20/-0)
ubuntu-download-manager-tests/fake_download_queue.h (+8/-0)
ubuntu-download-manager-tests/fake_timer.cpp (+75/-0)
ubuntu-download-manager-tests/fake_timer.h (+44/-0)
ubuntu-download-manager-tests/irl_tests.py (+84/-0)
ubuntu-download-manager-tests/test_download_daemon.cpp (+43/-1)
ubuntu-download-manager-tests/test_download_daemon.h (+7/-0)
ubuntu-download-manager-tests/test_download_manager.cpp (+44/-0)
ubuntu-download-manager-tests/test_download_manager.h (+4/-0)
ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro (+6/-2)
ubuntu-download-manager/ubuntu-download-manager.pro (+1/-1)
To merge this branch: bzr merge lp:~mandel/ubuntu-download-manager/stop-when-empty
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+181656@code.launchpad.net

Commit message

Ensures that the daemon is stopped when there is nothing to download.

Description of the change

Ensures that the daemon is stopped when there is nothing to download. To make thing simpler to test irl I have added a python script in the tests directory that uses the downloader to get an image. That way you can test that the downloader works and once the download is done the daemon is closed.

To post a comment you must log in.
98. By Manuel de la Peña

Merged with trunk and resolved errors.

99. By Manuel de la Peña

Link bug.

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

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libubuntudownloadmanager/download.cpp'
--- libubuntudownloadmanager/download.cpp 2013-08-21 14:10:28 +0000
+++ libubuntudownloadmanager/download.cpp 2013-08-22 21:00:52 +0000
@@ -352,7 +352,7 @@
352352
353QNetworkRequest353QNetworkRequest
354DownloadPrivate::buildRequest() {354DownloadPrivate::buildRequest() {
355 qDebug() << "Building request for " << _url;355 qDebug() << __FUNCTION__ << _url;
356 QNetworkRequest request = QNetworkRequest(_url);356 QNetworkRequest request = QNetworkRequest(_url);
357 foreach(const QString& header, _headers.keys()) {357 foreach(const QString& header, _headers.keys()) {
358 QString data = _headers[header];358 QString data = _headers[header];
@@ -366,7 +366,7 @@
366366
367void367void
368DownloadPrivate::emitError(const QString& error) {368DownloadPrivate::emitError(const QString& error) {
369 qDebug() << "EMIT ERROR:" << error;369 qDebug() << __FUNCTION__ << error;
370 Q_Q(Download);370 Q_Q(Download);
371 disconnectFromReplySignals();371 disconnectFromReplySignals();
372 _reply->deleteLater();372 _reply->deleteLater();
@@ -428,6 +428,7 @@
428428
429bool429bool
430DownloadPrivate::canDownload() {430DownloadPrivate::canDownload() {
431 qDebug() << __FUNCTION__;
431 QNetworkInfo::NetworkMode mode = _networkInfo->currentNetworkMode();432 QNetworkInfo::NetworkMode mode = _networkInfo->currentNetworkMode();
432 switch (mode) {433 switch (mode) {
433 case QNetworkInfo::UnknownMode:434 case QNetworkInfo::UnknownMode:
434435
=== modified file 'libubuntudownloadmanager/download_daemon.cpp'
--- libubuntudownloadmanager/download_daemon.cpp 2013-08-21 12:21:49 +0000
+++ libubuntudownloadmanager/download_daemon.cpp 2013-08-22 21:00:52 +0000
@@ -36,16 +36,23 @@
36 explicit DownloadDaemonPrivate(DownloadDaemon* parent);36 explicit DownloadDaemonPrivate(DownloadDaemon* parent);
37 explicit DownloadDaemonPrivate(Application* app,37 explicit DownloadDaemonPrivate(Application* app,
38 DBusConnection* conn,38 DBusConnection* conn,
39 Timer* timer,
40 DownloadManager* man,
39 DownloadDaemon* parent);41 DownloadDaemon* parent);
40 ~DownloadDaemonPrivate();42 ~DownloadDaemonPrivate();
4143
42 void start();44 void start();
45 void onTimeout();
46 void onDownloadManagerSizeChanged(int size);
47
48 static const int timeout = 30000;
4349
44 private:50 private:
45 void init();51 void init();
4652
47 private:53 private:
48 Application* _app;54 Application* _app;
55 Timer* _shutDownTimer;
49 QSharedPointer<DBusConnection> _conn;56 QSharedPointer<DBusConnection> _conn;
50 DownloadManager* _downInterface;57 DownloadManager* _downInterface;
51 DownloadManagerAdaptor* _downAdaptor;58 DownloadManagerAdaptor* _downAdaptor;
@@ -56,21 +63,36 @@
56 : q_ptr(parent) {63 : q_ptr(parent) {
57 _app = new Application();64 _app = new Application();
58 _conn = QSharedPointer<DBusConnection>(new DBusConnection());65 _conn = QSharedPointer<DBusConnection>(new DBusConnection());
66 _shutDownTimer = new Timer();
59 _downInterface = new DownloadManager(_conn, q_ptr);67 _downInterface = new DownloadManager(_conn, q_ptr);
60 init();68 init();
61}69}
6270
63DownloadDaemonPrivate::DownloadDaemonPrivate(Application* app,71DownloadDaemonPrivate::DownloadDaemonPrivate(Application* app,
64 DBusConnection* conn,72 DBusConnection* conn,
73 Timer* timer,
74 DownloadManager* man,
65 DownloadDaemon* parent)75 DownloadDaemon* parent)
66 : _app(app),76 : _app(app),
77 _shutDownTimer(timer),
67 _conn(conn),78 _conn(conn),
79 _downInterface(man),
68 q_ptr(parent) {80 q_ptr(parent) {
69 _downInterface = new DownloadManager(_conn);
70 init();81 init();
71}82}
7283
73void DownloadDaemonPrivate::init() {84void DownloadDaemonPrivate::init() {
85 Q_Q(DownloadDaemon);
86
87 q->connect(_shutDownTimer, SIGNAL(timeout()),
88 q, SLOT(onTimeout()));
89 _shutDownTimer->start(timeout);
90
91 // connect to the download manager changes
92 q->connect(_downInterface,
93 SIGNAL(sizeChanged(int)), // NOLINT (readability/function)
94 q, SLOT(onDownloadManagerSizeChanged(int))); // NOLINT (readability/function)
95
74 // set logging96 // set logging
75 Logger::setupLogging();97 Logger::setupLogging();
76#ifdef DEBUG98#ifdef DEBUG
@@ -87,6 +109,8 @@
87 delete _downInterface;109 delete _downInterface;
88 if (_app)110 if (_app)
89 delete _app;111 delete _app;
112 if (_shutDownTimer)
113 delete _shutDownTimer;
90114
91 // stop logging115 // stop logging
92 Logger::setupLogging();116 Logger::setupLogging();
@@ -112,6 +136,28 @@
112 _app->exit(-1);136 _app->exit(-1);
113}137}
114138
139void
140DownloadDaemonPrivate::onTimeout() {
141 qDebug() << "Timeout reached, shutdown service.";
142 _app->exit(0);
143}
144
145void
146DownloadDaemonPrivate::onDownloadManagerSizeChanged(int size) {
147 bool isActive = _shutDownTimer->isActive();
148 qDebug() << "Timer is active:" << isActive << "size is:" << size;
149
150 if (isActive && size > 0) {
151 qDebug() << "Timer must be stopped because we have" << size
152 << "downloads.";
153 _shutDownTimer->stop();
154 }
155 if (!isActive && size == 0) {
156 qDebug() << "Timer must be started because we have 0 downloads.";
157 _shutDownTimer->start(timeout);
158 }
159}
160
115/**161/**
116 * PUBLIC IMPLEMENTATION162 * PUBLIC IMPLEMENTATION
117 */163 */
@@ -123,9 +169,11 @@
123169
124DownloadDaemon::DownloadDaemon(Application* app,170DownloadDaemon::DownloadDaemon(Application* app,
125 DBusConnection* conn,171 DBusConnection* conn,
172 Timer* timer,
173 DownloadManager* man,
126 QObject *parent)174 QObject *parent)
127 : QObject(parent),175 : QObject(parent),
128 d_ptr(new DownloadDaemonPrivate(app, conn, this)) {176 d_ptr(new DownloadDaemonPrivate(app, conn, timer, man, this)) {
129}177}
130178
131void179void
@@ -133,3 +181,5 @@
133 Q_D(DownloadDaemon);181 Q_D(DownloadDaemon);
134 d->start();182 d->start();
135}183}
184
185#include "moc_download_daemon.cpp"
136186
=== modified file 'libubuntudownloadmanager/download_daemon.h'
--- libubuntudownloadmanager/download_daemon.h 2013-08-21 12:08:43 +0000
+++ libubuntudownloadmanager/download_daemon.h 2013-08-22 21:00:52 +0000
@@ -23,6 +23,8 @@
23#include "./app-downloader-lib_global.h"23#include "./app-downloader-lib_global.h"
24#include "./application.h"24#include "./application.h"
25#include "./dbus_connection.h"25#include "./dbus_connection.h"
26#include "./download_manager.h"
27#include "./timer.h"
2628
27class DownloadDaemonPrivate;29class DownloadDaemonPrivate;
28class APPDOWNLOADERLIBSHARED_EXPORT DownloadDaemon : public QObject {30class APPDOWNLOADERLIBSHARED_EXPORT DownloadDaemon : public QObject {
@@ -33,12 +35,18 @@
33 explicit DownloadDaemon(QObject *parent = 0);35 explicit DownloadDaemon(QObject *parent = 0);
34 explicit DownloadDaemon(Application* app,36 explicit DownloadDaemon(Application* app,
35 DBusConnection* conn,37 DBusConnection* conn,
38 Timer* timer,
39 DownloadManager* man,
36 QObject *parent = 0);40 QObject *parent = 0);
3741
38 public slots:42 public slots: // NOLINT (whitespace/indent)
39 void start();43 void start();
4044
41 private:45 private:
46 Q_PRIVATE_SLOT(d_func(), void onTimeout())
47 Q_PRIVATE_SLOT(d_func(), void onDownloadManagerSizeChanged(int)) // NOLINT (readability/function)
48
49 private:
42 // use pimpl so that we can mantains ABI compatibility50 // use pimpl so that we can mantains ABI compatibility
43 DownloadDaemonPrivate* d_ptr;51 DownloadDaemonPrivate* d_ptr;
44};52};
4553
=== modified file 'libubuntudownloadmanager/download_manager.cpp'
--- libubuntudownloadmanager/download_manager.cpp 2013-07-26 14:05:22 +0000
+++ libubuntudownloadmanager/download_manager.cpp 2013-08-22 21:00:52 +0000
@@ -44,7 +44,7 @@
44 void init();44 void init();
45 void addDownload(Download* download);45 void addDownload(Download* download);
46 void loadPreviewsDownloads(QString path);46 void loadPreviewsDownloads(QString path);
47 void onDownloadRemoved(QString path);47 void onDownloadsChanged(QString path);
4848
49 QDBusObjectPath createDownload(const QString& url,49 QDBusObjectPath createDownload(const QString& url,
50 const QVariantMap& metadata,50 const QVariantMap& metadata,
@@ -111,7 +111,9 @@
111 qDBusRegisterMetaType<StringMap>();111 qDBusRegisterMetaType<StringMap>();
112112
113 q->connect(_downloadsQueue, SIGNAL(downloadRemoved(QString)),113 q->connect(_downloadsQueue, SIGNAL(downloadRemoved(QString)),
114 q, SLOT(onDownloadRemoved(QString)));114 q, SLOT(onDownloadsChanged(QString)));
115 q->connect(_downloadsQueue, SIGNAL(downloadAdded(QString)),
116 q, SLOT(onDownloadsChanged(QString)));
115117
116 _reqFactory = new RequestFactory();118 _reqFactory = new RequestFactory();
117 _processFactory = new ProcessFactory();119 _processFactory = new ProcessFactory();
@@ -131,14 +133,17 @@
131}133}
132134
133void135void
134DownloadManagerPrivate::onDownloadRemoved(QString path) {136DownloadManagerPrivate::onDownloadsChanged(QString path) {
135 _conn->unregisterObject(path);137 qDebug() << __FUNCTION__ << path;
138 Q_Q(DownloadManager);
139 emit q->sizeChanged(_downloadsQueue->size());
136}140}
137141
138QDBusObjectPath142QDBusObjectPath
139DownloadManagerPrivate::createDownload(const QString& url,143DownloadManagerPrivate::createDownload(const QString& url,
140 const QVariantMap& metadata,144 const QVariantMap& metadata,
141 StringMap headers) {145 StringMap headers) {
146 qDebug() << __FUNCTION__ << url << metadata << headers;
142 return createDownloadWithHash(url, "", QCryptographicHash::Md5,147 return createDownloadWithHash(url, "", QCryptographicHash::Md5,
143 metadata, headers);148 metadata, headers);
144}149}
145150
=== modified file 'libubuntudownloadmanager/download_manager.h'
--- libubuntudownloadmanager/download_manager.h 2013-07-26 14:05:22 +0000
+++ libubuntudownloadmanager/download_manager.h 2013-08-22 21:00:52 +0000
@@ -62,9 +62,10 @@
6262
63 signals:63 signals:
64 void downloadCreated(const QDBusObjectPath& path);64 void downloadCreated(const QDBusObjectPath& path);
65 void sizeChanged(int count);
6566
66 private:67 private:
67 Q_PRIVATE_SLOT(d_func(), void onDownloadRemoved(QString))68 Q_PRIVATE_SLOT(d_func(), void onDownloadsChanged(QString))
6869
69 private:70 private:
70 // use pimpl so that we can mantains ABI compatibility71 // use pimpl so that we can mantains ABI compatibility
7172
=== modified file 'libubuntudownloadmanager/download_queue.cpp'
--- libubuntudownloadmanager/download_queue.cpp 2013-08-21 14:10:28 +0000
+++ libubuntudownloadmanager/download_queue.cpp 2013-08-22 21:00:52 +0000
@@ -40,16 +40,15 @@
40 QString currentDownload();40 QString currentDownload();
41 QStringList paths();41 QStringList paths();
42 QHash<QString, Download*> downloads();42 QHash<QString, Download*> downloads();
43 int size();
4344
44 void onDownloadStateChanged();45 void onDownloadStateChanged();
45 void onDestroyed(const QString& path);
46 void onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode mode);46 void onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode mode);
4747
48 private:48 private:
49 void updateCurrentDownload();49 void updateCurrentDownload();
5050
51 private:51 private:
52 QSignalMapper* _mapper;
53 QString _current;52 QString _current;
54 DownloadList _downloads; // quick for access53 DownloadList _downloads; // quick for access
55 QStringList _sortedPaths; // keep the order54 QStringList _sortedPaths; // keep the order
@@ -63,19 +62,13 @@
63 _networkInfo(networkInfo),62 _networkInfo(networkInfo),
64 q_ptr(parent) {63 q_ptr(parent) {
65 Q_Q(DownloadQueue);64 Q_Q(DownloadQueue);
66 _mapper = new QSignalMapper();
6765
68 q->connect(_networkInfo,66 q->connect(_networkInfo,
69 SIGNAL(currentNetworkModeChanged(QNetworkInfo::NetworkMode)), q,67 SIGNAL(currentNetworkModeChanged(QNetworkInfo::NetworkMode)), q,
70 SLOT(onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode)));68 SLOT(onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode)));
71
72 q->connect(_mapper, SIGNAL(mapped(const QString&)),
73 q, SLOT(onDestroyed(const QString&)));
74}69}
7570
76DownloadQueuePrivate::~DownloadQueuePrivate() {71DownloadQueuePrivate::~DownloadQueuePrivate() {
77 if (_mapper != NULL)
78 delete _mapper;
79}72}
8073
81void74void
@@ -89,6 +82,8 @@
89 Q_Q(DownloadQueue);82 Q_Q(DownloadQueue);
90 // connect to the signals and append to the list83 // connect to the signals and append to the list
91 QString path = value.first->path();84 QString path = value.first->path();
85 qDebug() << __FUNCTION__ << path;
86
92 _sortedPaths.append(path);87 _sortedPaths.append(path);
93 _downloads[path] = value;88 _downloads[path] = value;
9489
@@ -107,15 +102,10 @@
107 _sortedPaths.removeOne(path);102 _sortedPaths.removeOne(path);
108 _downloads.remove(path);103 _downloads.remove(path);
109104
110 // connect to the adaptor destroyed event to ensure that we have
111 // emitted all signals, else we might have a race condition where
112 // the object path is removed from dbus to early
113 q->connect(pair.second, SIGNAL(destroyed(QObject* obj)),
114 _mapper, SLOT(map(QObject* obj)));
115 _mapper->setMapping(pair.first, path);
116
117 pair.second->deleteLater();105 pair.second->deleteLater();
118 pair.first->deleteLater();106 pair.first->deleteLater();
107
108 emit q->downloadRemoved(path);
119}109}
120110
121QString111QString
@@ -137,8 +127,14 @@
137 return downloads;127 return downloads;
138}128}
139129
130int
131DownloadQueuePrivate::size() {
132 return _downloads.size();
133}
134
140void135void
141DownloadQueuePrivate::onDownloadStateChanged() {136DownloadQueuePrivate::onDownloadStateChanged() {
137 qDebug() << __FUNCTION__;
142 Q_Q(DownloadQueue);138 Q_Q(DownloadQueue);
143 // get the appdownload that emited the signal and decide what to do with it139 // get the appdownload that emited the signal and decide what to do with it
144 Download* sender = qobject_cast<Download*>(q->sender());140 Download* sender = qobject_cast<Download*>(q->sender());
@@ -180,13 +176,6 @@
180}176}
181177
182void178void
183DownloadQueuePrivate::onDestroyed(const QString &path) {
184 qDebug() << __FUNCTION__;
185 Q_Q(DownloadQueue);
186 emit q->downloadRemoved(path);
187}
188
189void
190DownloadQueuePrivate::onCurrentNetworkModeChanged(179DownloadQueuePrivate::onCurrentNetworkModeChanged(
191 QNetworkInfo::NetworkMode mode) {180 QNetworkInfo::NetworkMode mode) {
192 Q_UNUSED(mode);181 Q_UNUSED(mode);
@@ -195,6 +184,7 @@
195184
196void185void
197DownloadQueuePrivate::updateCurrentDownload() {186DownloadQueuePrivate::updateCurrentDownload() {
187 qDebug() << __FUNCTION__;
198 Q_Q(DownloadQueue);188 Q_Q(DownloadQueue);
199189
200 if (!_current.isEmpty()) {190 if (!_current.isEmpty()) {
@@ -203,10 +193,12 @@
203 Download::State state = currentDownload->state();193 Download::State state = currentDownload->state();
204 if (state == Download::CANCEL || state == Download::FINISH194 if (state == Download::CANCEL || state == Download::FINISH
205 || state == Download::ERROR) {195 || state == Download::ERROR) {
196 qDebug() << "States is CANCEL || FINISH";
206 remove(_current);197 remove(_current);
207 _current = "";198 _current = "";
208 } else if (!currentDownload->canDownload()199 } else if (!currentDownload->canDownload()
209 || state == Download::PAUSE) {200 || state == Download::PAUSE) {
201 qDebug() << "States is Cannot Download || PAUSE";
210 _current = "";202 _current = "";
211 } else {203 } else {
212 return;204 return;
@@ -272,4 +264,10 @@
272 return d->downloads();264 return d->downloads();
273}265}
274266
267int
268DownloadQueue::size() {
269 Q_D(DownloadQueue);
270 return d->size();
271}
272
275#include "moc_download_queue.cpp"273#include "moc_download_queue.cpp"
276274
=== modified file 'libubuntudownloadmanager/download_queue.h'
--- libubuntudownloadmanager/download_queue.h 2013-07-23 15:51:01 +0000
+++ libubuntudownloadmanager/download_queue.h 2013-08-22 21:00:52 +0000
@@ -40,6 +40,7 @@
40 QString currentDownload();40 QString currentDownload();
41 QStringList paths();41 QStringList paths();
42 QHash<QString, Download*> downloads();42 QHash<QString, Download*> downloads();
43 virtual int size();
4344
44 signals:45 signals:
45 // signals raised when things happens within the q46 // signals raised when things happens within the q
@@ -49,7 +50,6 @@
4950
50 private:51 private:
51 Q_PRIVATE_SLOT(d_func(), void onDownloadStateChanged())52 Q_PRIVATE_SLOT(d_func(), void onDownloadStateChanged())
52 Q_PRIVATE_SLOT(d_func(), void onDestroyed(const QString& path))
53 Q_PRIVATE_SLOT(d_func(),53 Q_PRIVATE_SLOT(d_func(),
54 void onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode mode))54 void onCurrentNetworkModeChanged(QNetworkInfo::NetworkMode mode))
5555
5656
=== modified file 'libubuntudownloadmanager/libubuntudownloadmanager.pro'
--- libubuntudownloadmanager/libubuntudownloadmanager.pro 2013-08-21 11:08:29 +0000
+++ libubuntudownloadmanager/libubuntudownloadmanager.pro 2013-08-22 21:00:52 +0000
@@ -24,7 +24,8 @@
24 process.cpp \24 process.cpp \
25 process_factory.cpp \25 process_factory.cpp \
26 logger.cpp \26 logger.cpp \
27 application.cpp27 application.cpp \
28 timer.cpp
2829
29HEADERS +=\30HEADERS +=\
30 app-downloader-lib_global.h \31 app-downloader-lib_global.h \
@@ -44,7 +45,8 @@
44 process_factory.h \45 process_factory.h \
45 metatypes.h \46 metatypes.h \
46 logger.h \47 logger.h \
47 application.h48 application.h \
49 timer.h
4850
49OTHER_FILES += \51OTHER_FILES += \
50 generate_adaptors.sh \52 generate_adaptors.sh \
5153
=== added file 'libubuntudownloadmanager/timer.cpp'
--- libubuntudownloadmanager/timer.cpp 1970-01-01 00:00:00 +0000
+++ libubuntudownloadmanager/timer.cpp 2013-08-22 21:00:52 +0000
@@ -0,0 +1,99 @@
1/*
2 * Copyright 2013 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#include <QTimer>
20#include "./timer.h"
21
22/*
23 * PRIVATE IMPLEMENTATION
24 */
25
26class TimerPrivate {
27 Q_DECLARE_PUBLIC(Timer)
28
29 public:
30 explicit TimerPrivate(Timer* parent);
31 ~TimerPrivate();
32
33 bool isActive();
34 void start(int msec);
35 void stop();
36
37 private:
38 QTimer* _timer;
39 Timer* q_ptr;
40};
41
42TimerPrivate::TimerPrivate(Timer* parent)
43 : q_ptr(parent) {
44 Q_Q(Timer);
45 _timer = new QTimer();
46 _timer->setSingleShot(true);
47
48 q->connect(_timer, SIGNAL(timeout()),
49 q, SIGNAL(timeout()));
50}
51
52TimerPrivate::~TimerPrivate() {
53 if (_timer)
54 delete _timer;
55}
56
57
58bool
59TimerPrivate::isActive() {
60 return _timer->isActive();
61}
62
63void
64TimerPrivate::start(int msec) {
65 _timer->start(msec);
66}
67
68void
69TimerPrivate::stop() {
70 _timer->stop();
71}
72
73
74/*
75 * PUBLIC IMPLEMENTATION
76 */
77
78Timer::Timer(QObject *parent)
79 : QObject(parent),
80 d_ptr(new TimerPrivate(this)) {
81}
82
83bool
84Timer::isActive() {
85 Q_D(Timer);
86 return d->isActive();
87}
88
89void
90Timer::start(int msec) {
91 Q_D(Timer);
92 d->start(msec);
93}
94
95void
96Timer::stop() {
97 Q_D(Timer);
98 d->stop();
99}
0100
=== added file 'libubuntudownloadmanager/timer.h'
--- libubuntudownloadmanager/timer.h 1970-01-01 00:00:00 +0000
+++ libubuntudownloadmanager/timer.h 2013-08-22 21:00:52 +0000
@@ -0,0 +1,45 @@
1/*
2 * Copyright 2013 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#ifndef DOWNLOADER_LIB_TIMER_H
20#define DOWNLOADER_LIB_TIMER_H
21
22#include <QObject>
23
24
25class TimerPrivate;
26class Timer : public QObject {
27 Q_OBJECT
28 Q_DECLARE_PRIVATE(Timer)
29
30 public:
31 explicit Timer(QObject *parent = 0);
32
33 virtual bool isActive();
34 virtual void start(int msec);
35 virtual void stop();
36
37 signals:
38 void timeout();
39
40 private:
41 // use pimpl so that we can mantains ABI compatibility
42 TimerPrivate* d_ptr;
43};
44
45#endif // DOWNLOADER_LIB_TIMER_H
046
=== added file 'ubuntu-download-manager-tests/fake_download_manager.cpp'
--- ubuntu-download-manager-tests/fake_download_manager.cpp 1970-01-01 00:00:00 +0000
+++ ubuntu-download-manager-tests/fake_download_manager.cpp 2013-08-22 21:00:52 +0000
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#include "./fake_download_manager.h"
20
21FakeDownloadManager::FakeDownloadManager(
22 QSharedPointer<DBusConnection> connection,
23 QObject *parent)
24 : DownloadManager(connection, parent),
25 Fake() {
26}
27
28void
29FakeDownloadManager::emitSizeChaged(int size) {
30 emit sizeChanged(size);
31}
32
033
=== added file 'ubuntu-download-manager-tests/fake_download_manager.h'
--- ubuntu-download-manager-tests/fake_download_manager.h 1970-01-01 00:00:00 +0000
+++ ubuntu-download-manager-tests/fake_download_manager.h 2013-08-22 21:00:52 +0000
@@ -0,0 +1,37 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#ifndef FAKE_DOWNLOAD_MANAGER_H
20#define FAKE_DOWNLOAD_MANAGER_H
21
22#include <QObject>
23#include <download_manager.h>
24#include "./fake.h"
25
26
27class FakeDownloadManager : public DownloadManager, public Fake {
28 Q_OBJECT
29
30 public:
31 explicit FakeDownloadManager(QSharedPointer<DBusConnection> connection,
32 QObject *parent = 0);
33
34 void emitSizeChaged(int size);
35};
36
37#endif // FAKE_DOWNLOAD_MANAGER_H
038
=== modified file 'ubuntu-download-manager-tests/fake_download_queue.cpp'
--- ubuntu-download-manager-tests/fake_download_queue.cpp 2013-07-23 17:42:03 +0000
+++ ubuntu-download-manager-tests/fake_download_queue.cpp 2013-08-22 21:00:52 +0000
@@ -57,3 +57,23 @@
57 }57 }
58 DownloadQueue::add(value);58 DownloadQueue::add(value);
59}59}
60
61int
62FakeDownloadQueue::size() {
63 return _size;
64}
65
66void
67FakeDownloadQueue::setSize(int size) {
68 _size = size;
69}
70
71void
72FakeDownloadQueue::emitDownloadAdded(const QString& path) {
73 emit downloadAdded(path);
74}
75
76void
77FakeDownloadQueue::emitDownloadRemoved(const QString& path) {
78 emit downloadRemoved(path);
79}
6080
=== modified file 'ubuntu-download-manager-tests/fake_download_queue.h'
--- ubuntu-download-manager-tests/fake_download_queue.h 2013-07-23 17:42:56 +0000
+++ ubuntu-download-manager-tests/fake_download_queue.h 2013-08-22 21:00:52 +0000
@@ -31,6 +31,14 @@
3131
32 void add(Download* download, DownloadAdaptor* adaptor) override;32 void add(Download* download, DownloadAdaptor* adaptor) override;
33 void add(const QPair<Download*, DownloadAdaptor*>& value) override;33 void add(const QPair<Download*, DownloadAdaptor*>& value) override;
34 int size() override;
35 void setSize(int size);
36
37 void emitDownloadAdded(const QString& path);
38 void emitDownloadRemoved(const QString& path);
39
40 private:
41 int _size;
34};42};
3543
36#endif // FAKE_DOWNLOAD_QUEUE_H44#endif // FAKE_DOWNLOAD_QUEUE_H
3745
=== added file 'ubuntu-download-manager-tests/fake_timer.cpp'
--- ubuntu-download-manager-tests/fake_timer.cpp 1970-01-01 00:00:00 +0000
+++ ubuntu-download-manager-tests/fake_timer.cpp 2013-08-22 21:00:52 +0000
@@ -0,0 +1,75 @@
1/*
2 * Copyright 2013 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#include "./fake_timer.h"
20
21FakeTimer::FakeTimer(QObject *parent)
22 : Timer(parent),
23 Fake() {
24}
25
26bool
27FakeTimer::isActive() {
28 if (_recording) {
29 QList<QObject*> inParams;
30
31 QList<QObject*> outParams;
32 outParams.append(new BoolWrapper(_isActive));
33
34 MethodParams params(inParams, outParams);
35 MethodData methodData("isActive", params);
36 _called.append(methodData);
37 }
38 return _isActive;
39}
40
41void
42FakeTimer::setIsActive(bool active) {
43 _isActive = active;
44}
45
46void
47FakeTimer::start(int msec) {
48 if (_recording) {
49 QList<QObject*> inParams;
50 inParams.append(new IntWrapper(msec));
51
52 QList<QObject*> outParams;
53
54 MethodParams params(inParams, outParams);
55 MethodData methodData("start", params);
56 _called.append(methodData);
57 }
58}
59
60void
61FakeTimer::stop() {
62 if (_recording) {
63 QList<QObject*> inParams;
64 QList<QObject*> outParams;
65
66 MethodParams params(inParams, outParams);
67 MethodData methodData("stop", params);
68 _called.append(methodData);
69 }
70}
71
72void
73FakeTimer::emitTimeout() {
74 emit timeout();
75}
076
=== added file 'ubuntu-download-manager-tests/fake_timer.h'
--- ubuntu-download-manager-tests/fake_timer.h 1970-01-01 00:00:00 +0000
+++ ubuntu-download-manager-tests/fake_timer.h 2013-08-22 21:00:52 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2013 2013 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19#ifndef FAKE_TIMER_H
20#define FAKE_TIMER_H
21
22#include <QObject>
23#include <timer.h>
24#include "./fake.h"
25
26
27class FakeTimer : public Timer, public Fake {
28 Q_OBJECT
29
30 public:
31 explicit FakeTimer(QObject *parent = 0);
32
33 bool isActive() override;
34 void setIsActive(bool active);
35 void start(int msec) override;
36 void stop() override;
37
38 void emitTimeout();
39
40 private:
41 bool _isActive;
42};
43
44#endif // FAKE_TIMER_H
045
=== added file 'ubuntu-download-manager-tests/irl_tests.py'
--- ubuntu-download-manager-tests/irl_tests.py 1970-01-01 00:00:00 +0000
+++ ubuntu-download-manager-tests/irl_tests.py 2013-08-22 21:00:52 +0000
@@ -0,0 +1,84 @@
1#!/usr/bin/python
2# -*- encoding: utf-8 -*-
3#
4# Copyright 2013 Canonical Ltd.
5#
6# This program is free software: you can redistribute it and/or modify it
7# under the terms of the GNU General Public License version 3, as published
8# by the Free Software Foundation.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranties of
12# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13# PURPOSE. See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# In addition, as a special exception, the copyright holders give
19# permission to link the code of portions of this program with the
20# OpenSSL library under certain conditions as described in each
21# individual source file, and distribute linked combinations
22# including the two.
23# You must obey the GNU General Public License in all respects
24# for all of the code used other than OpenSSL. If you modify
25# file(s) with this exception, you may extend this exception to your
26# version of the file(s), but you are not obligated to do so. If you
27# do not wish to do so, delete this exception statement from your
28# version. If you delete this exception statement from all source
29# files in the program, then also delete it here.
30"""Test the ubuntu downloader."""
31
32import gobject
33import dbus
34from dbus.mainloop.glib import DBusGMainLoop
35
36DBusGMainLoop(set_as_default=True)
37
38MANAGER_PATH = '/'
39MANAGER_IFACE = 'com.canonical.applications.DownloaderManager'
40DOWNLOAD_IFACE = 'com.canonical.applications.Download'
41IMAGE_FILE = 'http://i.imgur.com/y51njgu.jpg'
42
43
44def download_created(path):
45 """Deal with the download created signal."""
46 print 'Download created in %s' % path
47
48
49def finished_callback(path, loop):
50 """Deal with the finis signal."""
51 print 'Download performed in "%s"' % path
52 loop.quit()
53
54
55def progress_callback(total, progress):
56 """Deal with the progress signals."""
57 print 'Progress is %s/%s' % (progress, total)
58
59if __name__ == '__main__':
60
61 bus = dbus.SessionBus()
62 loop = gobject.MainLoop()
63 manager = bus.get_object('com.canonical.applications.Downloader',
64 MANAGER_PATH)
65 manager_dev_iface = dbus.Interface(manager, dbus_interface=MANAGER_IFACE)
66
67 # ensure that download created works
68 manager_dev_iface.connect_to_signal('downloadCreated', download_created)
69
70 down_path = manager_dev_iface.createDownload(IMAGE_FILE, {}, {})
71
72 download = bus.get_object('com.canonical.applications.Downloader',
73 down_path)
74
75 download_dev_iface = dbus.Interface(download, dbus_interface=DOWNLOAD_IFACE)
76
77 # connect to signals
78 download_dev_iface.connect_to_signal('progress', progress_callback)
79 download_dev_iface.connect_to_signal('finished',
80 lambda path: finished_callback(path, loop))
81
82 download_dev_iface.start()
83
84 loop.run()
085
=== modified file 'ubuntu-download-manager-tests/test_download_daemon.cpp'
--- ubuntu-download-manager-tests/test_download_daemon.cpp 2013-08-21 12:21:49 +0000
+++ ubuntu-download-manager-tests/test_download_daemon.cpp 2013-08-22 21:00:52 +0000
@@ -24,9 +24,11 @@
2424
25void25void
26TestDownloadDaemon::init() {26TestDownloadDaemon::init() {
27 _timer = new FakeTimer();
27 _app = new FakeApplication();28 _app = new FakeApplication();
28 _conn = new FakeDBusConnection();29 _conn = new FakeDBusConnection();
29 _daemon = new DownloadDaemon(_app, _conn, this);30 _man = new FakeDownloadManager(QSharedPointer<DBusConnection>(_conn));
31 _daemon = new DownloadDaemon(_app, _conn, _timer, _man, this);
30}32}
3133
32void34void
@@ -37,6 +39,10 @@
37 delete _conn;39 delete _conn;
38 if (_daemon != NULL)40 if (_daemon != NULL)
39 delete _daemon;41 delete _daemon;
42 if (_timer != NULL)
43 delete _timer;
44 if (_man != NULL)
45 delete _man;
40}46}
4147
42void48void
@@ -99,3 +105,39 @@
99 QCOMPARE(1, calledMethods.count());105 QCOMPARE(1, calledMethods.count());
100 QCOMPARE(QString("exit"), calledMethods[0].methodName());106 QCOMPARE(QString("exit"), calledMethods[0].methodName());
101}107}
108
109void
110TestDownloadDaemon::testTimerStop() {
111 _timer->setIsActive(true);
112 _timer->record();
113 _man->emitSizeChaged(1);
114
115 QList<MethodData> calledMethods = _timer->calledMethods();
116 QCOMPARE(2, calledMethods.count());
117 QCOMPARE(QString("isActive"), calledMethods[0].methodName());
118 QCOMPARE(QString("stop"), calledMethods[1].methodName());
119}
120
121void
122TestDownloadDaemon::testTimerStart() {
123 _timer->setIsActive(false);
124 _timer->record();
125 _man->emitSizeChaged(0);
126
127 QList<MethodData> calledMethods = _timer->calledMethods();
128 QCOMPARE(2, calledMethods.count());
129 QCOMPARE(QString("isActive"), calledMethods[0].methodName());
130 QCOMPARE(QString("start"), calledMethods[1].methodName());
131}
132
133void
134TestDownloadDaemon::testTimeoutExit() {
135 _app->record();
136 // emit the timeout signal and assert that exit was called
137 _timer->emitTimeout();
138
139 QList<MethodData> calledMethods = _app->calledMethods();
140 QCOMPARE(1, calledMethods.count());
141 QCOMPARE(QString("exit"), calledMethods[0].methodName());
142}
143
102144
=== modified file 'ubuntu-download-manager-tests/test_download_daemon.h'
--- ubuntu-download-manager-tests/test_download_daemon.h 2013-08-21 11:40:25 +0000
+++ ubuntu-download-manager-tests/test_download_daemon.h 2013-08-22 21:00:52 +0000
@@ -23,6 +23,8 @@
23#include <download_daemon.h>23#include <download_daemon.h>
24#include "./fake_application.h"24#include "./fake_application.h"
25#include "./fake_dbus_connection.h"25#include "./fake_dbus_connection.h"
26#include "./fake_download_manager.h"
27#include "./fake_timer.h"
26#include "./test_runner.h"28#include "./test_runner.h"
2729
28class TestDownloadDaemon : public QObject {30class TestDownloadDaemon : public QObject {
@@ -38,9 +40,14 @@
38 void testStart();40 void testStart();
39 void testStartFailServiceRegister();41 void testStartFailServiceRegister();
40 void testStartFailObjectRegister();42 void testStartFailObjectRegister();
43 void testTimerStop();
44 void testTimerStart();
45 void testTimeoutExit();
4146
42 private:47 private:
48 FakeTimer* _timer;
43 FakeApplication* _app;49 FakeApplication* _app;
50 FakeDownloadManager* _man;
44 FakeDBusConnection* _conn;51 FakeDBusConnection* _conn;
45 DownloadDaemon* _daemon;52 DownloadDaemon* _daemon;
46};53};
4754
=== modified file 'ubuntu-download-manager-tests/test_download_manager.cpp'
--- ubuntu-download-manager-tests/test_download_manager.cpp 2013-07-26 14:05:22 +0000
+++ ubuntu-download-manager-tests/test_download_manager.cpp 2013-08-22 21:00:52 +0000
@@ -387,3 +387,47 @@
387 QCOMPARE(download->throttle(), speed);387 QCOMPARE(download->throttle(), speed);
388 }388 }
389}389}
390
391void
392TestDownloadManager::testSizeChangedEmittedOnAddition_data() {
393 QTest::addColumn<int>("size");
394
395 QTest::newRow("First row") << 4;
396 QTest::newRow("Second row") << 5;
397 QTest::newRow("Third row") << 0;
398 QTest::newRow("Last row") << 34;
399}
400
401void
402TestDownloadManager::testSizeChangedEmittedOnAddition() {
403 QFETCH(int, size);
404 QSignalSpy spy(_man, SIGNAL(sizeChanged(int)));
405 _q->setSize(size);
406 _q->emitDownloadAdded("");
407
408 QCOMPARE(spy.count(), 1);
409 QList<QVariant> arguments = spy.takeFirst();
410 QCOMPARE(arguments.at(0).toInt(), size);
411}
412
413void
414TestDownloadManager::testSizeChangedEmittedOnRemoval_data() {
415 QTest::addColumn<int>("size");
416
417 QTest::newRow("First row") << 4;
418 QTest::newRow("Second row") << 5;
419 QTest::newRow("Third row") << 0;
420 QTest::newRow("Last row") << 34;
421}
422
423void
424TestDownloadManager::testSizeChangedEmittedOnRemoval() {
425 QFETCH(int, size);
426 QSignalSpy spy(_man, SIGNAL(sizeChanged(int)));
427 _q->setSize(size);
428 _q->emitDownloadRemoved("");
429
430 QCOMPARE(spy.count(), 1);
431 QList<QVariant> arguments = spy.takeFirst();
432 QCOMPARE(arguments.at(0).toInt(), size);
433}
390434
=== modified file 'ubuntu-download-manager-tests/test_download_manager.h'
--- ubuntu-download-manager-tests/test_download_manager.h 2013-07-26 14:05:22 +0000
+++ ubuntu-download-manager-tests/test_download_manager.h 2013-08-22 21:00:52 +0000
@@ -44,6 +44,8 @@
44 void testCreateDownloadWithHash_data();44 void testCreateDownloadWithHash_data();
45 void testSetThrottleNotDownloads_data();45 void testSetThrottleNotDownloads_data();
46 void testSetThrottleWithDownloads_data();46 void testSetThrottleWithDownloads_data();
47 void testSizeChangedEmittedOnAddition_data();
48 void testSizeChangedEmittedOnRemoval_data();
4749
48 // tests50 // tests
49 void testCreateDownload();51 void testCreateDownload();
@@ -52,6 +54,8 @@
52 void testAllDownloadsWithMetadata();54 void testAllDownloadsWithMetadata();
53 void testSetThrottleNotDownloads();55 void testSetThrottleNotDownloads();
54 void testSetThrottleWithDownloads();56 void testSetThrottleWithDownloads();
57 void testSizeChangedEmittedOnAddition();
58 void testSizeChangedEmittedOnRemoval();
5559
56 private:60 private:
57 QCryptographicHash::Algorithm algoFromString(const QString& data);61 QCryptographicHash::Algorithm algoFromString(const QString& data);
5862
=== modified file 'ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro'
--- ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro 2013-08-21 11:40:25 +0000
+++ ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro 2013-08-22 21:00:52 +0000
@@ -32,7 +32,9 @@
32 fake_system_network_info.cpp \32 fake_system_network_info.cpp \
33 fake_process.cpp \33 fake_process.cpp \
34 fake_process_factory.cpp \34 fake_process_factory.cpp \
35 fake_application.cpp35 fake_application.cpp \
36 fake_timer.cpp \
37 fake_download_manager.cpp
3638
37HEADERS += \39HEADERS += \
38 fake.h \40 fake.h \
@@ -53,7 +55,9 @@
53 fake_system_network_info.h \55 fake_system_network_info.h \
54 fake_process.h \56 fake_process.h \
55 fake_process_factory.h \57 fake_process_factory.h \
56 fake_application.h58 fake_application.h \
59 fake_timer.h \
60 fake_download_manager.h
5761
58LIBS += -L$$OUT_PWD/../libubuntudownloadmanager/ -lubuntudownloadmanager62LIBS += -L$$OUT_PWD/../libubuntudownloadmanager/ -lubuntudownloadmanager
5963
6064
=== modified file 'ubuntu-download-manager/ubuntu-download-manager.pro'
--- ubuntu-download-manager/ubuntu-download-manager.pro 2013-07-21 20:16:06 +0000
+++ ubuntu-download-manager/ubuntu-download-manager.pro 2013-08-22 21:00:52 +0000
@@ -4,7 +4,7 @@
4#4#
5#-------------------------------------------------5#-------------------------------------------------
66
7QT += core7QT += core systeminfo
88
9QT -= gui9QT -= gui
1010

Subscribers

People subscribed via source and target branches