Merge lp:~mzanetti/reminders-app/enable-attaching-images into lp:reminders-app

Proposed by Michael Zanetti
Status: Merged
Approved by: David Planella
Approved revision: 46
Merged at revision: 31
Proposed branch: lp:~mzanetti/reminders-app/enable-attaching-images
Merge into: lp:reminders-app
Diff against target: 757 lines (+341/-50)
18 files modified
run_on_ubuntu_touch.sh (+1/-1)
src/app/qml/reminders-app.qml (+12/-0)
src/app/qml/ui/EditNotePage.qml (+31/-3)
src/app/qml/ui/NotesPage.qml (+2/-2)
src/plugin/Evernote/CMakeLists.txt (+1/-0)
src/plugin/Evernote/evernoteplugin.cpp (+2/-0)
src/plugin/Evernote/jobs/createnotejob.cpp (+10/-6)
src/plugin/Evernote/jobs/createnotejob.h (+1/-1)
src/plugin/Evernote/jobs/savenotejob.cpp (+27/-0)
src/plugin/Evernote/note.cpp (+35/-12)
src/plugin/Evernote/note.h (+10/-8)
src/plugin/Evernote/notesstore.cpp (+6/-9)
src/plugin/Evernote/notesstore.h (+3/-2)
src/plugin/Evernote/resource.cpp (+92/-0)
src/plugin/Evernote/resource.h (+52/-0)
src/plugin/Evernote/resourceimageprovider.cpp (+1/-1)
src/plugin/Evernote/utils/enmldocument.cpp (+52/-4)
src/plugin/Evernote/utils/enmldocument.h (+3/-1)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/enable-attaching-images
Reviewer Review Type Date Requested Status
David Planella Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+202817@code.launchpad.net

Commit message

Enable attaching and uploading images

To post a comment you must log in.
46. By Michael Zanetti

cleanup

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
David Planella (dpm) wrote :

Here's what I did:

1. Create a new note
2. Change the note's title
3. Add some text to the note
4. Press the attach button to attach an image
5. Pick an image from the device after the Content Hub brings up the gallery app
6. I'm now back to the note, although there is no visual feedback that the note has an attached image
7. I press save
8. On the list of notes, my new note is called Untitled, regardless of the fact that I did give it a name
9. When I click on the note to view it, the title is then as expected, and I can see the image in the note's body
10. However, when I go to sandbox.evernote.com, I can only see a note called Untitled, with no content at all (neither the text, nor the image)

Here's the debug output that I got when I performed these steps:
http://pastebin.ubuntu.com/6802363/

review: Needs Fixing
Revision history for this message
David Planella (dpm) wrote :

I forgot to say: after these steps have been followed, the 'add note' button no longer works.

Revision history for this message
David Planella (dpm) wrote :

More feedback:

- If I create a note and save it, and then go back to it and attach the image, then it all works: the note contains the image and that note + image appear in sandbox.evernote.com

However, the fact that after adding an image the 'add note' button no longer works still remains.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

I can't reproduce it... the steps you described seem to work fine here.

Revision history for this message
David Planella (dpm) wrote :

LGTM, works now after having upgraded to the latest image.

review: Approve
Revision history for this message
David Planella (dpm) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'run_on_ubuntu_touch.sh'
2--- run_on_ubuntu_touch.sh 2014-01-07 12:21:44 +0000
3+++ run_on_ubuntu_touch.sh 2014-01-23 09:46:22 +0000
4@@ -79,7 +79,7 @@
5 }
6
7 run() {
8- exec_with_ssh "cd $CODE_DIR/$BUILD_DIR/src/app/ && ./$BINARY --desktop_file_hint=$CODE_DIR/reminders-app.desktop"
9+ exec_with_ssh "cd $CODE_DIR/$BUILD_DIR/src/app/ && ./$BINARY --desktop_file_hint=/home/phablet/$CODE_DIR/reminders-app.desktop"
10 }
11
12 set -- `getopt -n$0 -u -a --longoptions="setup,gdb,click,help" "sgch" "$@"`
13
14=== modified file 'src/app/qml/reminders-app.qml'
15--- src/app/qml/reminders-app.qml 2013-12-14 23:59:04 +0000
16+++ src/app/qml/reminders-app.qml 2014-01-23 09:46:22 +0000
17@@ -59,6 +59,18 @@
18 }
19 }
20
21+ Connections {
22+ target: NotesStore
23+ onNoteCreated: {
24+ var note = NotesStore.note(guid);
25+ print("note created:", note.guid);
26+ var component = Qt.createComponent(Qt.resolvedUrl("ui/EditNotePage.qml"));
27+ var page = component.createObject(pageStack)
28+ page.note = note;
29+ pagestack.push(page);
30+ }
31+ }
32+
33 PageStack {
34 id: pagestack
35
36
37=== modified file 'src/app/qml/ui/EditNotePage.qml'
38--- src/app/qml/ui/EditNotePage.qml 2013-12-17 23:19:58 +0000
39+++ src/app/qml/ui/EditNotePage.qml 2014-01-23 09:46:22 +0000
40@@ -19,6 +19,7 @@
41 import QtQuick 2.0
42 import Ubuntu.Components 0.1
43 import Ubuntu.Components.ListItems 0.1
44+import Ubuntu.Content 0.1
45 import Evernote 0.1
46 import "../components"
47
48@@ -51,6 +52,14 @@
49
50 ToolbarButton {
51 text: "attach"
52+ onTriggered: {
53+ priv.insertPosition = noteTextArea.cursorPosition;
54+ note.richTextContent = noteTextArea.text;
55+
56+ priv.activeTransfer = ContentHub.importContent(ContentType.Pictures);
57+ priv.activeTransfer.selectionType = ContentTransfer.Single;
58+ priv.activeTransfer.start();
59+ }
60 }
61 ToolbarButton {
62 text: "camera"
63@@ -59,8 +68,28 @@
64 ToolbarButton {
65 text: "rtf"
66 }
67-
68- }
69+ }
70+
71+ QtObject {
72+ id: priv
73+ property int insertPosition
74+ property var activeTransfer
75+ }
76+
77+ ContentImportHint {
78+ id: importHint
79+ anchors.fill: parent
80+ activeTransfer: root.activeTransfer
81+ }
82+ Connections {
83+ target: priv.activeTransfer ? priv.activeTransfer : null
84+ onStateChanged: {
85+ if (priv.activeTransfer.state === ContentTransfer.Charged) {
86+ print("attaching", priv.activeTransfer.items[0].url.toString())
87+ note.attachFile(priv.insertPosition, priv.activeTransfer.items[0].url.toString())
88+ }
89+ }
90+ }
91
92 Column {
93 anchors.fill: parent
94@@ -99,7 +128,6 @@
95
96 textFormat: TextEdit.RichText
97 text: root.note ? root.note.richTextContent : ""
98-
99 }
100 }
101 }
102
103=== modified file 'src/app/qml/ui/NotesPage.qml'
104--- src/app/qml/ui/NotesPage.qml 2013-12-15 01:57:25 +0000
105+++ src/app/qml/ui/NotesPage.qml 2014-01-23 09:46:22 +0000
106@@ -49,7 +49,7 @@
107 text: "add note"
108 iconName: "add"
109 onTriggered: {
110- pagestack.push(Qt.resolvedUrl("EditNotePage.qml"));
111+ NotesStore.createNote("Untitled");
112 }
113 }
114 }
115@@ -68,7 +68,7 @@
116 title: model.title
117 creationDate: model.created
118 content: model.plaintextContent
119- resource: model.resources.length > 0 ? model.resources[0] : ""
120+ resource: model.resourceUrls.length > 0 ? model.resourceUrls[0] : ""
121
122 onClicked: {
123 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})
124
125=== modified file 'src/plugin/Evernote/CMakeLists.txt'
126--- src/plugin/Evernote/CMakeLists.txt 2014-01-19 13:59:12 +0000
127+++ src/plugin/Evernote/CMakeLists.txt 2014-01-23 09:46:22 +0000
128@@ -11,6 +11,7 @@
129 notebooks.cpp
130 notes.cpp
131 note.cpp
132+ resource.cpp
133 notebook.cpp
134 jobs/fetchnotesjob.cpp
135 jobs/fetchnotebooksjob.cpp
136
137=== modified file 'src/plugin/Evernote/evernoteplugin.cpp'
138--- src/plugin/Evernote/evernoteplugin.cpp 2013-12-15 01:57:25 +0000
139+++ src/plugin/Evernote/evernoteplugin.cpp 2014-01-23 09:46:22 +0000
140@@ -26,6 +26,7 @@
141 #include "notes.h"
142 #include "notebooks.h"
143 #include "note.h"
144+#include "resource.h"
145 #include "notebook.h"
146 #include "resourceimageprovider.h"
147
148@@ -56,6 +57,7 @@
149 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");
150 qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");
151 qmlRegisterUncreatableType<Notebook>("Evernote", 0, 1, "Notebook", "Cannot create Notes in QML. Use NotesStore.createNotebook() instead.");
152+ qmlRegisterUncreatableType<Resource>("Evernote", 0, 1, "Resource", "Cannot create Resources. Use Note.attachFile() instead.");
153 }
154
155 void EvernotePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
156
157=== modified file 'src/plugin/Evernote/jobs/createnotejob.cpp'
158--- src/plugin/Evernote/jobs/createnotejob.cpp 2013-11-28 00:39:33 +0000
159+++ src/plugin/Evernote/jobs/createnotejob.cpp 2014-01-23 09:46:22 +0000
160@@ -35,12 +35,16 @@
161 evernote::edam::Note input;
162 input.title = m_title.toStdString();
163 input.__isset.title = true;
164- input.notebookGuid = m_notebookGuid.toStdString();
165- input.__isset.notebookGuid = true;
166- input.content = m_content.toStdString();
167- input.__isset.content = true;
168- input.contentLength = m_content.length();
169- input.__isset.contentLength = true;
170+ if (!m_notebookGuid.isEmpty()) {
171+ input.notebookGuid = m_notebookGuid.toStdString();
172+ input.__isset.notebookGuid = true;
173+ }
174+ if (!m_content.isEmpty()) {
175+ input.content = m_content.toStdString();
176+ input.__isset.content = true;
177+ input.contentLength = m_content.length();
178+ input.__isset.contentLength = true;
179+ }
180
181 client()->createNote(m_resultNote, token().toStdString(), input);
182 }
183
184=== modified file 'src/plugin/Evernote/jobs/createnotejob.h'
185--- src/plugin/Evernote/jobs/createnotejob.h 2013-11-29 20:58:04 +0000
186+++ src/plugin/Evernote/jobs/createnotejob.h 2014-01-23 09:46:22 +0000
187@@ -27,7 +27,7 @@
188 {
189 Q_OBJECT
190 public:
191- explicit CreateNoteJob(const QString &title, const QString &notebookGuid, const QString &content, QObject *parent = 0);
192+ explicit CreateNoteJob(const QString &title, const QString &notebookGuid = QString(), const QString &content = QString(), QObject *parent = 0);
193
194 signals:
195 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, evernote::edam::Note note);
196
197=== modified file 'src/plugin/Evernote/jobs/savenotejob.cpp'
198--- src/plugin/Evernote/jobs/savenotejob.cpp 2013-12-14 22:38:57 +0000
199+++ src/plugin/Evernote/jobs/savenotejob.cpp 2014-01-23 09:46:22 +0000
200@@ -54,6 +54,33 @@
201 note.attributes.reminderDoneTime = m_note->reminderDoneTime().toMSecsSinceEpoch();
202 note.attributes.__isset.reminderDoneTime = true;
203
204+ note.resources.clear();
205+ foreach (Resource *resource, m_note->resources()) {
206+ evernote::edam::Resource evResource;
207+ evResource.noteGuid = m_note->guid().toStdString();
208+ evResource.__isset.noteGuid = true;
209+ evResource.mime = resource->type().toStdString();
210+ evResource.__isset.mime = true;
211+
212+ evResource.data.bodyHash = resource->hash().toStdString();
213+ evResource.data.__isset.bodyHash = true;
214+
215+ QByteArray data = resource->data();
216+ evResource.data.body.assign(data.data(), data.length());
217+ evResource.data.__isset.body = true;
218+
219+ evResource.data.size = data.length();
220+ evResource.data.__isset.size = true;
221+ evResource.__isset.data = true;
222+
223+ evResource.attributes.fileName = resource->fileName().toStdString();
224+ evResource.attributes.__isset.fileName = true;
225+ evResource.__isset.attributes = true;
226+
227+ note.resources.push_back(evResource);
228+ }
229+ note.__isset.resources = true;
230+
231 client()->updateNote(m_resultNote, token().toStdString(), note);
232 }
233
234
235=== modified file 'src/plugin/Evernote/note.cpp'
236--- src/plugin/Evernote/note.cpp 2013-12-18 22:35:03 +0000
237+++ src/plugin/Evernote/note.cpp 2014-01-23 09:46:22 +0000
238@@ -27,6 +27,8 @@
239 #include <QUrlQuery>
240 #include <QStandardPaths>
241 #include <QDebug>
242+#include <QCryptographicHash>
243+#include <QFile>
244
245 Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :
246 QObject(parent),
247@@ -36,6 +38,11 @@
248 {
249 }
250
251+Note::~Note()
252+{
253+ qDeleteAll(m_resources.values());
254+}
255+
256 QString Note::guid() const
257 {
258 return m_guid;
259@@ -189,11 +196,16 @@
260 }
261 }
262
263-QStringList Note::resources() const
264+QList<Resource*> Note::resources() const
265+{
266+ return m_resources.values();
267+}
268+
269+QStringList Note::resourceUrls() const
270 {
271 QList<QString> ret;
272 foreach (const QString &hash, m_resources.keys()) {
273- QUrl url("image://resource/" + m_resourceTypes.value(hash));
274+ QUrl url("image://resource/" + m_resources.value(hash)->type());
275 QUrlQuery arguments;
276 arguments.addQueryItem("noteGuid", m_guid);
277 arguments.addQueryItem("hash", hash);
278@@ -203,24 +215,24 @@
279 return ret;
280 }
281
282-QImage Note::resource(const QString &hash)
283+Resource* Note::resource(const QString &hash)
284 {
285 return m_resources.value(hash);
286 }
287
288-QString Note::resourceName(const QString &hash)
289+
290+Resource* Note::addResource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type)
291 {
292- return m_resourceNames.value(hash);
293+ Resource *resource = new Resource(data, hash, fileName, type, this);
294+ m_resources.insert(hash, resource);
295+ return resource;
296 }
297
298-void Note::addResource(const QString &hash, const QString &fileName, const QString &type, const QImage &image)
299+Resource *Note::addResource(const QString &fileName)
300 {
301- image.save(QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first() + "/" + hash + "." + type.split('/').last());
302- if (!image.isNull()) {
303- m_resources.insert(hash, image);
304- }
305- m_resourceTypes.insert(hash, type);
306- m_resourceNames.insert(hash, fileName);
307+ Resource *resource = new Resource(fileName);
308+ m_resources.insert(resource->hash(), resource);
309+ return resource;
310 }
311
312 void Note::markTodo(const QString &todoId, bool checked)
313@@ -228,6 +240,13 @@
314 m_content.markTodo(todoId, checked);
315 }
316
317+void Note::attachFile(int position, const QUrl &fileName)
318+{
319+ Resource *resource = addResource(fileName.path());
320+ m_content.attachFile(position, fileName.path(), resource->hash(), resource->type());
321+ emit contentChanged();
322+}
323+
324 Note *Note::clone()
325 {
326 Note *note = new Note(m_guid, m_created);
327@@ -238,6 +257,10 @@
328 note->setReminderTime(m_reminderTime);
329 note->setReminderDoneTime(m_reminderDoneTime);
330 note->setIsSearchResult(m_isSearchResult);
331+ foreach (Resource *resource, m_resources) {
332+ note->addResource(resource->data(), resource->hash(), resource->fileName(), resource->type());
333+ }
334+
335 return note;
336 }
337
338
339=== modified file 'src/plugin/Evernote/note.h'
340--- src/plugin/Evernote/note.h 2014-01-10 12:00:26 +0000
341+++ src/plugin/Evernote/note.h 2014-01-23 09:46:22 +0000
342@@ -22,6 +22,7 @@
343 #define NOTE_H
344
345 #include "utils/enmldocument.h"
346+#include "resource.h"
347
348 #include <QObject>
349 #include <QDateTime>
350@@ -41,7 +42,7 @@
351 Q_PROPERTY(QString richTextContent READ richTextContent WRITE setRichTextContent NOTIFY contentChanged)
352 Q_PROPERTY(QString enmlContent READ enmlContent WRITE setEnmlContent NOTIFY contentChanged)
353 Q_PROPERTY(QString plaintextContent READ plaintextContent NOTIFY contentChanged)
354- Q_PROPERTY(QList<QString> resources READ resources NOTIFY contentChanged)
355+ Q_PROPERTY(QStringList resourceUrls READ resourceUrls NOTIFY contentChanged)
356 Q_PROPERTY(bool reminder READ reminder WRITE setReminder NOTIFY reminderChanged)
357 Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)
358 Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)
359@@ -51,6 +52,7 @@
360
361 public:
362 explicit Note(const QString &guid, const QDateTime &created, QObject *parent = 0);
363+ ~Note();
364
365 QString guid() const;
366
367@@ -96,12 +98,14 @@
368 bool isSearchResult() const;
369 void setIsSearchResult(bool isSearchResult);
370
371- QStringList resources() const;
372- QImage resource(const QString &hash);
373- QString resourceName(const QString &hash);
374- void addResource(const QString &hash, const QString &fileName, const QString &type, const QImage &image = QImage());
375+ QStringList resourceUrls() const;
376+ Resource* resource(const QString &hash);
377+ QList<Resource*> resources() const;
378+ Resource *addResource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type);
379+ Resource *addResource(const QString &fileName);
380
381 Q_INVOKABLE void markTodo(const QString &todoId, bool checked);
382+ Q_INVOKABLE void attachFile(int position, const QUrl &fileName);
383
384 Note* clone();
385
386@@ -128,9 +132,7 @@
387 QDateTime m_reminderTime;
388 QDateTime m_reminderDoneTime;
389 bool m_isSearchResult;
390- QHash<QString, QImage> m_resources;
391- QHash<QString, QString> m_resourceTypes;
392- QHash<QString, QString> m_resourceNames;
393+ QHash<QString, Resource*> m_resources;
394 };
395
396 #endif // NOTE_H
397
398=== modified file 'src/plugin/Evernote/notesstore.cpp'
399--- src/plugin/Evernote/notesstore.cpp 2013-12-18 22:35:03 +0000
400+++ src/plugin/Evernote/notesstore.cpp 2014-01-23 09:46:22 +0000
401@@ -93,8 +93,8 @@
402 return m_notes.at(index.row())->richTextContent();
403 case RolePlaintextContent:
404 return m_notes.at(index.row())->plaintextContent();
405- case RoleResources:
406- return m_notes.at(index.row())->resources();
407+ case RoleResourceUrls:
408+ return m_notes.at(index.row())->resourceUrls();
409 }
410 return QVariant();
411 }
412@@ -114,7 +114,7 @@
413 roles.insert(RoleRichTextContent, "richTextContent");
414 roles.insert(RoleHtmlContent, "htmlContent");
415 roles.insert(RolePlaintextContent, "plaintextContent");
416- roles.insert(RoleResources, "resources");
417+ roles.insert(RoleResourceUrls, "resourceUrls");
418 return roles;
419 }
420
421@@ -235,12 +235,8 @@
422 QString fileName = QString::fromStdString(resource.attributes.fileName);
423 QString mime = QString::fromStdString(resource.mime);
424
425- if (mime.startsWith("image/")) {
426- QImage image = QImage::fromData((const uchar*)resource.data.body.data(), resource.data.size);
427- note->addResource(hash, fileName, mime, image);
428- } else {
429- note->addResource(hash, fileName, mime);
430- }
431+ QByteArray resourceData = QByteArray(resource.data.body.data(), resource.data.size);
432+ note->addResource(resourceData, hash, fileName, mime);
433 }
434
435 note->setEnmlContent(QString::fromStdString(result.content));
436@@ -324,6 +320,7 @@
437 endInsertRows();
438
439 emit noteAdded(note->guid(), note->notebookGuid());
440+ emit noteCreated(note->guid(), note->notebookGuid());
441 }
442
443 void NotesStore::saveNote(const QString &guid)
444
445=== modified file 'src/plugin/Evernote/notesstore.h'
446--- src/plugin/Evernote/notesstore.h 2014-01-10 12:00:26 +0000
447+++ src/plugin/Evernote/notesstore.h 2014-01-23 09:46:22 +0000
448@@ -63,7 +63,7 @@
449 RoleHtmlContent,
450 RoleRichTextContent,
451 RolePlaintextContent,
452- RoleResources
453+ RoleResourceUrls
454 };
455
456 ~NotesStore();
457@@ -77,7 +77,7 @@
458 QList<Note*> notes() const;
459
460 Q_INVOKABLE Note* note(const QString &guid);
461- Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &richTextContent);
462+ Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid = QString(), const QString &richTextContent = QString());
463 void createNote(const QString &title, const QString &notebookGuid, const EnmlDocument &content);
464 Q_INVOKABLE void saveNote(const QString &guid);
465 Q_INVOKABLE void deleteNote(const QString &guid);
466@@ -96,6 +96,7 @@
467 signals:
468 void tokenChanged();
469
470+ void noteCreated(const QString &guid, const QString &notebookGuid);
471 void noteAdded(const QString &guid, const QString &notebookGuid);
472 void noteChanged(const QString &guid, const QString &notebookGuid);
473 void noteRemoved(const QString &guid, const QString &notebookGuid);
474
475=== added file 'src/plugin/Evernote/resource.cpp'
476--- src/plugin/Evernote/resource.cpp 1970-01-01 00:00:00 +0000
477+++ src/plugin/Evernote/resource.cpp 2014-01-23 09:46:22 +0000
478@@ -0,0 +1,92 @@
479+/*
480+ * Copyright: 2013 Canonical, Ltd
481+ *
482+ * This file is part of reminders-app
483+ *
484+ * reminders-app is free software: you can redistribute it and/or modify
485+ * it under the terms of the GNU General Public License as published by
486+ * the Free Software Foundation; version 3.
487+ *
488+ * reminders-app is distributed in the hope that it will be useful,
489+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
490+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
491+ * GNU General Public License for more details.
492+ *
493+ * You should have received a copy of the GNU General Public License
494+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
495+ *
496+ * Authors: Michael Zanetti <michael.zanetti@canonical.com>
497+ */
498+
499+#include "resource.h"
500+
501+#include <QFile>
502+#include <QStandardPaths>
503+#include <QDebug>
504+#include <QCryptographicHash>
505+
506+Resource::Resource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type, QObject *parent):
507+ m_hash(hash),
508+ m_fileName(fileName),
509+ m_type(type)
510+{
511+
512+ m_filePath = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first() + "/" + hash + "." + type.split('/').last();
513+
514+ QFile file(m_filePath);
515+ if (!file.exists()) {
516+
517+ if (!file.open(QFile::WriteOnly)) {
518+ qWarning() << "error writing file" << m_filePath;
519+ return;
520+ }
521+ file.write(data);
522+ file.close();
523+ }
524+}
525+
526+Resource::Resource(const QString &path, QObject *parent):
527+ m_filePath(path)
528+{
529+ QFile file(path);
530+ if (!file.open(QFile::ReadOnly)) {
531+ qWarning() << "Cannot open file for reading...";
532+ return;
533+ }
534+
535+ QByteArray fileContent = file.readAll();
536+ m_hash = QCryptographicHash::hash(fileContent, QCryptographicHash::Md5).toHex();
537+
538+ m_fileName = path.split('/').last();
539+ if (m_fileName.endsWith(".png")) {
540+ m_type = "image/png";
541+ } else if (m_fileName.endsWith(".jpg") || m_fileName.endsWith(".jpeg")) {
542+ m_type = "image/jpeg";
543+ } else {
544+ qWarning() << "cannot determine mime type of file" << m_fileName;
545+ }
546+}
547+
548+QString Resource::hash() const
549+{
550+ return m_hash;
551+}
552+
553+QString Resource::type() const
554+{
555+ return m_type;
556+}
557+
558+QString Resource::fileName() const
559+{
560+ return m_fileName;
561+}
562+
563+QByteArray Resource::data() const
564+{
565+ QFile file(m_filePath);
566+ if (file.open(QFile::ReadOnly)) {
567+ return file.readAll();
568+ }
569+ return QByteArray();
570+}
571
572=== added file 'src/plugin/Evernote/resource.h'
573--- src/plugin/Evernote/resource.h 1970-01-01 00:00:00 +0000
574+++ src/plugin/Evernote/resource.h 2014-01-23 09:46:22 +0000
575@@ -0,0 +1,52 @@
576+/*
577+ * Copyright: 2013 Canonical, Ltd
578+ *
579+ * This file is part of reminders-app
580+ *
581+ * reminders-app is free software: you can redistribute it and/or modify
582+ * it under the terms of the GNU General Public License as published by
583+ * the Free Software Foundation; version 3.
584+ *
585+ * reminders-app is distributed in the hope that it will be useful,
586+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
587+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
588+ * GNU General Public License for more details.
589+ *
590+ * You should have received a copy of the GNU General Public License
591+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
592+ *
593+ * Authors: Michael Zanetti <michael.zanetti@canonical.com>
594+ */
595+
596+#ifndef RESOURCE_H
597+#define RESOURCE_H
598+
599+#include <QObject>
600+#include <QString>
601+#include <QImage>
602+
603+class Resource: public QObject
604+{
605+ Q_OBJECT
606+ Q_PROPERTY(QByteArray data READ data CONSTANT)
607+ Q_PROPERTY(QString hash READ hash CONSTANT)
608+ Q_PROPERTY(QString fileName READ fileName CONSTANT)
609+ Q_PROPERTY(QString type READ type CONSTANT)
610+
611+public:
612+ Resource(const QString &path, QObject *parent = 0);
613+ Resource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type, QObject *parent = 0);
614+
615+ QByteArray data() const;
616+ QString hash() const;
617+ QString fileName() const;
618+ QString type() const;
619+
620+private:
621+ QString m_hash;
622+ QString m_fileName;
623+ QString m_filePath;
624+ QString m_type;
625+};
626+
627+#endif
628
629=== modified file 'src/plugin/Evernote/resourceimageprovider.cpp'
630--- src/plugin/Evernote/resourceimageprovider.cpp 2013-12-18 22:35:03 +0000
631+++ src/plugin/Evernote/resourceimageprovider.cpp 2014-01-23 09:46:22 +0000
632@@ -26,7 +26,7 @@
633
634 QImage image;
635 if (mediaType.startsWith("image")) {
636- image = NotesStore::instance()->note(noteGuid)->resource(resourceHash);
637+ image = QImage::fromData(NotesStore::instance()->note(noteGuid)->resource(resourceHash)->data());
638 } else if (mediaType.startsWith("audio")) {
639 image.load("/usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg");
640 } else {
641
642=== modified file 'src/plugin/Evernote/utils/enmldocument.cpp'
643--- src/plugin/Evernote/utils/enmldocument.cpp 2014-01-10 12:00:26 +0000
644+++ src/plugin/Evernote/utils/enmldocument.cpp 2014-01-23 09:46:22 +0000
645@@ -156,7 +156,7 @@
646 } else if (type == TypeHtml) {
647 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg";
648 writer.writeAttribute("src", imagePath);
649- writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resourceName(hash));
650+ writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resource(hash)->fileName());
651 }
652 } else {
653 if (type == TypeRichText) {
654@@ -169,7 +169,7 @@
655 } else if (type == TypeHtml) {
656 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/help.svg";
657 writer.writeAttribute("src", imagePath);
658- writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resourceName(hash));
659+ writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resource(hash)->fileName());
660 }
661 }
662 }
663@@ -234,16 +234,22 @@
664 return html;
665 }
666
667-void EnmlDocument::setRichText(const QString &html)
668+void EnmlDocument::setRichText(const QString &richText)
669 {
670 // output
671 m_enml.clear();
672+
673 QXmlStreamWriter writer(&m_enml);
674 writer.writeStartDocument();
675 writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">");
676
677+ if (richText.isEmpty()) {
678+ writer.writeStartElement("en-note");
679+ writer.writeEndElement();
680+ }
681+
682 // input
683- QXmlStreamReader reader(html);
684+ QXmlStreamReader reader(richText);
685
686 // state
687 bool isBody = false;
688@@ -363,6 +369,48 @@
689 m_enml = output;
690 }
691
692+void EnmlDocument::attachFile(int position, const QString &file, const QString &hash, const QString &type)
693+{
694+ QXmlStreamReader reader(m_enml);
695+
696+ QString output;
697+ QXmlStreamWriter writer(&output);
698+ writer.writeStartDocument();
699+ writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">");
700+
701+ int textPos = 0;
702+
703+ while (!reader.atEnd() && !reader.hasError()) {
704+ QXmlStreamReader::TokenType token = reader.readNext();
705+
706+ if (token == QXmlStreamReader::StartElement) {
707+ writer.writeStartElement(reader.name().toString());
708+ writer.writeAttributes(reader.attributes());
709+ }
710+
711+ if (token == QXmlStreamReader::Characters) {
712+ QString textString = reader.text().toString();
713+ if (textPos <= position && textPos + textString.length() > position) {
714+ writer.writeCharacters(textString.left(position - textPos));
715+
716+ writer.writeStartElement("en-media");
717+ writer.writeAttribute("hash", hash);
718+ writer.writeAttribute("type", type);
719+ writer.writeEndElement();
720+
721+ writer.writeCharacters(textString.right(textString.length() - (position - textPos)));
722+ } else {
723+ writer.writeCharacters(reader.text().toString());
724+ }
725+ textPos += textString.length();
726+ }
727+ if (token == QXmlStreamReader::EndElement) {
728+ writer.writeEndElement();
729+ }
730+ }
731+ m_enml = output;
732+}
733+
734 QString EnmlDocument::toPlaintext() const
735 {
736 // output
737
738=== modified file 'src/plugin/Evernote/utils/enmldocument.h'
739--- src/plugin/Evernote/utils/enmldocument.h 2014-01-10 12:00:26 +0000
740+++ src/plugin/Evernote/utils/enmldocument.h 2014-01-23 09:46:22 +0000
741@@ -38,6 +38,9 @@
742
743 void setRichText(const QString &richText);
744
745+ // Will insert the file at position in the plaintext string
746+ void attachFile(int position, const QString &file, const QString &hash, const QString &type);
747+
748 void markTodo(const QString &todoId, bool checked);
749
750 private:
751@@ -47,7 +50,6 @@
752 };
753
754 QString convert(const QString &noteGuid, Type type) const;
755-
756 private:
757 QString m_enml;
758

Subscribers

People subscribed via source and target branches