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
=== modified file 'run_on_ubuntu_touch.sh'
--- run_on_ubuntu_touch.sh 2014-01-07 12:21:44 +0000
+++ run_on_ubuntu_touch.sh 2014-01-23 09:46:22 +0000
@@ -79,7 +79,7 @@
79}79}
8080
81run() {81run() {
82 exec_with_ssh "cd $CODE_DIR/$BUILD_DIR/src/app/ && ./$BINARY --desktop_file_hint=$CODE_DIR/reminders-app.desktop"82 exec_with_ssh "cd $CODE_DIR/$BUILD_DIR/src/app/ && ./$BINARY --desktop_file_hint=/home/phablet/$CODE_DIR/reminders-app.desktop"
83}83}
8484
85set -- `getopt -n$0 -u -a --longoptions="setup,gdb,click,help" "sgch" "$@"`85set -- `getopt -n$0 -u -a --longoptions="setup,gdb,click,help" "sgch" "$@"`
8686
=== modified file 'src/app/qml/reminders-app.qml'
--- src/app/qml/reminders-app.qml 2013-12-14 23:59:04 +0000
+++ src/app/qml/reminders-app.qml 2014-01-23 09:46:22 +0000
@@ -59,6 +59,18 @@
59 }59 }
60 }60 }
6161
62 Connections {
63 target: NotesStore
64 onNoteCreated: {
65 var note = NotesStore.note(guid);
66 print("note created:", note.guid);
67 var component = Qt.createComponent(Qt.resolvedUrl("ui/EditNotePage.qml"));
68 var page = component.createObject(pageStack)
69 page.note = note;
70 pagestack.push(page);
71 }
72 }
73
62 PageStack {74 PageStack {
63 id: pagestack75 id: pagestack
6476
6577
=== modified file 'src/app/qml/ui/EditNotePage.qml'
--- src/app/qml/ui/EditNotePage.qml 2013-12-17 23:19:58 +0000
+++ src/app/qml/ui/EditNotePage.qml 2014-01-23 09:46:22 +0000
@@ -19,6 +19,7 @@
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.121import Ubuntu.Components.ListItems 0.1
22import Ubuntu.Content 0.1
22import Evernote 0.123import Evernote 0.1
23import "../components"24import "../components"
2425
@@ -51,6 +52,14 @@
5152
52 ToolbarButton {53 ToolbarButton {
53 text: "attach"54 text: "attach"
55 onTriggered: {
56 priv.insertPosition = noteTextArea.cursorPosition;
57 note.richTextContent = noteTextArea.text;
58
59 priv.activeTransfer = ContentHub.importContent(ContentType.Pictures);
60 priv.activeTransfer.selectionType = ContentTransfer.Single;
61 priv.activeTransfer.start();
62 }
54 }63 }
55 ToolbarButton {64 ToolbarButton {
56 text: "camera"65 text: "camera"
@@ -59,8 +68,28 @@
59 ToolbarButton {68 ToolbarButton {
60 text: "rtf"69 text: "rtf"
61 }70 }
6271 }
63 }72
73 QtObject {
74 id: priv
75 property int insertPosition
76 property var activeTransfer
77 }
78
79 ContentImportHint {
80 id: importHint
81 anchors.fill: parent
82 activeTransfer: root.activeTransfer
83 }
84 Connections {
85 target: priv.activeTransfer ? priv.activeTransfer : null
86 onStateChanged: {
87 if (priv.activeTransfer.state === ContentTransfer.Charged) {
88 print("attaching", priv.activeTransfer.items[0].url.toString())
89 note.attachFile(priv.insertPosition, priv.activeTransfer.items[0].url.toString())
90 }
91 }
92 }
6493
65 Column {94 Column {
66 anchors.fill: parent95 anchors.fill: parent
@@ -99,7 +128,6 @@
99128
100 textFormat: TextEdit.RichText129 textFormat: TextEdit.RichText
101 text: root.note ? root.note.richTextContent : ""130 text: root.note ? root.note.richTextContent : ""
102
103 }131 }
104 }132 }
105}133}
106134
=== modified file 'src/app/qml/ui/NotesPage.qml'
--- src/app/qml/ui/NotesPage.qml 2013-12-15 01:57:25 +0000
+++ src/app/qml/ui/NotesPage.qml 2014-01-23 09:46:22 +0000
@@ -49,7 +49,7 @@
49 text: "add note"49 text: "add note"
50 iconName: "add"50 iconName: "add"
51 onTriggered: {51 onTriggered: {
52 pagestack.push(Qt.resolvedUrl("EditNotePage.qml"));52 NotesStore.createNote("Untitled");
53 }53 }
54 }54 }
55 }55 }
@@ -68,7 +68,7 @@
68 title: model.title68 title: model.title
69 creationDate: model.created69 creationDate: model.created
70 content: model.plaintextContent70 content: model.plaintextContent
71 resource: model.resources.length > 0 ? model.resources[0] : ""71 resource: model.resourceUrls.length > 0 ? model.resourceUrls[0] : ""
7272
73 onClicked: {73 onClicked: {
74 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})74 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})
7575
=== modified file 'src/plugin/Evernote/CMakeLists.txt'
--- src/plugin/Evernote/CMakeLists.txt 2014-01-19 13:59:12 +0000
+++ src/plugin/Evernote/CMakeLists.txt 2014-01-23 09:46:22 +0000
@@ -11,6 +11,7 @@
11 notebooks.cpp11 notebooks.cpp
12 notes.cpp12 notes.cpp
13 note.cpp13 note.cpp
14 resource.cpp
14 notebook.cpp15 notebook.cpp
15 jobs/fetchnotesjob.cpp16 jobs/fetchnotesjob.cpp
16 jobs/fetchnotebooksjob.cpp17 jobs/fetchnotebooksjob.cpp
1718
=== modified file 'src/plugin/Evernote/evernoteplugin.cpp'
--- src/plugin/Evernote/evernoteplugin.cpp 2013-12-15 01:57:25 +0000
+++ src/plugin/Evernote/evernoteplugin.cpp 2014-01-23 09:46:22 +0000
@@ -26,6 +26,7 @@
26#include "notes.h"26#include "notes.h"
27#include "notebooks.h"27#include "notebooks.h"
28#include "note.h"28#include "note.h"
29#include "resource.h"
29#include "notebook.h"30#include "notebook.h"
30#include "resourceimageprovider.h"31#include "resourceimageprovider.h"
3132
@@ -56,6 +57,7 @@
56 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");57 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");
57 qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");58 qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");
58 qmlRegisterUncreatableType<Notebook>("Evernote", 0, 1, "Notebook", "Cannot create Notes in QML. Use NotesStore.createNotebook() instead.");59 qmlRegisterUncreatableType<Notebook>("Evernote", 0, 1, "Notebook", "Cannot create Notes in QML. Use NotesStore.createNotebook() instead.");
60 qmlRegisterUncreatableType<Resource>("Evernote", 0, 1, "Resource", "Cannot create Resources. Use Note.attachFile() instead.");
59}61}
6062
61void EvernotePlugin::initializeEngine(QQmlEngine *engine, const char *uri)63void EvernotePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
6264
=== modified file 'src/plugin/Evernote/jobs/createnotejob.cpp'
--- src/plugin/Evernote/jobs/createnotejob.cpp 2013-11-28 00:39:33 +0000
+++ src/plugin/Evernote/jobs/createnotejob.cpp 2014-01-23 09:46:22 +0000
@@ -35,12 +35,16 @@
35 evernote::edam::Note input;35 evernote::edam::Note input;
36 input.title = m_title.toStdString();36 input.title = m_title.toStdString();
37 input.__isset.title = true;37 input.__isset.title = true;
38 input.notebookGuid = m_notebookGuid.toStdString();38 if (!m_notebookGuid.isEmpty()) {
39 input.__isset.notebookGuid = true;39 input.notebookGuid = m_notebookGuid.toStdString();
40 input.content = m_content.toStdString();40 input.__isset.notebookGuid = true;
41 input.__isset.content = true;41 }
42 input.contentLength = m_content.length();42 if (!m_content.isEmpty()) {
43 input.__isset.contentLength = true;43 input.content = m_content.toStdString();
44 input.__isset.content = true;
45 input.contentLength = m_content.length();
46 input.__isset.contentLength = true;
47 }
4448
45 client()->createNote(m_resultNote, token().toStdString(), input);49 client()->createNote(m_resultNote, token().toStdString(), input);
46}50}
4751
=== modified file 'src/plugin/Evernote/jobs/createnotejob.h'
--- src/plugin/Evernote/jobs/createnotejob.h 2013-11-29 20:58:04 +0000
+++ src/plugin/Evernote/jobs/createnotejob.h 2014-01-23 09:46:22 +0000
@@ -27,7 +27,7 @@
27{27{
28 Q_OBJECT28 Q_OBJECT
29public:29public:
30 explicit CreateNoteJob(const QString &title, const QString &notebookGuid, const QString &content, QObject *parent = 0);30 explicit CreateNoteJob(const QString &title, const QString &notebookGuid = QString(), const QString &content = QString(), QObject *parent = 0);
3131
32signals:32signals:
33 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, evernote::edam::Note note);33 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, evernote::edam::Note note);
3434
=== modified file 'src/plugin/Evernote/jobs/savenotejob.cpp'
--- src/plugin/Evernote/jobs/savenotejob.cpp 2013-12-14 22:38:57 +0000
+++ src/plugin/Evernote/jobs/savenotejob.cpp 2014-01-23 09:46:22 +0000
@@ -54,6 +54,33 @@
54 note.attributes.reminderDoneTime = m_note->reminderDoneTime().toMSecsSinceEpoch();54 note.attributes.reminderDoneTime = m_note->reminderDoneTime().toMSecsSinceEpoch();
55 note.attributes.__isset.reminderDoneTime = true;55 note.attributes.__isset.reminderDoneTime = true;
5656
57 note.resources.clear();
58 foreach (Resource *resource, m_note->resources()) {
59 evernote::edam::Resource evResource;
60 evResource.noteGuid = m_note->guid().toStdString();
61 evResource.__isset.noteGuid = true;
62 evResource.mime = resource->type().toStdString();
63 evResource.__isset.mime = true;
64
65 evResource.data.bodyHash = resource->hash().toStdString();
66 evResource.data.__isset.bodyHash = true;
67
68 QByteArray data = resource->data();
69 evResource.data.body.assign(data.data(), data.length());
70 evResource.data.__isset.body = true;
71
72 evResource.data.size = data.length();
73 evResource.data.__isset.size = true;
74 evResource.__isset.data = true;
75
76 evResource.attributes.fileName = resource->fileName().toStdString();
77 evResource.attributes.__isset.fileName = true;
78 evResource.__isset.attributes = true;
79
80 note.resources.push_back(evResource);
81 }
82 note.__isset.resources = true;
83
57 client()->updateNote(m_resultNote, token().toStdString(), note);84 client()->updateNote(m_resultNote, token().toStdString(), note);
58}85}
5986
6087
=== modified file 'src/plugin/Evernote/note.cpp'
--- src/plugin/Evernote/note.cpp 2013-12-18 22:35:03 +0000
+++ src/plugin/Evernote/note.cpp 2014-01-23 09:46:22 +0000
@@ -27,6 +27,8 @@
27#include <QUrlQuery>27#include <QUrlQuery>
28#include <QStandardPaths>28#include <QStandardPaths>
29#include <QDebug>29#include <QDebug>
30#include <QCryptographicHash>
31#include <QFile>
3032
31Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :33Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :
32 QObject(parent),34 QObject(parent),
@@ -36,6 +38,11 @@
36{38{
37}39}
3840
41Note::~Note()
42{
43 qDeleteAll(m_resources.values());
44}
45
39QString Note::guid() const46QString Note::guid() const
40{47{
41 return m_guid;48 return m_guid;
@@ -189,11 +196,16 @@
189 }196 }
190}197}
191198
192QStringList Note::resources() const199QList<Resource*> Note::resources() const
200{
201 return m_resources.values();
202}
203
204QStringList Note::resourceUrls() const
193{205{
194 QList<QString> ret;206 QList<QString> ret;
195 foreach (const QString &hash, m_resources.keys()) {207 foreach (const QString &hash, m_resources.keys()) {
196 QUrl url("image://resource/" + m_resourceTypes.value(hash));208 QUrl url("image://resource/" + m_resources.value(hash)->type());
197 QUrlQuery arguments;209 QUrlQuery arguments;
198 arguments.addQueryItem("noteGuid", m_guid);210 arguments.addQueryItem("noteGuid", m_guid);
199 arguments.addQueryItem("hash", hash);211 arguments.addQueryItem("hash", hash);
@@ -203,24 +215,24 @@
203 return ret;215 return ret;
204}216}
205217
206QImage Note::resource(const QString &hash)218Resource* Note::resource(const QString &hash)
207{219{
208 return m_resources.value(hash);220 return m_resources.value(hash);
209}221}
210222
211QString Note::resourceName(const QString &hash)223
224Resource* Note::addResource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type)
212{225{
213 return m_resourceNames.value(hash);226 Resource *resource = new Resource(data, hash, fileName, type, this);
227 m_resources.insert(hash, resource);
228 return resource;
214}229}
215230
216void Note::addResource(const QString &hash, const QString &fileName, const QString &type, const QImage &image)231Resource *Note::addResource(const QString &fileName)
217{232{
218 image.save(QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first() + "/" + hash + "." + type.split('/').last());233 Resource *resource = new Resource(fileName);
219 if (!image.isNull()) {234 m_resources.insert(resource->hash(), resource);
220 m_resources.insert(hash, image);235 return resource;
221 }
222 m_resourceTypes.insert(hash, type);
223 m_resourceNames.insert(hash, fileName);
224}236}
225237
226void Note::markTodo(const QString &todoId, bool checked)238void Note::markTodo(const QString &todoId, bool checked)
@@ -228,6 +240,13 @@
228 m_content.markTodo(todoId, checked);240 m_content.markTodo(todoId, checked);
229}241}
230242
243void Note::attachFile(int position, const QUrl &fileName)
244{
245 Resource *resource = addResource(fileName.path());
246 m_content.attachFile(position, fileName.path(), resource->hash(), resource->type());
247 emit contentChanged();
248}
249
231Note *Note::clone()250Note *Note::clone()
232{251{
233 Note *note = new Note(m_guid, m_created);252 Note *note = new Note(m_guid, m_created);
@@ -238,6 +257,10 @@
238 note->setReminderTime(m_reminderTime);257 note->setReminderTime(m_reminderTime);
239 note->setReminderDoneTime(m_reminderDoneTime);258 note->setReminderDoneTime(m_reminderDoneTime);
240 note->setIsSearchResult(m_isSearchResult);259 note->setIsSearchResult(m_isSearchResult);
260 foreach (Resource *resource, m_resources) {
261 note->addResource(resource->data(), resource->hash(), resource->fileName(), resource->type());
262 }
263
241 return note;264 return note;
242}265}
243266
244267
=== modified file 'src/plugin/Evernote/note.h'
--- src/plugin/Evernote/note.h 2014-01-10 12:00:26 +0000
+++ src/plugin/Evernote/note.h 2014-01-23 09:46:22 +0000
@@ -22,6 +22,7 @@
22#define NOTE_H22#define NOTE_H
2323
24#include "utils/enmldocument.h"24#include "utils/enmldocument.h"
25#include "resource.h"
2526
26#include <QObject>27#include <QObject>
27#include <QDateTime>28#include <QDateTime>
@@ -41,7 +42,7 @@
41 Q_PROPERTY(QString richTextContent READ richTextContent WRITE setRichTextContent NOTIFY contentChanged)42 Q_PROPERTY(QString richTextContent READ richTextContent WRITE setRichTextContent NOTIFY contentChanged)
42 Q_PROPERTY(QString enmlContent READ enmlContent WRITE setEnmlContent NOTIFY contentChanged)43 Q_PROPERTY(QString enmlContent READ enmlContent WRITE setEnmlContent NOTIFY contentChanged)
43 Q_PROPERTY(QString plaintextContent READ plaintextContent NOTIFY contentChanged)44 Q_PROPERTY(QString plaintextContent READ plaintextContent NOTIFY contentChanged)
44 Q_PROPERTY(QList<QString> resources READ resources NOTIFY contentChanged)45 Q_PROPERTY(QStringList resourceUrls READ resourceUrls NOTIFY contentChanged)
45 Q_PROPERTY(bool reminder READ reminder WRITE setReminder NOTIFY reminderChanged)46 Q_PROPERTY(bool reminder READ reminder WRITE setReminder NOTIFY reminderChanged)
46 Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)47 Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)
47 Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)48 Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)
@@ -51,6 +52,7 @@
5152
52public:53public:
53 explicit Note(const QString &guid, const QDateTime &created, QObject *parent = 0);54 explicit Note(const QString &guid, const QDateTime &created, QObject *parent = 0);
55 ~Note();
5456
55 QString guid() const;57 QString guid() const;
5658
@@ -96,12 +98,14 @@
96 bool isSearchResult() const;98 bool isSearchResult() const;
97 void setIsSearchResult(bool isSearchResult);99 void setIsSearchResult(bool isSearchResult);
98100
99 QStringList resources() const;101 QStringList resourceUrls() const;
100 QImage resource(const QString &hash);102 Resource* resource(const QString &hash);
101 QString resourceName(const QString &hash);103 QList<Resource*> resources() const;
102 void addResource(const QString &hash, const QString &fileName, const QString &type, const QImage &image = QImage());104 Resource *addResource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type);
105 Resource *addResource(const QString &fileName);
103106
104 Q_INVOKABLE void markTodo(const QString &todoId, bool checked);107 Q_INVOKABLE void markTodo(const QString &todoId, bool checked);
108 Q_INVOKABLE void attachFile(int position, const QUrl &fileName);
105109
106 Note* clone();110 Note* clone();
107111
@@ -128,9 +132,7 @@
128 QDateTime m_reminderTime;132 QDateTime m_reminderTime;
129 QDateTime m_reminderDoneTime;133 QDateTime m_reminderDoneTime;
130 bool m_isSearchResult;134 bool m_isSearchResult;
131 QHash<QString, QImage> m_resources;135 QHash<QString, Resource*> m_resources;
132 QHash<QString, QString> m_resourceTypes;
133 QHash<QString, QString> m_resourceNames;
134};136};
135137
136#endif // NOTE_H138#endif // NOTE_H
137139
=== modified file 'src/plugin/Evernote/notesstore.cpp'
--- src/plugin/Evernote/notesstore.cpp 2013-12-18 22:35:03 +0000
+++ src/plugin/Evernote/notesstore.cpp 2014-01-23 09:46:22 +0000
@@ -93,8 +93,8 @@
93 return m_notes.at(index.row())->richTextContent();93 return m_notes.at(index.row())->richTextContent();
94 case RolePlaintextContent:94 case RolePlaintextContent:
95 return m_notes.at(index.row())->plaintextContent();95 return m_notes.at(index.row())->plaintextContent();
96 case RoleResources:96 case RoleResourceUrls:
97 return m_notes.at(index.row())->resources();97 return m_notes.at(index.row())->resourceUrls();
98 }98 }
99 return QVariant();99 return QVariant();
100}100}
@@ -114,7 +114,7 @@
114 roles.insert(RoleRichTextContent, "richTextContent");114 roles.insert(RoleRichTextContent, "richTextContent");
115 roles.insert(RoleHtmlContent, "htmlContent");115 roles.insert(RoleHtmlContent, "htmlContent");
116 roles.insert(RolePlaintextContent, "plaintextContent");116 roles.insert(RolePlaintextContent, "plaintextContent");
117 roles.insert(RoleResources, "resources");117 roles.insert(RoleResourceUrls, "resourceUrls");
118 return roles;118 return roles;
119}119}
120120
@@ -235,12 +235,8 @@
235 QString fileName = QString::fromStdString(resource.attributes.fileName);235 QString fileName = QString::fromStdString(resource.attributes.fileName);
236 QString mime = QString::fromStdString(resource.mime);236 QString mime = QString::fromStdString(resource.mime);
237237
238 if (mime.startsWith("image/")) {238 QByteArray resourceData = QByteArray(resource.data.body.data(), resource.data.size);
239 QImage image = QImage::fromData((const uchar*)resource.data.body.data(), resource.data.size);239 note->addResource(resourceData, hash, fileName, mime);
240 note->addResource(hash, fileName, mime, image);
241 } else {
242 note->addResource(hash, fileName, mime);
243 }
244 }240 }
245241
246 note->setEnmlContent(QString::fromStdString(result.content));242 note->setEnmlContent(QString::fromStdString(result.content));
@@ -324,6 +320,7 @@
324 endInsertRows();320 endInsertRows();
325321
326 emit noteAdded(note->guid(), note->notebookGuid());322 emit noteAdded(note->guid(), note->notebookGuid());
323 emit noteCreated(note->guid(), note->notebookGuid());
327}324}
328325
329void NotesStore::saveNote(const QString &guid)326void NotesStore::saveNote(const QString &guid)
330327
=== modified file 'src/plugin/Evernote/notesstore.h'
--- src/plugin/Evernote/notesstore.h 2014-01-10 12:00:26 +0000
+++ src/plugin/Evernote/notesstore.h 2014-01-23 09:46:22 +0000
@@ -63,7 +63,7 @@
63 RoleHtmlContent,63 RoleHtmlContent,
64 RoleRichTextContent,64 RoleRichTextContent,
65 RolePlaintextContent,65 RolePlaintextContent,
66 RoleResources66 RoleResourceUrls
67 };67 };
6868
69 ~NotesStore();69 ~NotesStore();
@@ -77,7 +77,7 @@
77 QList<Note*> notes() const;77 QList<Note*> notes() const;
7878
79 Q_INVOKABLE Note* note(const QString &guid);79 Q_INVOKABLE Note* note(const QString &guid);
80 Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &richTextContent);80 Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid = QString(), const QString &richTextContent = QString());
81 void createNote(const QString &title, const QString &notebookGuid, const EnmlDocument &content);81 void createNote(const QString &title, const QString &notebookGuid, const EnmlDocument &content);
82 Q_INVOKABLE void saveNote(const QString &guid);82 Q_INVOKABLE void saveNote(const QString &guid);
83 Q_INVOKABLE void deleteNote(const QString &guid);83 Q_INVOKABLE void deleteNote(const QString &guid);
@@ -96,6 +96,7 @@
96signals:96signals:
97 void tokenChanged();97 void tokenChanged();
9898
99 void noteCreated(const QString &guid, const QString &notebookGuid);
99 void noteAdded(const QString &guid, const QString &notebookGuid);100 void noteAdded(const QString &guid, const QString &notebookGuid);
100 void noteChanged(const QString &guid, const QString &notebookGuid);101 void noteChanged(const QString &guid, const QString &notebookGuid);
101 void noteRemoved(const QString &guid, const QString &notebookGuid);102 void noteRemoved(const QString &guid, const QString &notebookGuid);
102103
=== added file 'src/plugin/Evernote/resource.cpp'
--- src/plugin/Evernote/resource.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/resource.cpp 2014-01-23 09:46:22 +0000
@@ -0,0 +1,92 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "resource.h"
22
23#include <QFile>
24#include <QStandardPaths>
25#include <QDebug>
26#include <QCryptographicHash>
27
28Resource::Resource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type, QObject *parent):
29 m_hash(hash),
30 m_fileName(fileName),
31 m_type(type)
32{
33
34 m_filePath = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first() + "/" + hash + "." + type.split('/').last();
35
36 QFile file(m_filePath);
37 if (!file.exists()) {
38
39 if (!file.open(QFile::WriteOnly)) {
40 qWarning() << "error writing file" << m_filePath;
41 return;
42 }
43 file.write(data);
44 file.close();
45 }
46}
47
48Resource::Resource(const QString &path, QObject *parent):
49 m_filePath(path)
50{
51 QFile file(path);
52 if (!file.open(QFile::ReadOnly)) {
53 qWarning() << "Cannot open file for reading...";
54 return;
55 }
56
57 QByteArray fileContent = file.readAll();
58 m_hash = QCryptographicHash::hash(fileContent, QCryptographicHash::Md5).toHex();
59
60 m_fileName = path.split('/').last();
61 if (m_fileName.endsWith(".png")) {
62 m_type = "image/png";
63 } else if (m_fileName.endsWith(".jpg") || m_fileName.endsWith(".jpeg")) {
64 m_type = "image/jpeg";
65 } else {
66 qWarning() << "cannot determine mime type of file" << m_fileName;
67 }
68}
69
70QString Resource::hash() const
71{
72 return m_hash;
73}
74
75QString Resource::type() const
76{
77 return m_type;
78}
79
80QString Resource::fileName() const
81{
82 return m_fileName;
83}
84
85QByteArray Resource::data() const
86{
87 QFile file(m_filePath);
88 if (file.open(QFile::ReadOnly)) {
89 return file.readAll();
90 }
91 return QByteArray();
92}
093
=== added file 'src/plugin/Evernote/resource.h'
--- src/plugin/Evernote/resource.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/resource.h 2014-01-23 09:46:22 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef RESOURCE_H
22#define RESOURCE_H
23
24#include <QObject>
25#include <QString>
26#include <QImage>
27
28class Resource: public QObject
29{
30 Q_OBJECT
31 Q_PROPERTY(QByteArray data READ data CONSTANT)
32 Q_PROPERTY(QString hash READ hash CONSTANT)
33 Q_PROPERTY(QString fileName READ fileName CONSTANT)
34 Q_PROPERTY(QString type READ type CONSTANT)
35
36public:
37 Resource(const QString &path, QObject *parent = 0);
38 Resource(const QByteArray &data, const QString &hash, const QString &fileName, const QString &type, QObject *parent = 0);
39
40 QByteArray data() const;
41 QString hash() const;
42 QString fileName() const;
43 QString type() const;
44
45private:
46 QString m_hash;
47 QString m_fileName;
48 QString m_filePath;
49 QString m_type;
50};
51
52#endif
053
=== modified file 'src/plugin/Evernote/resourceimageprovider.cpp'
--- src/plugin/Evernote/resourceimageprovider.cpp 2013-12-18 22:35:03 +0000
+++ src/plugin/Evernote/resourceimageprovider.cpp 2014-01-23 09:46:22 +0000
@@ -26,7 +26,7 @@
2626
27 QImage image;27 QImage image;
28 if (mediaType.startsWith("image")) {28 if (mediaType.startsWith("image")) {
29 image = NotesStore::instance()->note(noteGuid)->resource(resourceHash);29 image = QImage::fromData(NotesStore::instance()->note(noteGuid)->resource(resourceHash)->data());
30 } else if (mediaType.startsWith("audio")) {30 } else if (mediaType.startsWith("audio")) {
31 image.load("/usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg");31 image.load("/usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg");
32 } else {32 } else {
3333
=== modified file 'src/plugin/Evernote/utils/enmldocument.cpp'
--- src/plugin/Evernote/utils/enmldocument.cpp 2014-01-10 12:00:26 +0000
+++ src/plugin/Evernote/utils/enmldocument.cpp 2014-01-23 09:46:22 +0000
@@ -156,7 +156,7 @@
156 } else if (type == TypeHtml) {156 } else if (type == TypeHtml) {
157 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg";157 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg";
158 writer.writeAttribute("src", imagePath);158 writer.writeAttribute("src", imagePath);
159 writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resourceName(hash));159 writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resource(hash)->fileName());
160 }160 }
161 } else {161 } else {
162 if (type == TypeRichText) {162 if (type == TypeRichText) {
@@ -169,7 +169,7 @@
169 } else if (type == TypeHtml) {169 } else if (type == TypeHtml) {
170 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/help.svg";170 QString imagePath = "file:///usr/share/icons/ubuntu-mobile/actions/scalable/help.svg";
171 writer.writeAttribute("src", imagePath);171 writer.writeAttribute("src", imagePath);
172 writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resourceName(hash));172 writer.writeCharacters(NotesStore::instance()->note(noteGuid)->resource(hash)->fileName());
173 }173 }
174 }174 }
175 }175 }
@@ -234,16 +234,22 @@
234 return html;234 return html;
235}235}
236236
237void EnmlDocument::setRichText(const QString &html)237void EnmlDocument::setRichText(const QString &richText)
238{238{
239 // output239 // output
240 m_enml.clear();240 m_enml.clear();
241
241 QXmlStreamWriter writer(&m_enml);242 QXmlStreamWriter writer(&m_enml);
242 writer.writeStartDocument();243 writer.writeStartDocument();
243 writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">");244 writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">");
244245
246 if (richText.isEmpty()) {
247 writer.writeStartElement("en-note");
248 writer.writeEndElement();
249 }
250
245 // input251 // input
246 QXmlStreamReader reader(html);252 QXmlStreamReader reader(richText);
247253
248 // state254 // state
249 bool isBody = false;255 bool isBody = false;
@@ -363,6 +369,48 @@
363 m_enml = output;369 m_enml = output;
364}370}
365371
372void EnmlDocument::attachFile(int position, const QString &file, const QString &hash, const QString &type)
373{
374 QXmlStreamReader reader(m_enml);
375
376 QString output;
377 QXmlStreamWriter writer(&output);
378 writer.writeStartDocument();
379 writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">");
380
381 int textPos = 0;
382
383 while (!reader.atEnd() && !reader.hasError()) {
384 QXmlStreamReader::TokenType token = reader.readNext();
385
386 if (token == QXmlStreamReader::StartElement) {
387 writer.writeStartElement(reader.name().toString());
388 writer.writeAttributes(reader.attributes());
389 }
390
391 if (token == QXmlStreamReader::Characters) {
392 QString textString = reader.text().toString();
393 if (textPos <= position && textPos + textString.length() > position) {
394 writer.writeCharacters(textString.left(position - textPos));
395
396 writer.writeStartElement("en-media");
397 writer.writeAttribute("hash", hash);
398 writer.writeAttribute("type", type);
399 writer.writeEndElement();
400
401 writer.writeCharacters(textString.right(textString.length() - (position - textPos)));
402 } else {
403 writer.writeCharacters(reader.text().toString());
404 }
405 textPos += textString.length();
406 }
407 if (token == QXmlStreamReader::EndElement) {
408 writer.writeEndElement();
409 }
410 }
411 m_enml = output;
412}
413
366QString EnmlDocument::toPlaintext() const414QString EnmlDocument::toPlaintext() const
367{415{
368 // output416 // output
369417
=== modified file 'src/plugin/Evernote/utils/enmldocument.h'
--- src/plugin/Evernote/utils/enmldocument.h 2014-01-10 12:00:26 +0000
+++ src/plugin/Evernote/utils/enmldocument.h 2014-01-23 09:46:22 +0000
@@ -38,6 +38,9 @@
3838
39 void setRichText(const QString &richText);39 void setRichText(const QString &richText);
4040
41 // Will insert the file at position in the plaintext string
42 void attachFile(int position, const QString &file, const QString &hash, const QString &type);
43
41 void markTodo(const QString &todoId, bool checked);44 void markTodo(const QString &todoId, bool checked);
4245
43private:46private:
@@ -47,7 +50,6 @@
47 };50 };
4851
49 QString convert(const QString &noteGuid, Type type) const;52 QString convert(const QString &noteGuid, Type type) const;
50
51private:53private:
52 QString m_enml;54 QString m_enml;
5355

Subscribers

People subscribed via source and target branches