Merge lp:~renatofilho/address-book-app/fix-1469005 into lp:address-book-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 486
Merged at revision: 497
Proposed branch: lp:~renatofilho/address-book-app/fix-1469005
Merge into: lp:address-book-app
Prerequisite: lp:~renatofilho/address-book-app/update-autopilot-with-new-bottom-edge
Diff against target: 291 lines (+69/-45)
6 files modified
src/imports/Ubuntu/AddressBook/ContactEditor/AvatarImport.qml (+1/-4)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml (+24/-3)
src/imports/Ubuntu/Contacts/contacts.cpp (+10/-21)
src/imports/Ubuntu/Contacts/contacts.h (+2/-1)
src/imports/Ubuntu/Contacts/imagescalethread.cpp (+25/-11)
src/imports/Ubuntu/Contacts/imagescalethread.h (+7/-5)
To merge this branch: bzr merge lp:~renatofilho/address-book-app/fix-1469005
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+276046@code.launchpad.net

This proposal supersedes a proposal from 2015-10-19.

Commit message

Use Runnable implementation instead of thread to avoid overload cpu usage.
Implement async copyImage support.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/AvatarImport.qml'
2--- src/imports/Ubuntu/AddressBook/ContactEditor/AvatarImport.qml 2015-10-26 13:18:11 +0000
3+++ src/imports/Ubuntu/AddressBook/ContactEditor/AvatarImport.qml 2015-10-28 19:43:37 +0000
4@@ -59,7 +59,6 @@
5 id: peerPicker
6
7 anchors.fill: parent
8- visible: dialogue.done
9 contentType: ContentType.Pictures
10 handler: ContentHandler.Source
11
12@@ -77,13 +76,11 @@
13 Connections {
14 id: signalConnections
15
16- target: dialogue.activeTransfer
17 onStateChanged: {
18 var done = ((dialogue.activeTransfer.state === ContentTransfer.Charged) ||
19 (dialogue.activeTransfer.state === ContentTransfer.Aborted))
20
21 if (dialogue.activeTransfer.state === ContentTransfer.Charged) {
22- dialogue.hide()
23 if (dialogue.activeTransfer.items.length > 0) {
24 root.avatarReceived(dialogue.activeTransfer.items[0].url)
25 }
26@@ -108,7 +105,7 @@
27 repeat: true
28 running: false
29 onTriggered: {
30- if(Qt.application.active) {
31+ if(Qt.application.state === Qt.ApplicationActive) {
32 PopupUtils.close(root.importDialog)
33 }
34 }
35
36=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml'
37--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml 2015-10-26 13:18:11 +0000
38+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml 2015-10-28 19:43:37 +0000
39@@ -27,6 +27,8 @@
40
41 readonly property alias busy: activityIndicator.running
42 readonly property string defaultAvatar: "image://theme/add"
43+ property string temporaryAvatar: ""
44+ property string temporaryAvatarId: ""
45
46 function isEmpty() {
47 return false;
48@@ -101,7 +103,7 @@
49 id: activityIndicator
50
51 anchors.centerIn: avatar
52- running: (avatarImport.importDialog != null)
53+ running: (avatarImport.importDialog != null) || (root.temporaryAvatarId != "")
54 visible: running
55 }
56
57@@ -109,12 +111,25 @@
58 id: avatarImport
59
60 onAvatarReceived: {
61+ Contacts.removeFile(root.temporaryAvatar)
62+
63 // remove the previous image, this is nessary to make sure that the new image
64 // get updated otherwise if the new image has the same name the image will not
65 // be updated
66 avatarImage.source = ""
67- // Update with the new value
68- avatarImage.source = Contacts.copyImage(root.contact, avatarUrl);
69+ // copy and resize image
70+ root.temporaryAvatarId = Contacts.copyImage(avatarUrl, null);
71+ }
72+ }
73+
74+ Connections {
75+ target: Contacts
76+ onImageCopyDone: {
77+ if (root.temporaryAvatarId === id) {
78+ root.temporaryAvatar = fileName
79+ avatarImage.source = fileName
80+ root.temporaryAvatarId = ""
81+ }
82 }
83 }
84
85@@ -126,6 +141,12 @@
86 avatarImport.requestNewAvatar()
87 }
88 }
89+
90+ Component.onDestruction: {
91+ console.debug("Delete temporary avatar image:" + root.temporaryAvatar)
92+ Contacts.removeFile("file:///" + root.temporaryAvatar)
93+ root.temporaryAvatar = ""
94+ }
95 }
96
97
98
99=== modified file 'src/imports/Ubuntu/Contacts/contacts.cpp'
100--- src/imports/Ubuntu/Contacts/contacts.cpp 2015-10-14 22:53:35 +0000
101+++ src/imports/Ubuntu/Contacts/contacts.cpp 2015-10-28 19:43:37 +0000
102@@ -23,6 +23,7 @@
103 #include <QtCore/QDir>
104 #include <QtCore/QUrl>
105 #include <QtCore/QLockFile>
106+#include <QtCore/QThreadPool>
107
108 #include "config.h"
109
110@@ -77,27 +78,11 @@
111 return out;
112 }
113
114-QUrl UbuntuContacts::copyImage(QObject *contact, const QUrl &imageUrl)
115+QString UbuntuContacts::copyImage(const QUrl &imageUrl)
116 {
117- // keep track of threads to avoid memory leeak
118- ImageScaleThread *imgThread;
119- QVariant oldThread = contact->property("IMAGE_SCALE_THREAD");
120- if (!oldThread.isNull()) {
121- imgThread = oldThread.value<ImageScaleThread *>();
122- imgThread->updateImageUrl(imageUrl);
123- } else {
124- imgThread = new ImageScaleThread(imageUrl, contact);
125- contact->setProperty("IMAGE_SCALE_THREAD", QVariant::fromValue<ImageScaleThread*>(imgThread));
126- }
127-
128- imgThread->start();
129-
130- // FIXME: implement this as async function
131- while(imgThread->isRunning()) {
132- QCoreApplication::processEvents(QEventLoop::AllEvents, 3000);
133- }
134-
135- return imgThread->outputFile();
136+ ImageScaleThread *imgThread = new ImageScaleThread(imageUrl, this);
137+ QThreadPool::globalInstance()->start(imgThread);
138+ return imgThread->id();
139 }
140
141 bool UbuntuContacts::containsLetters(const QString &value)
142@@ -112,7 +97,11 @@
143
144 bool UbuntuContacts::removeFile(const QUrl &file)
145 {
146- return QFile::remove(file.toLocalFile());
147+ QString localFile = file.toLocalFile();
148+ if (!localFile.isEmpty() && QFile::exists(localFile)) {
149+ return QFile::remove(localFile);
150+ }
151+ return false;
152 }
153
154 bool UbuntuContacts::updateIsRunning() const
155
156=== modified file 'src/imports/Ubuntu/Contacts/contacts.h'
157--- src/imports/Ubuntu/Contacts/contacts.h 2015-10-13 12:50:14 +0000
158+++ src/imports/Ubuntu/Contacts/contacts.h 2015-10-28 19:43:37 +0000
159@@ -36,12 +36,13 @@
160
161 Q_INVOKABLE QString contactInitialsFromString(const QString &value);
162 Q_INVOKABLE QString normalized(const QString &value);
163- Q_INVOKABLE QUrl copyImage(QObject *contact, const QUrl &imageUrl);
164+ Q_INVOKABLE QString copyImage(const QUrl &imageUrl);
165 Q_INVOKABLE bool containsLetters(const QString &value);
166 Q_INVOKABLE bool removeFile(const QUrl &file);
167 Q_INVOKABLE bool updateIsRunning() const;
168
169 Q_SIGNALS:
170+ void imageCopyDone(const QString &id, const QString &fileName);
171 void updateIsRunningChanged();
172
173 private:
174
175=== modified file 'src/imports/Ubuntu/Contacts/imagescalethread.cpp'
176--- src/imports/Ubuntu/Contacts/imagescalethread.cpp 2015-05-07 17:27:16 +0000
177+++ src/imports/Ubuntu/Contacts/imagescalethread.cpp 2015-10-28 19:43:37 +0000
178@@ -20,39 +20,46 @@
179 #include <QImageReader>
180 #include <QFile>
181 #include <QDir>
182+#include <QUuid>
183 #include <QDebug>
184
185-ImageScaleThread::ImageScaleThread(const QUrl &imageUrl, QObject *parent)
186- : QThread(parent),
187- m_imageUrl(imageUrl),
188- m_tmpFile(0)
189+ImageScaleThread::ImageScaleThread(const QUrl &imageUrl, QObject *listener)
190+ : m_imageUrl(imageUrl),
191+ m_id(QUuid::createUuid().toString()),
192+ m_listener(listener),
193+ m_tmpFile(0)
194 {
195 }
196
197 ImageScaleThread::~ImageScaleThread()
198 {
199 if (m_tmpFile) {
200- delete m_tmpFile;
201+ m_tmpFile->setAutoRemove(false);
202+ m_tmpFile->deleteLater();
203+ m_tmpFile = 0;
204 }
205 }
206
207-void ImageScaleThread::updateImageUrl(const QUrl &imageUrl)
208+QString ImageScaleThread::id()
209 {
210- if (isRunning()) {
211- wait();
212- }
213- m_imageUrl = imageUrl;
214+ return m_id;
215 }
216
217 QString ImageScaleThread::outputFile() const
218 {
219- return m_tmpFile->fileName();
220+ if (m_tmpFile) {
221+ return m_tmpFile->fileName();
222+ } else {
223+ return QString();
224+ }
225 }
226
227 void ImageScaleThread::run()
228 {
229 // make sure that the old image get deleted
230 if (m_tmpFile) {
231+ qDebug() << "Delete previous avatar" << m_tmpFile->fileName();
232+ m_tmpFile->setAutoRemove(true);
233 m_tmpFile->close();
234 delete m_tmpFile;
235 }
236@@ -60,6 +67,7 @@
237 // Create the temporary file
238 m_tmpFile = new QTemporaryFile(QString("%1/avatar_XXXXXX.png").arg(QDir::tempPath()));
239 if (!m_tmpFile->open()) {
240+ qWarning() << "Fail to create avatar temporary file";
241 return;
242 }
243
244@@ -91,5 +99,11 @@
245 if (!scaledAvatar.isNull()) {
246 scaledAvatar.save(m_tmpFile, "png");
247 }
248+
249 m_tmpFile->close();
250+
251+ if (m_listener) {
252+ QMetaObject::invokeMethod(m_listener, "imageCopyDone",
253+ Q_ARG(QString, m_id), Q_ARG(QString, m_tmpFile->fileName()));
254+ }
255 }
256
257=== modified file 'src/imports/Ubuntu/Contacts/imagescalethread.h'
258--- src/imports/Ubuntu/Contacts/imagescalethread.h 2015-05-07 17:27:16 +0000
259+++ src/imports/Ubuntu/Contacts/imagescalethread.h 2015-10-28 19:43:37 +0000
260@@ -18,18 +18,18 @@
261 #define IMAGESCALETHREAD_H
262
263 #include <QObject>
264-#include <QThread>
265+#include <QRunnable>
266 #include <QUrl>
267+#include <QPointer>
268 #include <QTemporaryFile>
269
270-class ImageScaleThread : public QThread
271+class ImageScaleThread : public QRunnable
272 {
273- Q_OBJECT
274 public:
275- ImageScaleThread(const QUrl &imageUrl, QObject *parent=0);
276+ ImageScaleThread(const QUrl &imageUrl, QObject *listener);
277 ~ImageScaleThread();
278
279- void updateImageUrl(const QUrl &imageUrl);
280+ QString id();
281 QString outputFile() const;
282
283 protected:
284@@ -37,6 +37,8 @@
285
286 private:
287 QUrl m_imageUrl;
288+ QString m_id;
289+ QPointer<QObject> m_listener;
290 QTemporaryFile *m_tmpFile;
291 };
292

Subscribers

People subscribed via source and target branches