Merge lp:~mzanetti/reminders-app/notes-refactor into lp:reminders-app

Proposed by Michael Zanetti
Status: Merged
Approved by: David Planella
Approved revision: 11
Merged at revision: 9
Proposed branch: lp:~mzanetti/reminders-app/notes-refactor
Merge into: lp:reminders-app
Diff against target: 1163 lines (+654/-176)
22 files modified
src/app/qml/reminders-app.qml (+1/-1)
src/app/qml/ui/NotePage.qml (+3/-2)
src/app/qml/ui/NotesPage.qml (+1/-9)
src/plugin/Evernote/Evernote.pro (+12/-2)
src/plugin/Evernote/evernoteplugin.cpp (+2/-0)
src/plugin/Evernote/fetchnotebooksjob.cpp (+25/-0)
src/plugin/Evernote/fetchnotebooksjob.h (+29/-0)
src/plugin/Evernote/fetchnotejob.cpp (+26/-0)
src/plugin/Evernote/fetchnotejob.h (+29/-0)
src/plugin/Evernote/fetchnotesjob.cpp (+48/-0)
src/plugin/Evernote/fetchnotesjob.h (+30/-0)
src/plugin/Evernote/note.cpp (+51/-0)
src/plugin/Evernote/note.h (+40/-0)
src/plugin/Evernote/notebook.cpp (+25/-0)
src/plugin/Evernote/notebook.h (+30/-0)
src/plugin/Evernote/notebooks.cpp (+20/-25)
src/plugin/Evernote/notebooks.h (+4/-5)
src/plugin/Evernote/notes.cpp (+37/-53)
src/plugin/Evernote/notes.h (+12/-6)
src/plugin/Evernote/notesstore.cpp (+187/-58)
src/plugin/Evernote/notesstore.h (+42/-13)
src/plugin/Evernote/userstore.h (+0/-2)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/notes-refactor
Reviewer Review Type Date Requested Status
David Planella Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+196455@code.launchpad.net

Commit message

Add proper Notes classes and refactor server interaction and error handling

Description of the change

This adds proper classes for Notes and Notebooks to be used with QML. Also, it refactors the interaction to evernote to be threaded in order to not block the ui. Last but not least it removes the ugly displayException() method from the NotesStore and uses proper error handling instead. We still need to communicate error to the UI somehow.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
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 :

Looks good to me and works well, nice to see the improvement in UI responsiveness.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/qml/reminders-app.qml'
2--- src/app/qml/reminders-app.qml 2013-11-22 00:42:39 +0000
3+++ src/app/qml/reminders-app.qml 2013-11-24 20:43:59 +0000
4@@ -29,7 +29,7 @@
5
6 Component.onCompleted: {
7 pagestack.push(rootTabs)
8- if (NotesStore.token.length == 0) {
9+ if (NotesStore.token.length === 0) {
10 pagestack.push(Qt.resolvedUrl("ui/AccountSelectorPage.qml"));
11 }
12 }
13
14=== modified file 'src/app/qml/ui/NotePage.qml'
15--- src/app/qml/ui/NotePage.qml 2013-11-21 23:30:15 +0000
16+++ src/app/qml/ui/NotePage.qml 2013-11-24 20:43:59 +0000
17@@ -3,13 +3,14 @@
18 import Evernote 0.1
19
20 Page {
21-
22- property alias text: noteTextArea.text
23+ title: note.title
24+ property var note
25
26 TextArea {
27 id: noteTextArea
28 anchors.fill: parent
29 textFormat: TextEdit.RichText
30+ text: note.content
31 }
32 }
33
34
35=== modified file 'src/app/qml/ui/NotesPage.qml'
36--- src/app/qml/ui/NotesPage.qml 2013-11-21 23:30:15 +0000
37+++ src/app/qml/ui/NotesPage.qml 2013-11-24 20:43:59 +0000
38@@ -8,16 +8,8 @@
39
40 property alias filter: notes.filterNotebookGuid
41
42- onActiveChanged: {
43- if (active) {
44- notes.refresh();
45- }
46- }
47-
48 Notes {
49 id: notes
50-
51- onFilterNotebookGuidChanged: refresh();
52 }
53
54 ListView {
55@@ -28,7 +20,7 @@
56 text: title
57
58 onClicked: {
59- pageStack.push(Qt.resolvedUrl("NotePage.qml"), {title: title, text: notes.note(guid)})
60+ pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: notes.note(guid)})
61 }
62 }
63 }
64
65=== modified file 'src/plugin/Evernote/Evernote.pro'
66--- src/plugin/Evernote/Evernote.pro 2013-11-21 23:30:15 +0000
67+++ src/plugin/Evernote/Evernote.pro 2013-11-24 20:43:59 +0000
68@@ -13,13 +13,23 @@
69 notesstore.cpp \
70 userstore.cpp \
71 notebooks.cpp \
72- notes.cpp
73+ notes.cpp \
74+ note.cpp \
75+ notebook.cpp \
76+ fetchnotesjob.cpp \
77+ fetchnotebooksjob.cpp \
78+ fetchnotejob.cpp
79
80 HEADERS += evernoteplugin.h \
81 notesstore.h \
82 userstore.h \
83 notebooks.h \
84- notes.h
85+ notes.h \
86+ note.h \
87+ notebook.h \
88+ fetchnotesjob.h \
89+ fetchnotebooksjob.h \
90+ fetchnotejob.h
91
92 message(building in $$OUT_PWD)
93 LIBS += -L$$OUT_PWD/../../../3rdParty/evernote-sdk-cpp/ -L$$OUT_PWD/../../../3rdParty/libthrift/ -levernote-sdk-cpp -llibthrift
94
95=== modified file 'src/plugin/Evernote/evernoteplugin.cpp'
96--- src/plugin/Evernote/evernoteplugin.cpp 2013-11-21 23:30:15 +0000
97+++ src/plugin/Evernote/evernoteplugin.cpp 2013-11-24 20:43:59 +0000
98@@ -22,6 +22,7 @@
99 #include "notesstore.h"
100 #include "notes.h"
101 #include "notebooks.h"
102+#include "note.h"
103
104 #include <QtQml>
105
106@@ -37,4 +38,5 @@
107 qmlRegisterSingletonType<NotesStore>("Evernote", 0, 1, "NotesStore", notesStoreProvider);
108 qmlRegisterType<Notes>("Evernote", 0, 1, "Notes");
109 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");
110+ qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");
111 }
112
113=== added file 'src/plugin/Evernote/fetchnotebooksjob.cpp'
114--- src/plugin/Evernote/fetchnotebooksjob.cpp 1970-01-01 00:00:00 +0000
115+++ src/plugin/Evernote/fetchnotebooksjob.cpp 2013-11-24 20:43:59 +0000
116@@ -0,0 +1,25 @@
117+#include "fetchnotebooksjob.h"
118+
119+#include <QDebug>
120+
121+FetchNotebooksJob::FetchNotebooksJob(evernote::edam::NoteStoreClient *client, const QString &token, QObject *parent) :
122+ QThread(parent),
123+ m_client(client),
124+ m_token(token)
125+{
126+}
127+
128+
129+void FetchNotebooksJob::run()
130+{
131+ NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;
132+ std::vector<evernote::edam::Notebook> results;
133+ try {
134+ m_client->listNotebooks(results, m_token.toStdString());
135+ } catch(evernote::edam::EDAMUserException) {
136+ errorCode = NotesStore::ErrorCodeUserException;
137+ } catch(evernote::edam::EDAMSystemException) {
138+ errorCode = NotesStore::ErrorCodeSystemException;
139+ }
140+ emit resultReady(errorCode, results);
141+}
142
143=== added file 'src/plugin/Evernote/fetchnotebooksjob.h'
144--- src/plugin/Evernote/fetchnotebooksjob.h 1970-01-01 00:00:00 +0000
145+++ src/plugin/Evernote/fetchnotebooksjob.h 2013-11-24 20:43:59 +0000
146@@ -0,0 +1,29 @@
147+#ifndef FETCHNOTEBOOKSJOB_H
148+#define FETCHNOTEBOOKSJOB_H
149+
150+#include "notesstore.h"
151+
152+// Evernote SDK
153+#include <NoteStore.h>
154+#include <NoteStore_constants.h>
155+#include <Errors_types.h>
156+
157+#include <QThread>
158+
159+class FetchNotebooksJob : public QThread
160+{
161+ Q_OBJECT
162+public:
163+ explicit FetchNotebooksJob(evernote::edam::NoteStoreClient *client, const QString &token, QObject *parent = 0);
164+
165+ void run();
166+
167+signals:
168+ void resultReady(NotesStore::ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results);
169+
170+private:
171+ evernote::edam::NoteStoreClient *m_client;
172+ QString m_token;
173+};
174+
175+#endif // FETCHNOTEBOOKSJOB_H
176
177=== added file 'src/plugin/Evernote/fetchnotejob.cpp'
178--- src/plugin/Evernote/fetchnotejob.cpp 1970-01-01 00:00:00 +0000
179+++ src/plugin/Evernote/fetchnotejob.cpp 2013-11-24 20:43:59 +0000
180@@ -0,0 +1,26 @@
181+#include "fetchnotejob.h"
182+
183+FetchNoteJob::FetchNoteJob(evernote::edam::NoteStoreClient *client, const QString &token, const QString &guid, QObject *parent) :
184+ QThread(parent),
185+ m_client(client),
186+ m_token(token),
187+ m_guid(guid)
188+{
189+}
190+
191+void FetchNoteJob::run()
192+{
193+ NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;
194+ evernote::edam::Note result;
195+ try {
196+ m_client->getNote(result, m_token.toStdString(), m_guid.toStdString(), true, true, false, false);
197+ } catch(evernote::edam::EDAMUserException) {
198+ errorCode = NotesStore::ErrorCodeUserException;
199+ } catch(evernote::edam::EDAMSystemException) {
200+ errorCode = NotesStore::ErrorCodeSystemException;
201+ } catch(evernote::edam::EDAMNotFoundException) {
202+ errorCode = NotesStore::ErrorCodeNotFoundExcpetion;
203+ }
204+
205+ emit resultReady(errorCode, result);
206+}
207
208=== added file 'src/plugin/Evernote/fetchnotejob.h'
209--- src/plugin/Evernote/fetchnotejob.h 1970-01-01 00:00:00 +0000
210+++ src/plugin/Evernote/fetchnotejob.h 2013-11-24 20:43:59 +0000
211@@ -0,0 +1,29 @@
212+#ifndef FETCHNOTEJOB_H
213+#define FETCHNOTEJOB_H
214+
215+#include "notesstore.h"
216+
217+// Evernote SDK
218+#include <NoteStore.h>
219+#include <NoteStore_constants.h>
220+#include <Errors_types.h>
221+
222+#include <QThread>
223+
224+class FetchNoteJob : public QThread
225+{
226+ Q_OBJECT
227+public:
228+ explicit FetchNoteJob(evernote::edam::NoteStoreClient *client, const QString &token, const QString &guid, QObject *parent = 0);
229+
230+ void run();
231+signals:
232+ void resultReady(NotesStore::ErrorCode error, const evernote::edam::Note &note);
233+
234+private:
235+ evernote::edam::NoteStoreClient *m_client;
236+ QString m_token;
237+ QString m_guid;
238+};
239+
240+#endif // FETCHNOTEJOB_H
241
242=== added file 'src/plugin/Evernote/fetchnotesjob.cpp'
243--- src/plugin/Evernote/fetchnotesjob.cpp 1970-01-01 00:00:00 +0000
244+++ src/plugin/Evernote/fetchnotesjob.cpp 2013-11-24 20:43:59 +0000
245@@ -0,0 +1,48 @@
246+#include "fetchnotesjob.h"
247+
248+#include "notesstore.h"
249+
250+#include <QDebug>
251+
252+FetchNotesJob::FetchNotesJob(evernote::edam::NoteStoreClient *client,
253+ const QString &token,
254+ const QString &filterNotebookGuid, QObject *parent) :
255+ QThread(parent),
256+ m_client(client),
257+ m_token(token),
258+ m_filterNotebookGuid(filterNotebookGuid)
259+{
260+}
261+
262+void FetchNotesJob::run()
263+{
264+ // TODO: fix start/end (use smaller chunks and continue fetching if there are more notes available)
265+ int32_t start = 0;
266+ int32_t end = 10000;
267+
268+ // Prepare filter
269+ evernote::edam::NoteFilter filter;
270+ filter.notebookGuid = m_filterNotebookGuid.toStdString();
271+ filter.__isset.notebookGuid = !m_filterNotebookGuid.isEmpty();
272+
273+ // Prepare ResultSpec
274+ evernote::edam::NotesMetadataResultSpec resultSpec;
275+ resultSpec.includeNotebookGuid = true;
276+ resultSpec.__isset.includeNotebookGuid = true;
277+ resultSpec.includeTitle = true;
278+ resultSpec.__isset.includeTitle = true;
279+
280+ NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;
281+ evernote::edam::NotesMetadataList results;
282+
283+ try {
284+ m_client->findNotesMetadata(results, m_token.toStdString(), filter, start, end, resultSpec);
285+ } catch(evernote::edam::EDAMUserException) {
286+ errorCode = NotesStore::ErrorCodeUserException;
287+ } catch(evernote::edam::EDAMSystemException) {
288+ errorCode = NotesStore::ErrorCodeSystemException;
289+ } catch(evernote::edam::EDAMNotFoundException) {
290+ errorCode = NotesStore::ErrorCodeNotFoundExcpetion;
291+ }
292+ emit resultReady(errorCode, results);
293+}
294
295=== added file 'src/plugin/Evernote/fetchnotesjob.h'
296--- src/plugin/Evernote/fetchnotesjob.h 1970-01-01 00:00:00 +0000
297+++ src/plugin/Evernote/fetchnotesjob.h 2013-11-24 20:43:59 +0000
298@@ -0,0 +1,30 @@
299+#ifndef FETCHNOTESJOB_H
300+#define FETCHNOTESJOB_H
301+
302+#include "notesstore.h"
303+
304+// Evernote SDK
305+#include <NoteStore.h>
306+#include <NoteStore_constants.h>
307+#include <Errors_types.h>
308+
309+#include <QThread>
310+
311+class FetchNotesJob : public QThread
312+{
313+ Q_OBJECT
314+public:
315+ explicit FetchNotesJob(evernote::edam::NoteStoreClient *client, const QString &token, const QString &filterNotebookGuid, QObject *parent = 0);
316+
317+ void run();
318+
319+signals:
320+ void resultReady(NotesStore::ErrorCode errorCode, const evernote::edam::NotesMetadataList &results);
321+
322+private:
323+ evernote::edam::NoteStoreClient *m_client;
324+ QString m_token;
325+ QString m_filterNotebookGuid;
326+};
327+
328+#endif // FETCHNOTESJOB_H
329
330=== added file 'src/plugin/Evernote/note.cpp'
331--- src/plugin/Evernote/note.cpp 1970-01-01 00:00:00 +0000
332+++ src/plugin/Evernote/note.cpp 2013-11-24 20:43:59 +0000
333@@ -0,0 +1,51 @@
334+#include "note.h"
335+
336+Note::Note(const QString &guid, QObject *parent) :
337+ QObject(parent),
338+ m_guid(guid)
339+{
340+}
341+
342+QString Note::guid() const
343+{
344+ return m_guid;
345+}
346+
347+QString Note::notebookGuid() const
348+{
349+ return m_notebookGuid;
350+}
351+
352+void Note::setNotebookGuid(const QString &notebookGuid)
353+{
354+ if (m_notebookGuid != notebookGuid) {
355+ m_notebookGuid = notebookGuid;
356+ emit notebookGuidChanged();
357+ }
358+}
359+
360+QString Note::title() const
361+{
362+ return m_title;
363+}
364+
365+void Note::setTitle(const QString &title)
366+{
367+ if (m_title != title) {
368+ m_title = title;
369+ emit titleChanged();
370+ }
371+}
372+
373+QString Note::content() const
374+{
375+ return m_content;
376+}
377+
378+void Note::setContent(const QString &content)
379+{
380+ if (m_content != content) {
381+ m_content = content;
382+ emit contentChanged();
383+ }
384+}
385
386=== added file 'src/plugin/Evernote/note.h'
387--- src/plugin/Evernote/note.h 1970-01-01 00:00:00 +0000
388+++ src/plugin/Evernote/note.h 2013-11-24 20:43:59 +0000
389@@ -0,0 +1,40 @@
390+#ifndef NOTE_H
391+#define NOTE_H
392+
393+#include <QObject>
394+
395+class Note : public QObject
396+{
397+ Q_OBJECT
398+
399+ Q_PROPERTY(QString guid READ guid CONSTANT)
400+ Q_PROPERTY(QString notebookGuid READ notebookGuid WRITE setNotebookGuid NOTIFY notebookGuidChanged)
401+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
402+ Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)
403+public:
404+ explicit Note(const QString &guid, QObject *parent = 0);
405+
406+ QString guid() const;
407+
408+ QString notebookGuid() const;
409+ void setNotebookGuid(const QString &notebookGuid);
410+
411+ QString title() const;
412+ void setTitle(const QString &title);
413+
414+ QString content() const;
415+ void setContent(const QString &content);
416+
417+signals:
418+ void titleChanged();
419+ void notebookGuidChanged();
420+ void contentChanged();
421+
422+private:
423+ QString m_guid;
424+ QString m_notebookGuid;
425+ QString m_title;
426+ QString m_content;
427+};
428+
429+#endif // NOTE_H
430
431=== added file 'src/plugin/Evernote/notebook.cpp'
432--- src/plugin/Evernote/notebook.cpp 1970-01-01 00:00:00 +0000
433+++ src/plugin/Evernote/notebook.cpp 2013-11-24 20:43:59 +0000
434@@ -0,0 +1,25 @@
435+#include "notebook.h"
436+
437+Notebook::Notebook(QString guid, QObject *parent) :
438+ QObject(parent),
439+ m_guid(guid)
440+{
441+}
442+
443+QString Notebook::guid() const
444+{
445+ return m_guid;
446+}
447+
448+QString Notebook::name() const
449+{
450+ return m_name;
451+}
452+
453+void Notebook::setName(const QString &name)
454+{
455+ if (m_name != name) {
456+ m_name = name;
457+ emit nameChanged();
458+ }
459+}
460
461=== added file 'src/plugin/Evernote/notebook.h'
462--- src/plugin/Evernote/notebook.h 1970-01-01 00:00:00 +0000
463+++ src/plugin/Evernote/notebook.h 2013-11-24 20:43:59 +0000
464@@ -0,0 +1,30 @@
465+#ifndef NOTEBOOK_H
466+#define NOTEBOOK_H
467+
468+#include <QObject>
469+
470+class Notebook : public QObject
471+{
472+ Q_OBJECT
473+
474+ Q_PROPERTY(QString guid READ guid CONSTANT)
475+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
476+public:
477+ explicit Notebook(QString guid, QObject *parent = 0);
478+
479+ QString guid() const;
480+
481+ QString name() const;
482+ void setName(const QString &name);
483+
484+signals:
485+ void nameChanged();
486+
487+public slots:
488+
489+private:
490+ QString m_guid;
491+ QString m_name;
492+};
493+
494+#endif // NOTEBOOK_H
495
496=== modified file 'src/plugin/Evernote/notebooks.cpp'
497--- src/plugin/Evernote/notebooks.cpp 2013-11-21 23:30:15 +0000
498+++ src/plugin/Evernote/notebooks.cpp 2013-11-24 20:43:59 +0000
499@@ -1,27 +1,34 @@
500 #include "notebooks.h"
501+#include "notebook.h"
502
503 #include <QDebug>
504
505 Notebooks::Notebooks(QObject *parent) :
506 QAbstractListModel(parent)
507 {
508+ foreach (Notebook *notebook, NotesStore::instance()->notebooks()) {
509+ m_list.append(notebook->guid());
510+ }
511+
512+ connect(NotesStore::instance(), SIGNAL(notebookAdded(const QString &)), SLOT(notebookAdded(const QString &)));
513 }
514
515 QVariant Notebooks::data(const QModelIndex &index, int role) const
516 {
517+
518+ Notebook *notebook = NotesStore::instance()->notebook(m_list.at(index.row()));
519 switch(role) {
520 case RoleGuid:
521- return QString::fromStdString(m_list.at(index.row()).guid);
522+ return notebook->guid();
523 case RoleName:
524- return QString::fromStdString(m_list.at(index.row()).name);
525+ return notebook->name();
526 }
527-
528 return QVariant();
529 }
530
531 int Notebooks::rowCount(const QModelIndex &parent) const
532 {
533- return m_list.size();
534+ return m_list.count();
535 }
536
537 QHash<int, QByteArray> Notebooks::roleNames() const
538@@ -34,25 +41,13 @@
539
540 void Notebooks::refresh()
541 {
542-
543- QString token = NotesStore::instance()->token();
544- if (token.isEmpty()) {
545- qDebug() << "No token set. Cannot fetch notebooks.";
546- return;
547- }
548-
549- beginResetModel();
550- try {
551- NotesStore::instance()->evernoteNotesStoreClient()->listNotebooks(m_list, token.toStdString());
552- } catch(...) {
553- qDebug() << "Error fetching notebooks.";
554-// displayException();
555- }
556-
557- endResetModel();
558-
559-// for (int i = 0; i < notebooks.size(); ++i) {
560-// qDebug() << "got notebooks" << QString::fromStdString(notebooks.at(i).name) << QString::fromStdString(notebooks.at(i).name)
561-// << QString::fromStdString(notebooks.at(i).guid);
562-// }
563+ qDebug() << "refreshing notebooks";
564+ NotesStore::instance()->refreshNotebooks();
565+}
566+
567+void Notebooks::notebookAdded(const QString &guid)
568+{
569+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
570+ m_list.append(guid);
571+ endInsertRows();
572 }
573
574=== modified file 'src/plugin/Evernote/notebooks.h'
575--- src/plugin/Evernote/notebooks.h 2013-11-21 23:30:15 +0000
576+++ src/plugin/Evernote/notebooks.h 2013-11-24 20:43:59 +0000
577@@ -5,8 +5,6 @@
578
579 #include <QAbstractListModel>
580
581-using namespace evernote::edam;
582-
583 class Notebooks : public QAbstractListModel
584 {
585 Q_OBJECT
586@@ -24,10 +22,11 @@
587 public slots:
588 void refresh();
589
590+private slots:
591+ void notebookAdded(const QString &guid);
592+
593 private:
594- std::vector<Notebook> m_list;
595-
596-
597+ QList<QString> m_list;
598 };
599
600 #endif // NOTEBOOKS_H
601
602=== modified file 'src/plugin/Evernote/notes.cpp'
603--- src/plugin/Evernote/notes.cpp 2013-11-21 23:30:15 +0000
604+++ src/plugin/Evernote/notes.cpp 2013-11-24 20:43:59 +0000
605@@ -1,19 +1,22 @@
606 #include "notes.h"
607+#include "note.h"
608
609 #include <QDebug>
610
611 Notes::Notes(QObject *parent) :
612 QAbstractListModel(parent)
613 {
614+ connect(NotesStore::instance(), SIGNAL(noteAdded(const QString &)), SLOT(noteAdded(const QString &)));
615 }
616
617 QVariant Notes::data(const QModelIndex &index, int role) const
618 {
619+ Note *note = NotesStore::instance()->note(m_list.at(index.row()));
620 switch(role) {
621 case RoleGuid:
622- return QString::fromStdString(m_list.at(index.row()).guid);
623+ return note->guid();
624 case RoleTitle:
625- return QString::fromStdString(m_list.at(index.row()).title);
626+ return note->title();
627 }
628
629 return QVariant();
630@@ -45,59 +48,40 @@
631 }
632 }
633
634-QString Notes::note(const QString &noteGuid)
635-{
636- QString token = NotesStore::instance()->token();
637- if (token.isEmpty()) {
638- qDebug() << "No token set. Cannot fetch note.";
639- return QString();
640- }
641-
642- Note note;
643- try {
644- NotesStore::instance()->evernoteNotesStoreClient()->getNote(note, token.toStdString(), noteGuid.toStdString(), true, true, false, false);
645- } catch(...) {
646- qDebug() << "error fetching note";
647- return QString();
648- }
649-
650- return QString::fromStdString(note.content);
651+Note* Notes::note(const QString &guid)
652+{
653+ NotesStore::instance()->refreshNoteContent(guid);
654+ return NotesStore::instance()->note(guid);
655+}
656+
657+void Notes::componentComplete()
658+{
659+ foreach (Note *note, NotesStore::instance()->notes()) {
660+ if (m_filterNotebookGuid.isEmpty() || note->notebookGuid() == m_filterNotebookGuid) {
661+ m_list.append(note->guid());
662+ }
663+ }
664+ beginInsertRows(QModelIndex(), 0, m_list.count() - 1);
665+ endInsertRows();
666+ refresh();
667 }
668
669 void Notes::refresh()
670 {
671- QString token = NotesStore::instance()->token();
672- if (token.isEmpty()) {
673- qDebug() << "No token set. Cannot fetch notes.";
674- return;
675- }
676-
677- int32_t start = 0;
678- int32_t end = 10000;
679-
680- // Prepare filter
681- NoteFilter filter;
682- filter.notebookGuid = m_filterNotebookGuid.toStdString();
683- filter.__isset.notebookGuid = !m_filterNotebookGuid.isEmpty();
684-
685- // Prepare ResultSpec
686- NotesMetadataResultSpec resultSpec;
687- resultSpec.includeTitle = true;
688- resultSpec.__isset.includeTitle = true;
689-
690- NotesMetadataList notes;
691- try {
692- NotesStore::instance()->evernoteNotesStoreClient()->findNotesMetadata(notes, token.toStdString(), filter, start, end, resultSpec);
693- } catch(...) {
694- qDebug() << "error fetching notes";
695- return;
696- }
697-
698- beginResetModel();
699- m_list.clear();
700- foreach (NoteMetadata note, notes.notes) {
701- m_list.append(note);
702- qDebug() << QString::fromStdString(note.guid) << QString::fromStdString(note.title);
703- }
704- endResetModel();
705+ NotesStore::instance()->refreshNotes(m_filterNotebookGuid);
706+}
707+
708+void Notes::noteAdded(const QString &guid)
709+{
710+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
711+ m_list.append(guid);
712+ endInsertRows();
713+}
714+
715+void Notes::noteChanged(const QString &guid)
716+{
717+ int row = m_list.indexOf(guid);
718+ if (row >= 0) {
719+ emit dataChanged(index(row), index(row));
720+ }
721 }
722
723=== modified file 'src/plugin/Evernote/notes.h'
724--- src/plugin/Evernote/notes.h 2013-11-21 23:30:15 +0000
725+++ src/plugin/Evernote/notes.h 2013-11-24 20:43:59 +0000
726@@ -4,10 +4,9 @@
727 #include "notesstore.h"
728
729 #include <QAbstractListModel>
730-
731-using namespace evernote::edam;
732-
733-class Notes : public QAbstractListModel
734+#include <QQmlParserStatus>
735+
736+class Notes : public QAbstractListModel, public QQmlParserStatus
737 {
738 Q_OBJECT
739 Q_PROPERTY(QString filterNotebookGuid READ filterNotebookGuid WRITE setFilterNotebookGuid NOTIFY filterNotebookGuidChanged)
740@@ -25,16 +24,23 @@
741 QString filterNotebookGuid() const;
742 void setFilterNotebookGuid(const QString &notebookGuid);
743
744- Q_INVOKABLE QString note(const QString &noteGuid);
745+ Q_INVOKABLE Note* note(const QString &guid);
746+
747+ void classBegin() {}
748+ void componentComplete();
749
750 public slots:
751 void refresh();
752
753+private slots:
754+ void noteAdded(const QString &guid);
755+ void noteChanged(const QString &guid);
756+
757 signals:
758 void filterNotebookGuidChanged();
759
760 private:
761- QList<NoteMetadata> m_list;
762+ QList<QString> m_list;
763 QString m_filterNotebookGuid;
764
765 };
766
767=== modified file 'src/plugin/Evernote/notesstore.cpp'
768--- src/plugin/Evernote/notesstore.cpp 2013-11-21 23:30:15 +0000
769+++ src/plugin/Evernote/notesstore.cpp 2013-11-24 20:43:59 +0000
770@@ -1,6 +1,11 @@
771 #include "notesstore.h"
772-
773 #include "notebooks.h"
774+#include "notebook.h"
775+#include "note.h"
776+
777+#include "fetchnotesjob.h"
778+#include "fetchnotebooksjob.h"
779+#include "fetchnotejob.h"
780
781 // Thrift
782 #include <arpa/inet.h> // seems thrift forgot this one
783@@ -11,7 +16,6 @@
784
785 #include <QDebug>
786
787-using namespace evernote::edam;
788 using namespace apache::thrift;
789 using namespace apache::thrift::protocol;
790 using namespace apache::thrift::transport;
791@@ -19,11 +23,10 @@
792 NotesStore* NotesStore::s_instance = 0;
793
794 NotesStore::NotesStore(QObject *parent) :
795- QObject(parent)
796+ QObject(parent),
797+ m_currentJob(0)
798 {
799 try {
800- // TODO: Move this to a common place instead of keeping a copy here and in UserStore
801-
802 // FIXME: need to populate this string from the system
803 // The structure should be:
804 // application/version; platform/version; [ device/version ]
805@@ -54,13 +57,21 @@
806 userStoreHttpClient->open();
807
808 boost::shared_ptr<TProtocol> iprot(new TBinaryProtocol(userStoreHttpClient));
809- m_client = new NoteStoreClient(iprot);
810+ m_client = new evernote::edam::NoteStoreClient(iprot);
811
812 qDebug() << "NoteStore client created.";
813- } catch(...) {
814- displayException();
815+
816+ } catch (const TTransportException & e) {
817+ qWarning() << "Failed to create Transport:" << e.what();
818+ } catch (const TException & e) {
819+ qWarning() << "Generic Thrift exception:" << e.what();
820 }
821
822+ qRegisterMetaType<NotesStore::ErrorCode>("NotesStore::ErrorCode");
823+ qRegisterMetaType<evernote::edam::NotesMetadataList>("evernote::edam::NotesMetadataList");
824+ qRegisterMetaType<evernote::edam::Note>("evernote::edam::Note");
825+ qRegisterMetaType<std::vector<evernote::edam::Notebook> >("std::vector<evernote::edam::Notebook>");
826+
827 }
828
829 NotesStore *NotesStore::instance()
830@@ -71,6 +82,21 @@
831 return s_instance;
832 }
833
834+QString NotesStore::errorCodeToString(NotesStore::ErrorCode errorCode)
835+{
836+ switch(errorCode) {
837+ case ErrorCodeNoError:
838+ return QStringLiteral("No error");
839+ case ErrorCodeUserException:
840+ return QStringLiteral("User exception");
841+ case ErrorCodeSystemException:
842+ return QStringLiteral("System exception");
843+ case ErrorCodeNotFoundExcpetion:
844+ return QStringLiteral("Not found");
845+ }
846+ return QString();
847+}
848+
849 NotesStore::~NotesStore()
850 {
851 delete m_client;
852@@ -84,56 +110,159 @@
853 void NotesStore::setToken(const QString &token)
854 {
855 if (token != m_token) {
856- qDebug() << "NotesStore: setting token:" << token;
857 m_token = token;
858 emit tokenChanged();
859- }
860-}
861-
862-NoteStoreClient *NotesStore::evernoteNotesStoreClient()
863-{
864- return m_client;
865-}
866-
867-// TODO: move to a common place instead of copying it through *store.cpps
868-void NotesStore::displayException()
869-{
870- QString error_message = "Unknown Exception";
871- try
872- {
873- // this function is meant to be called from a catch block
874- // rethrow the exception to catch it again
875- throw;
876- }
877- catch (const EDAMNotFoundException & e)
878- {
879- qDebug() << e.what();
880- }
881- catch (const EDAMSystemException & e)
882- {
883- qDebug() << e.what();
884- }
885- catch (const EDAMUserException & e)
886- {
887- qDebug() << e.what();
888- }
889- catch (const TTransportException & e)
890- {
891- qDebug() << e.what();
892- }
893- catch (const TException & e)
894- {
895- qDebug() << e.what();
896- }
897- catch (const std::exception & e)
898- {
899- qDebug() << e.what();
900- }
901- catch (...)
902- {
903- error_message = "Tried to sync, but something went wrong.\n Unknown exception.";
904- }
905-
906- qDebug() << error_message;
907- disconnect();
908+ refreshNotebooks();
909+ refreshNotes();
910+ }
911+}
912+
913+QList<Note*> NotesStore::notes() const
914+{
915+ return m_notes.values();
916+}
917+
918+Note *NotesStore::note(const QString &guid)
919+{
920+ return m_notes.value(guid);
921+}
922+
923+QList<Notebook *> NotesStore::notebooks() const
924+{
925+ return m_notebooks.values();
926+}
927+
928+Notebook *NotesStore::notebook(const QString &guid)
929+{
930+ return m_notebooks.value(guid);
931+}
932+
933+void NotesStore::startJobQueue()
934+{
935+ if (m_requestQueue.isEmpty()) {
936+ return;
937+ }
938+
939+ if (m_currentJob) {
940+ return;
941+ }
942+ m_currentJob = m_requestQueue.takeFirst();
943+ m_currentJob->start();
944+}
945+
946+void NotesStore::startNextJob()
947+{
948+ m_currentJob = 0;
949+ startJobQueue();
950+}
951+
952+void NotesStore::refreshNotes(const QString &filterNotebookGuid)
953+{
954+ if (m_token.isEmpty()) {
955+ qWarning() << "No token set. Cannot fetch notes.";
956+ return;
957+ }
958+
959+ FetchNotesJob *job = new FetchNotesJob(m_client, m_token, filterNotebookGuid);
960+ connect(job, &FetchNotesJob::resultReady, this, &NotesStore::fetchNotesJobDone);
961+ connect(job, &FetchNoteJob::finished, job, &FetchNotesJob::deleteLater);
962+
963+ m_requestQueue.append(job);
964+ startJobQueue();
965+}
966+
967+void NotesStore::fetchNotesJobDone(ErrorCode errorCode, const evernote::edam::NotesMetadataList &results)
968+{
969+ if (errorCode != ErrorCodeNoError) {
970+ qWarning() << "Failed to fetch notes list:" << errorCodeToString(errorCode);
971+ startNextJob();
972+ return;
973+ }
974+
975+ for (int i = 0; i < results.notes.size(); ++i) {
976+ evernote::edam::NoteMetadata result = results.notes.at(i);
977+ Note *note = m_notes.value(QString::fromStdString(result.guid));
978+ if (note) {
979+ qDebug() << "Received update for existing note";
980+ } else {
981+ note = new Note(QString::fromStdString(result.guid), this);
982+ note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
983+ note->setTitle(QString::fromStdString(result.title));
984+ m_notes.insert(note->guid(), note);
985+ emit noteAdded(note->guid());
986+ }
987+ }
988+
989+ startNextJob();
990+}
991+
992+void NotesStore::refreshNoteContent(const QString &guid)
993+{
994+ if (m_token.isEmpty()) {
995+ qWarning() << "No token set. Cannot fetch note.";
996+ return;
997+ }
998+
999+ FetchNoteJob *job = new FetchNoteJob(m_client, m_token, guid, this);
1000+ connect(job, &FetchNoteJob::resultReady, this, &NotesStore::fetchNoteJobDone);
1001+ connect(job, &FetchNoteJob::finished, job, &FetchNoteJob::deleteLater);
1002+ m_requestQueue.append(job);
1003+
1004+ startJobQueue();
1005+}
1006+
1007+void NotesStore::fetchNoteJobDone(ErrorCode errorCode, const evernote::edam::Note &result)
1008+{
1009+ if (errorCode != ErrorCodeNoError) {
1010+ qWarning() << "Error fetching note:" << errorCode;
1011+ startNextJob();
1012+ return;
1013+ }
1014+
1015+ Note *note = m_notes.value(QString::fromStdString(result.guid));
1016+ note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
1017+ note->setTitle(QString::fromStdString(result.title));
1018+ note->setContent(QString::fromStdString(result.content));
1019+ emit noteChanged(note->guid());
1020+
1021+ startNextJob();
1022+}
1023+
1024+void NotesStore::refreshNotebooks()
1025+{
1026+ if (m_token.isEmpty()) {
1027+ qWarning() << "No token set. Cannot refresh notebooks.";
1028+ return;
1029+ }
1030+
1031+ FetchNotebooksJob *job = new FetchNotebooksJob(m_client, m_token);
1032+ connect(job, &FetchNotebooksJob::resultReady, this, &NotesStore::fetchNotebooksJobDone);
1033+ connect(job, &FetchNotebooksJob::finished, job, &FetchNotebooksJob::deleteLater);
1034+
1035+ m_requestQueue.append(job);
1036+ startJobQueue();
1037+}
1038+
1039+void NotesStore::fetchNotebooksJobDone(ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results)
1040+{
1041+ if (errorCode != ErrorCodeNoError) {
1042+ qWarning() << "Error fetching notebooks:" << errorCodeToString(errorCode);
1043+ startNextJob();
1044+ return;
1045+ }
1046+
1047+ for (int i = 0; i < results.size(); ++i) {
1048+ evernote::edam::Notebook result = results.at(i);
1049+ Notebook *notebook = m_notebooks.value(QString::fromStdString(result.guid));
1050+ if (notebook) {
1051+ qDebug() << "got notebook update";
1052+ } else {
1053+ notebook = new Notebook(QString::fromStdString(result.guid), this);
1054+ notebook->setName(QString::fromStdString(result.name));
1055+ m_notebooks.insert(notebook->guid(), notebook);
1056+ emit notebookAdded(notebook->guid());
1057+ }
1058+ }
1059+
1060+ startNextJob();
1061 }
1062
1063=== modified file 'src/plugin/Evernote/notesstore.h'
1064--- src/plugin/Evernote/notesstore.h 2013-11-21 23:30:15 +0000
1065+++ src/plugin/Evernote/notesstore.h 2013-11-24 20:43:59 +0000
1066@@ -6,12 +6,11 @@
1067 #include <NoteStore_constants.h>
1068 #include <Errors_types.h>
1069
1070-// Qt
1071 #include <QObject>
1072-
1073-using namespace evernote::edam;
1074-
1075-class Notebooks;
1076+#include <QHash>
1077+
1078+class Notebook;
1079+class Note;
1080
1081 class NotesStore : public QObject
1082 {
1083@@ -19,29 +18,59 @@
1084 Q_PROPERTY(QString token READ token WRITE setToken NOTIFY tokenChanged)
1085
1086 public:
1087+ enum ErrorCode {
1088+ ErrorCodeNoError,
1089+ ErrorCodeUserException,
1090+ ErrorCodeSystemException,
1091+ ErrorCodeNotFoundExcpetion
1092+ };
1093+
1094 static NotesStore *instance();
1095+ static QString errorCodeToString(ErrorCode errorCode);
1096
1097 ~NotesStore();
1098
1099 QString token() const;
1100 void setToken(const QString &token);
1101
1102- NoteStoreClient *evernoteNotesStoreClient();
1103-
1104-private:
1105- explicit NotesStore(QObject *parent = 0);
1106+ QList<Note*> notes() const;
1107+ Note* note(const QString &guid);
1108+
1109+ QList<Notebook*> notebooks() const;
1110+ Notebook* notebook(const QString &guid);
1111+
1112+ void refreshNotes(const QString &filterNotebookGuid = QString());
1113+ void refreshNoteContent(const QString &guid);
1114+ void refreshNotebooks();
1115
1116 signals:
1117 void tokenChanged();
1118
1119+ void noteAdded(const QString &guid);
1120+ void noteChanged(const QString &guid);
1121+
1122+ void notebookAdded(const QString &guid);
1123+
1124+private slots:
1125+ void fetchNotesJobDone(ErrorCode errorCode, const evernote::edam::NotesMetadataList &results);
1126+ void fetchNotebooksJobDone(ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results);
1127+ void fetchNoteJobDone(ErrorCode errorCode, const evernote::edam::Note &result);
1128+
1129+ void startJobQueue();
1130+ void startNextJob();
1131+
1132 private:
1133+ explicit NotesStore(QObject *parent = 0);
1134 static NotesStore *s_instance;
1135
1136- void displayException();
1137-
1138 QString m_token;
1139- NoteStoreClient *m_client;
1140-
1141+ evernote::edam::NoteStoreClient *m_client;
1142+
1143+ QHash<QString, Notebook*> m_notebooks;
1144+ QHash<QString, Note*> m_notes;
1145+
1146+ QList<QThread*> m_requestQueue;
1147+ QThread *m_currentJob;
1148 };
1149
1150 #endif // NOTESSTORE_H
1151
1152=== modified file 'src/plugin/Evernote/userstore.h'
1153--- src/plugin/Evernote/userstore.h 2013-11-21 23:30:15 +0000
1154+++ src/plugin/Evernote/userstore.h 2013-11-24 20:43:59 +0000
1155@@ -5,8 +5,6 @@
1156
1157 #include <QObject>
1158
1159-using namespace evernote::edam;
1160-
1161 class UserStore : public QObject
1162 {
1163 Q_OBJECT

Subscribers

People subscribed via source and target branches