Merge lp:~mzanetti/reminders-app/add-reminders into lp:reminders-app

Proposed by Michael Zanetti
Status: Merged
Approved by: Michael Zanetti
Approved revision: 19
Merged at revision: 17
Proposed branch: lp:~mzanetti/reminders-app/add-reminders
Merge into: lp:reminders-app
Prerequisite: lp:~mzanetti/reminders-app/get-username
Diff against target: 952 lines (+375/-195)
13 files modified
src/app/qml/ui/NotesPage.qml (+2/-3)
src/app/qml/ui/RemindersPage.qml (+9/-10)
src/plugin/Evernote/jobs/evernotejob.cpp (+1/-1)
src/plugin/Evernote/jobs/fetchnotesjob.cpp (+13/-3)
src/plugin/Evernote/jobs/savenotejob.cpp (+22/-13)
src/plugin/Evernote/jobs/savenotejob.h (+2/-6)
src/plugin/Evernote/note.cpp (+90/-10)
src/plugin/Evernote/note.h (+44/-4)
src/plugin/Evernote/notebooks.cpp (+0/-1)
src/plugin/Evernote/notes.cpp (+38/-80)
src/plugin/Evernote/notes.h (+11/-24)
src/plugin/Evernote/notesstore.cpp (+116/-31)
src/plugin/Evernote/notesstore.h (+27/-9)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/add-reminders
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Jordan Keyes Approve
Review via email: mp+197261@code.launchpad.net

Commit message

Add support for reminders

Description of the change

This adds support for reminders.

Also moves the QAbstractListModel logic into notesstore, so that Notes is just a stupid QSortFilterProxyModel. This additionally has the benefit that we can easily filter for notebookGuid or the reminder flag (and in the future for tags) and sort the model according to the note creation timestamp (or whatever we need in the future).

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

fix savenotejob to also store reminder stuff

18. By Michael Zanetti

delete note clone after savejob is done

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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jordan Keyes (jkeyes0) wrote :

Maybe this is by design, but when you select a note from the Notes tab, then click the "Save" button (or make a change to the text and click "Save"), it adds a reminder to the note. I haven't noticed this behavior from other Evernote clients.
It appears this was added in src/plugin/Evernote/jobs/savenotejob.cpp, in void SaveNoteJob::startJob(), but my C++ is definitely a bit rusty.

Is this something that will need to be pulled out and put into a separate job for when a new reminder is created?

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

> Maybe this is by design, but when you select a note from the Notes tab, then
> click the "Save" button (or make a change to the text and click "Save"), it
> adds a reminder to the note. I haven't noticed this behavior from other
> Evernote clients.

No, this is a bug in my code. Thanks for finding!

> It appears this was added in src/plugin/Evernote/jobs/savenotejob.cpp, in void
> SaveNoteJob::startJob(), but my C++ is definitely a bit rusty.
>
> Is this something that will need to be pulled out and put into a separate job
> for when a new reminder is created?

Not really no, we just need initialize it with some sane defaults... I'll fix tonight.

Btw. feel free to put "Needs fixing" on my merges. If really unsure, mark it as "Needs information". I'm thankful for every found issue. After all that's what those merge requests are for.

19. By Michael Zanetti

fix reminder flag when saving notes

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

> Maybe this is by design, but when you select a note from the Notes tab, then
> click the "Save" button (or make a change to the text and click "Save"), it
> adds a reminder to the note. I haven't noticed this behavior from other
> Evernote clients.

fixed

Revision history for this message
Jordan Keyes (jkeyes0) wrote :

Looks good here.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/qml/ui/NotesPage.qml'
2--- src/app/qml/ui/NotesPage.qml 2013-11-26 17:18:33 +0000
3+++ src/app/qml/ui/NotesPage.qml 2013-12-12 21:36:37 +0000
4@@ -28,8 +28,7 @@
5
6 onActiveChanged: {
7 if (active) {
8- print("refreshing notes")
9- notes.refresh();
10+ NotesStore.refreshNotes();
11 }
12 }
13
14@@ -59,7 +58,7 @@
15 text: title
16
17 onClicked: {
18- pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: notes.note(guid)})
19+ pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})
20 }
21
22 onPressAndHold: {
23
24=== modified file 'src/app/qml/ui/RemindersPage.qml'
25--- src/app/qml/ui/RemindersPage.qml 2013-11-26 17:18:33 +0000
26+++ src/app/qml/ui/RemindersPage.qml 2013-12-12 21:36:37 +0000
27@@ -19,28 +19,27 @@
28 import QtQuick 2.0
29 import Ubuntu.Components 0.1
30 import Ubuntu.Components.ListItems 0.1
31-//import "../components"
32+import Evernote 0.1
33
34 Page {
35 id: remindersPage
36
37- Label {
38- id: developmentWarning
39- anchors.centerIn: parent
40- text: i18n.tr("This page is still in development")
41+ Notes {
42+ id: notes
43+ onlyReminders: true
44 }
45
46 ListView {
47
48- width: parent.width; height: parent.height
49+ anchors.fill: parent
50
51 delegate: Subtitled {
52- text: '<b>Name:</b> ' + model.name
53- subText: '<b>Date:</b> ' + model.date
54+ text: '<b>Name:</b> ' + model.title
55+ subText: '<b>Date:</b> ' + Qt.formatDateTime(model.created) +
56+ (model.reminderDone ? " - <b>Done:</b> " + Qt.formatDate(model.reminderDoneTime) : "")
57 }
58
59-// model: RemindersModel {}
60-
61+ model: notes
62 }
63
64 }
65
66=== modified file 'src/plugin/Evernote/jobs/evernotejob.cpp'
67--- src/plugin/Evernote/jobs/evernotejob.cpp 2013-12-12 21:36:37 +0000
68+++ src/plugin/Evernote/jobs/evernotejob.cpp 2013-12-12 21:36:37 +0000
69@@ -48,7 +48,7 @@
70 void EvernoteJob::run()
71 {
72 if (m_token.isEmpty()) {
73- qWarning() << "No token set. Cannot execute job.";
74+ qWarning() << "No token set. Cannot execute job. (" << this->metaObject()->className() << ")";
75 emitJobDone(EvernoteConnection::ErrorCodeUserException, QStringLiteral("No token set."));
76 return;
77 }
78
79=== modified file 'src/plugin/Evernote/jobs/fetchnotesjob.cpp'
80--- src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-12-12 21:36:37 +0000
81+++ src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-12-12 21:36:37 +0000
82@@ -22,6 +22,9 @@
83
84 #include "notesstore.h"
85
86+// evernote sdk
87+#include "Limits_constants.h"
88+
89 #include <QDebug>
90
91 FetchNotesJob::FetchNotesJob( const QString &filterNotebookGuid, QObject *parent) :
92@@ -32,10 +35,10 @@
93
94 void FetchNotesJob::startJob()
95 {
96- qDebug() << "starting fetch notes job";
97 // TODO: fix start/end (use smaller chunks and continue fetching if there are more notes available)
98 int32_t start = 0;
99- int32_t end = 10000;
100+ evernote::limits::LimitsConstants limits;
101+ int32_t end = limits.EDAM_USER_NOTES_MAX;
102
103 // Prepare filter
104 evernote::edam::NoteFilter filter;
105@@ -44,13 +47,20 @@
106
107 // Prepare ResultSpec
108 evernote::edam::NotesMetadataResultSpec resultSpec;
109+
110 resultSpec.includeNotebookGuid = true;
111 resultSpec.__isset.includeNotebookGuid = true;
112+
113+ resultSpec.includeCreated = true;
114+ resultSpec.__isset.includeCreated = true;
115+
116 resultSpec.includeTitle = true;
117 resultSpec.__isset.includeTitle = true;
118
119+ resultSpec.includeAttributes = true;
120+ resultSpec.__isset.includeAttributes = true;
121+
122 client()->findNotesMetadata(m_results, token().toStdString(), filter, start, end, resultSpec);
123- qDebug() << "ending fetch notes job";
124 }
125
126 void FetchNotesJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
127
128=== modified file 'src/plugin/Evernote/jobs/savenotejob.cpp'
129--- src/plugin/Evernote/jobs/savenotejob.cpp 2013-12-12 21:36:37 +0000
130+++ src/plugin/Evernote/jobs/savenotejob.cpp 2013-12-12 21:36:37 +0000
131@@ -24,31 +24,40 @@
132 #include <QDebug>
133
134 SaveNoteJob::SaveNoteJob(Note *note, QObject *parent) :
135- NotesStoreJob(parent),
136- m_guid(note->guid()),
137- m_title(note->title()),
138- m_notebookGuid(note->notebookGuid()),
139- m_content(note->content())
140+ NotesStoreJob(parent)
141 {
142+ // Need to clone it. As startJob() will run in another thread we can't access the real note from there.
143+ m_note = note->clone();
144+
145+ // Make sure we delete the clone when done
146+ m_note->setParent(this);
147 }
148
149 void SaveNoteJob::startJob()
150 {
151 evernote::edam::Note note;
152- note.guid = m_guid.toStdString();
153+ note.guid = m_note->guid().toStdString();
154 note.__isset.guid = true;
155- note.title = m_title.toStdString();
156+ note.title = m_note->title().toStdString();
157 note.__isset.title = true;
158- note.notebookGuid = m_notebookGuid.toStdString();
159+ note.notebookGuid = m_note->notebookGuid().toStdString();
160 note.__isset.notebookGuid = true;
161- note.content = m_content.toStdString();
162+ note.content = m_note->content().toStdString();
163 note.__isset.content = true;
164- note.contentLength = m_content.length();
165-
166- client()->updateNote(m_note, token().toStdString(), note);
167+ note.contentLength = m_note->content().length();
168+
169+ note.__isset.attributes = true;
170+ note.attributes.reminderOrder = m_note->reminderOrder();
171+ note.attributes.__isset.reminderOrder = true;
172+ note.attributes.reminderTime = m_note->reminderTime().toMSecsSinceEpoch();
173+ note.attributes.__isset.reminderTime = true;
174+ note.attributes.reminderDoneTime = m_note->reminderDoneTime().toMSecsSinceEpoch();
175+ note.attributes.__isset.reminderDoneTime = true;
176+
177+ client()->updateNote(m_resultNote, token().toStdString(), note);
178 }
179
180 void SaveNoteJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
181 {
182- emit jobDone(errorCode, errorMessage, m_note);
183+ emit jobDone(errorCode, errorMessage, m_resultNote);
184 }
185
186=== modified file 'src/plugin/Evernote/jobs/savenotejob.h'
187--- src/plugin/Evernote/jobs/savenotejob.h 2013-12-12 21:36:37 +0000
188+++ src/plugin/Evernote/jobs/savenotejob.h 2013-12-12 21:36:37 +0000
189@@ -17,12 +17,8 @@
190 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
191
192 private:
193- QString m_guid;
194- QString m_title;
195- QString m_notebookGuid;
196- QString m_content;
197-
198- evernote::edam::Note m_note;
199+ Note* m_note;
200+ evernote::edam::Note m_resultNote;
201 };
202
203 #endif // SAVENOTEJOB_H
204
205=== modified file 'src/plugin/Evernote/note.cpp'
206--- src/plugin/Evernote/note.cpp 2013-12-12 21:36:37 +0000
207+++ src/plugin/Evernote/note.cpp 2013-12-12 21:36:37 +0000
208@@ -22,9 +22,12 @@
209
210 #include "notesstore.h"
211
212-Note::Note(const QString &guid, QObject *parent) :
213+#include <QDateTime>
214+
215+Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :
216 QObject(parent),
217- m_guid(guid)
218+ m_guid(guid),
219+ m_created(created)
220 {
221 }
222
223@@ -33,14 +36,6 @@
224 return m_guid;
225 }
226
227-void Note::setGuid(const QString &guid)
228-{
229- if (m_guid != guid) {
230- m_guid = guid;
231- emit guidChanged();
232- }
233-}
234-
235 QString Note::notebookGuid() const
236 {
237 return m_notebookGuid;
238@@ -54,6 +49,11 @@
239 }
240 }
241
242+QDateTime Note::created() const
243+{
244+ return m_created;
245+}
246+
247 QString Note::title() const
248 {
249 return m_title;
250@@ -80,6 +80,86 @@
251 }
252 }
253
254+bool Note::reminder() const
255+{
256+ return m_reminderOrder > 0;
257+}
258+
259+void Note::setReminder(bool reminder)
260+{
261+ if (reminder && m_reminderOrder == 0) {
262+ m_reminderOrder = QDateTime::currentMSecsSinceEpoch();
263+ emit reminderChanged();
264+ } else if (!reminder && m_reminderOrder > 0) {
265+ m_reminderOrder = 0;
266+ emit reminderChanged();
267+ }
268+}
269+
270+qint64 Note::reminderOrder() const
271+{
272+ return m_reminderOrder;
273+}
274+
275+void Note::setReminderOrder(qint64 reminderOrder)
276+{
277+ if (m_reminderOrder != reminderOrder) {
278+ m_reminderOrder = reminderOrder;
279+ emit reminderChanged();
280+ }
281+}
282+
283+QDateTime Note::reminderTime() const
284+{
285+ return m_reminderTime;
286+}
287+
288+void Note::setReminderTime(const QDateTime &reminderTime)
289+{
290+ if (m_reminderTime != reminderTime) {
291+ m_reminderTime = reminderTime;
292+ emit reminderTimeChanged();
293+ }
294+}
295+
296+bool Note::reminderDone() const
297+{
298+ return !m_reminderDoneTime.isNull();
299+}
300+
301+void Note::setReminderDone(bool reminderDone)
302+{
303+ if (reminderDone && m_reminderDoneTime.isNull()) {
304+ m_reminderDoneTime = QDateTime::currentDateTime();
305+ emit reminderDoneChanged();
306+ }
307+}
308+
309+QDateTime Note::reminderDoneTime() const
310+{
311+ return m_reminderDoneTime;
312+}
313+
314+void Note::setReminderDoneTime(const QDateTime &reminderDoneTime)
315+{
316+ if (m_reminderDoneTime != reminderDoneTime) {
317+ m_reminderDoneTime = reminderDoneTime;
318+ emit reminderDoneChanged();
319+ }
320+}
321+
322+Note *Note::clone()
323+{
324+ Note *note = new Note(m_guid, m_created);
325+ note->setNotebookGuid(m_notebookGuid);
326+ note->setTitle(m_title);
327+ note->setContent(m_content);
328+ note->setReminderOrder(m_reminderOrder);
329+ note->setReminderTime(m_reminderTime);
330+ note->setReminderDoneTime(m_reminderDoneTime);
331+ return note;
332+}
333+
334 void Note::save()
335 {
336 NotesStore::instance()->saveNote(m_guid);
337
338=== modified file 'src/plugin/Evernote/note.h'
339--- src/plugin/Evernote/note.h 2013-11-25 00:49:48 +0000
340+++ src/plugin/Evernote/note.h 2013-12-12 21:36:37 +0000
341@@ -2,45 +2,85 @@
342 #define NOTE_H
343
344 #include <QObject>
345+#include <QDateTime>
346+#include <QStringList>
347
348 class Note : public QObject
349 {
350 Q_OBJECT
351
352- Q_PROPERTY(QString guid READ guid NOTIFY guidChanged)
353+ // Don't forget to update clone() if you add properties!
354+ Q_PROPERTY(QString guid READ guid CONSTANT)
355 Q_PROPERTY(QString notebookGuid READ notebookGuid WRITE setNotebookGuid NOTIFY notebookGuidChanged)
356+ Q_PROPERTY(QDateTime created READ created CONSTANT)
357 Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
358 Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)
359+ Q_PROPERTY(bool reminder READ reminder WRITE setReminder NOTIFY reminderChanged)
360+ Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)
361+ Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)
362+ Q_PROPERTY(QDateTime reminderDoneTime READ reminderDoneTime WRITE setReminderDoneTime NOTIFY reminderDoneChanged)
363+ // Don't forget to update clone() if you add properties!
364+
365 public:
366- explicit Note(const QString &guid = QString(), QObject *parent = 0);
367+ explicit Note(const QString &guid, const QDateTime &created, QObject *parent = 0);
368
369 QString guid() const;
370- void setGuid(const QString &guid);
371
372 QString notebookGuid() const;
373 void setNotebookGuid(const QString &notebookGuid);
374
375+ QDateTime created() const;
376+
377 QString title() const;
378 void setTitle(const QString &title);
379
380 QString content() const;
381 void setContent(const QString &content);
382
383+ // This is the QML representation as we don't want to deal with timestamps there.
384+ // setting it to false will reset the reminderOrder to 0, setting it to true will
385+ // create a new timestamp for it.
386+ bool reminder() const;
387+ void setReminder(bool reminder);
388+
389+ qint64 reminderOrder() const;
390+ void setReminderOrder(qint64 reminderOrder);
391+
392+ QDateTime reminderTime() const;
393+ void setReminderTime(const QDateTime &reminderTime);
394+
395+ // This is the QML representation as we don't want to deal with timestamps there.
396+ // setting it to false will reset reminderDoneTime to 0, setting it to true will
397+ // create a new timestamp for it.
398+ bool reminderDone() const;
399+ void setReminderDone(bool reminderDone);
400+
401+ QDateTime reminderDoneTime() const;
402+ void setReminderDoneTime(const QDateTime &reminderDoneTime);
403+
404+ Note* clone();
405+
406 public slots:
407 void save();
408 void remove();
409
410 signals:
411- void guidChanged();
412 void titleChanged();
413 void notebookGuidChanged();
414 void contentChanged();
415+ void reminderChanged();
416+ void reminderTimeChanged();
417+ void reminderDoneChanged();
418
419 private:
420 QString m_guid;
421 QString m_notebookGuid;
422+ QDateTime m_created;
423 QString m_title;
424 QString m_content;
425+ qint64 m_reminderOrder;
426+ QDateTime m_reminderTime;
427+ QDateTime m_reminderDoneTime;
428 };
429
430 #endif // NOTE_H
431
432=== modified file 'src/plugin/Evernote/notebooks.cpp'
433--- src/plugin/Evernote/notebooks.cpp 2013-11-26 17:18:33 +0000
434+++ src/plugin/Evernote/notebooks.cpp 2013-12-12 21:36:37 +0000
435@@ -35,7 +35,6 @@
436
437 QVariant Notebooks::data(const QModelIndex &index, int role) const
438 {
439-
440 Notebook *notebook = NotesStore::instance()->notebook(m_list.at(index.row()));
441 switch(role) {
442 case RoleGuid:
443
444=== modified file 'src/plugin/Evernote/notes.cpp'
445--- src/plugin/Evernote/notes.cpp 2013-11-26 17:18:33 +0000
446+++ src/plugin/Evernote/notes.cpp 2013-12-12 21:36:37 +0000
447@@ -24,37 +24,12 @@
448 #include <QDebug>
449
450 Notes::Notes(QObject *parent) :
451- QAbstractListModel(parent)
452-{
453- connect(NotesStore::instance(), &NotesStore::noteAdded, this, &Notes::noteAdded);
454- connect(NotesStore::instance(), &NotesStore::noteRemoved, this, &Notes::noteRemoved);
455- connect(NotesStore::instance(), &NotesStore::noteChanged, this, &Notes::noteChanged);
456-}
457-
458-QVariant Notes::data(const QModelIndex &index, int role) const
459-{
460- Note *note = NotesStore::instance()->note(m_list.at(index.row()));
461- switch(role) {
462- case RoleGuid:
463- return note->guid();
464- case RoleTitle:
465- return note->title();
466- }
467-
468- return QVariant();
469-}
470-
471-int Notes::rowCount(const QModelIndex &parent) const
472-{
473- return m_list.count();
474-}
475-
476-QHash<int, QByteArray> Notes::roleNames() const
477-{
478- QHash<int, QByteArray> roles;
479- roles.insert(RoleGuid, "guid");
480- roles.insert(RoleTitle, "title");
481- return roles;
482+ QSortFilterProxyModel(parent),
483+ m_onlyReminders(false)
484+{
485+ setSourceModel(NotesStore::instance());
486+ setSortRole(NotesStore::RoleCreated);
487+ sort(0, Qt::DescendingOrder);
488 }
489
490 QString Notes::filterNotebookGuid() const
491@@ -67,53 +42,36 @@
492 if (m_filterNotebookGuid != notebookGuid) {
493 m_filterNotebookGuid = notebookGuid;
494 emit filterNotebookGuidChanged();
495- }
496-}
497-
498-Note* Notes::note(const QString &guid)
499-{
500- NotesStore::instance()->refreshNoteContent(guid);
501- return NotesStore::instance()->note(guid);
502-}
503-
504-void Notes::componentComplete()
505-{
506- foreach (Note *note, NotesStore::instance()->notes()) {
507- if (m_filterNotebookGuid.isEmpty() || note->notebookGuid() == m_filterNotebookGuid) {
508- m_list.append(note->guid());
509- }
510- }
511- beginInsertRows(QModelIndex(), 0, m_list.count() - 1);
512- endInsertRows();
513- refresh();
514-}
515-
516-void Notes::refresh()
517-{
518- NotesStore::instance()->refreshNotes(m_filterNotebookGuid);
519-}
520-
521-void Notes::noteAdded(const QString &guid)
522-{
523- beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
524- m_list.append(guid);
525- endInsertRows();
526-}
527-
528-void Notes::noteChanged(const QString &guid)
529-{
530- int row = m_list.indexOf(guid);
531- if (row >= 0) {
532- emit dataChanged(index(row), index(row));
533- }
534-}
535-
536-void Notes::noteRemoved(const QString &guid)
537-{
538- int index = m_list.indexOf(guid);
539- if (index >= 0) {
540- beginRemoveRows(QModelIndex(), index, index);
541- m_list.removeAt(index);
542- endRemoveRows();
543- }
544+ invalidateFilter();
545+ }
546+}
547+
548+bool Notes::onlyReminders() const
549+{
550+ return m_onlyReminders;
551+}
552+
553+void Notes::setOnlyReminders(bool onlyReminders)
554+{
555+ if (m_onlyReminders != onlyReminders) {
556+ m_onlyReminders = onlyReminders;
557+ emit onlyRemindersChanged();
558+ invalidateFilter();
559+ }
560+}
561+
562+bool Notes::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
563+{
564+ QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
565+ if (!m_filterNotebookGuid.isEmpty()) {
566+ if (sourceModel()->data(sourceIndex, NotesStore::RoleNotebookGuid).toString() != m_filterNotebookGuid) {
567+ return false;
568+ }
569+ }
570+ if (m_onlyReminders) {
571+ if (!sourceModel()->data(sourceIndex, NotesStore::RoleReminder).toBool()) {
572+ return false;
573+ }
574+ }
575+ return true;
576 }
577
578=== modified file 'src/plugin/Evernote/notes.h'
579--- src/plugin/Evernote/notes.h 2013-11-25 00:49:48 +0000
580+++ src/plugin/Evernote/notes.h 2013-12-12 21:36:37 +0000
581@@ -3,46 +3,33 @@
582
583 #include "notesstore.h"
584
585-#include <QAbstractListModel>
586-#include <QQmlParserStatus>
587+#include <QSortFilterProxyModel>
588
589-class Notes : public QAbstractListModel, public QQmlParserStatus
590+class Notes : public QSortFilterProxyModel
591 {
592 Q_OBJECT
593 Q_PROPERTY(QString filterNotebookGuid READ filterNotebookGuid WRITE setFilterNotebookGuid NOTIFY filterNotebookGuidChanged)
594+ Q_PROPERTY(bool onlyReminders READ onlyReminders WRITE setOnlyReminders NOTIFY onlyRemindersChanged)
595+
596 public:
597- enum Roles {
598- RoleGuid,
599- RoleTitle
600- };
601 explicit Notes(QObject *parent = 0);
602
603- QVariant data(const QModelIndex &index, int role) const;
604- int rowCount(const QModelIndex &parent) const;
605- QHash<int, QByteArray> roleNames() const;
606-
607 QString filterNotebookGuid() const;
608 void setFilterNotebookGuid(const QString &notebookGuid);
609
610- Q_INVOKABLE Note* note(const QString &guid);
611-
612- void classBegin() {}
613- void componentComplete();
614-
615-public slots:
616- void refresh();
617-
618-private slots:
619- void noteAdded(const QString &guid);
620- void noteChanged(const QString &guid);
621- void noteRemoved(const QString &guid);
622+ bool onlyReminders() const;
623+ void setOnlyReminders(bool onlyReminders);
624+
625+protected:
626+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
627
628 signals:
629 void filterNotebookGuidChanged();
630+ void onlyRemindersChanged();
631
632 private:
633- QList<QString> m_list;
634 QString m_filterNotebookGuid;
635+ bool m_onlyReminders;
636
637 };
638
639
640=== modified file 'src/plugin/Evernote/notesstore.cpp'
641--- src/plugin/Evernote/notesstore.cpp 2013-12-12 21:36:37 +0000
642+++ src/plugin/Evernote/notesstore.cpp 2013-12-12 21:36:37 +0000
643@@ -37,7 +37,7 @@
644 NotesStore* NotesStore::s_instance = 0;
645
646 NotesStore::NotesStore(QObject *parent) :
647- QObject(parent)
648+ QAbstractListModel(parent)
649 {
650 connect(EvernoteConnection::instance(), &EvernoteConnection::tokenChanged, this, &NotesStore::refreshNotebooks);
651 connect(EvernoteConnection::instance(), SIGNAL(tokenChanged()), this, SLOT(refreshNotes()));
652@@ -57,28 +57,71 @@
653 return s_instance;
654 }
655
656+int NotesStore::rowCount(const QModelIndex &parent) const
657+{
658+ return m_notes.count();
659+}
660+
661+QVariant NotesStore::data(const QModelIndex &index, int role) const
662+{
663+ switch (role) {
664+ case RoleGuid:
665+ return m_notes.at(index.row())->guid();
666+ case RoleNotebookGuid:
667+ return m_notes.at(index.row())->notebookGuid();
668+ case RoleCreated:
669+ return m_notes.at(index.row())->created();
670+ case RoleTitle:
671+ return m_notes.at(index.row())->title();
672+ case RoleReminder:
673+ return m_notes.at(index.row())->reminder();
674+ case RoleReminderTime:
675+ return m_notes.at(index.row())->reminderTime();
676+ case RoleReminderDone:
677+ return m_notes.at(index.row())->reminderDone();
678+ case RoleReminderDoneTime:
679+ return m_notes.at(index.row())->reminderDoneTime();
680+ }
681+ return QVariant();
682+}
683+
684+QHash<int, QByteArray> NotesStore::roleNames() const
685+{
686+ QHash<int, QByteArray> roles;
687+ roles.insert(RoleGuid, "guid");
688+ roles.insert(RoleNotebookGuid, "notebookGuid");
689+ roles.insert(RoleCreated, "created");
690+ roles.insert(RoleTitle, "title");
691+ roles.insert(RoleReminder, "reminder");
692+ roles.insert(RoleReminderTime, "reminderTime");
693+ roles.insert(RoleReminderDone, "reminderDone");
694+ roles.insert(RoleReminderDoneTime, "reminderDoneTime");
695+ return roles;
696+}
697+
698 NotesStore::~NotesStore()
699 {
700 }
701
702 QList<Note*> NotesStore::notes() const
703 {
704- return m_notes.values();
705+ return m_notes;
706 }
707
708 Note *NotesStore::note(const QString &guid)
709 {
710- return m_notes.value(guid);
711+ refreshNoteContent(guid);
712+ return m_notesHash.value(guid);
713 }
714
715 QList<Notebook *> NotesStore::notebooks() const
716 {
717- return m_notebooks.values();
718+ return m_notebooks;
719 }
720
721 Notebook *NotesStore::notebook(const QString &guid)
722 {
723- return m_notebooks.value(guid);
724+ return m_notebooksHash.value(guid);
725 }
726
727 void NotesStore::refreshNotes(const QString &filterNotebookGuid)
728@@ -97,17 +140,33 @@
729
730 for (int i = 0; i < results.notes.size(); ++i) {
731 evernote::edam::NoteMetadata result = results.notes.at(i);
732- Note *note = m_notes.value(QString::fromStdString(result.guid));
733- if (note) {
734- note->setTitle(QString::fromStdString(result.title));
735- note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
736+ Note *note = m_notesHash.value(QString::fromStdString(result.guid));
737+ bool newNote = note == 0;
738+ if (newNote) {
739+ QString guid = QString::fromStdString(result.guid);
740+ QDateTime created = QDateTime::fromMSecsSinceEpoch(result.created);
741+ note = new Note(guid, created, this);
742+ }
743+
744+ note->setTitle(QString::fromStdString(result.title));
745+ note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
746+ note->setReminderOrder(result.attributes.reminderOrder);
747+ QDateTime reminderDoneTime;
748+ if (result.attributes.reminderDoneTime > 0) {
749+ reminderDoneTime = QDateTime::fromMSecsSinceEpoch(result.attributes.reminderDoneTime);
750+ }
751+ note->setReminderDoneTime(reminderDoneTime);
752+
753+ if (newNote) {
754+ beginInsertRows(QModelIndex(), m_notes.count(), m_notes.count());
755+ m_notesHash.insert(note->guid(), note);
756+ m_notes.append(note);
757+ endInsertRows();
758+ emit noteAdded(note->guid());
759+ } else {
760+ QModelIndex noteIndex = index(m_notes.indexOf(note));
761+ emit dataChanged(noteIndex, noteIndex);
762 emit noteChanged(note->guid());
763- } else {
764- note = new Note(QString::fromStdString(result.guid), this);
765- note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
766- note->setTitle(QString::fromStdString(result.title));
767- m_notes.insert(note->guid(), note);
768- emit noteAdded(note->guid());
769 }
770 }
771 }
772@@ -126,11 +185,20 @@
773 return;
774 }
775
776- Note *note = m_notes.value(QString::fromStdString(result.guid));
777+ Note *note = m_notesHash.value(QString::fromStdString(result.guid));
778 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
779 note->setTitle(QString::fromStdString(result.title));
780 note->setContent(QString::fromStdString(result.content));
781+ note->setReminderOrder(result.attributes.reminderOrder);
782+ QDateTime reminderDoneTime;
783+ if (result.attributes.reminderDoneTime > 0) {
784+ reminderDoneTime = QDateTime::fromMSecsSinceEpoch(result.attributes.reminderDoneTime);
785+ }
786+ note->setReminderDoneTime(reminderDoneTime);
787 emit noteChanged(note->guid());
788+
789+ QModelIndex noteIndex = index(m_notes.indexOf(note));
790+ emit dataChanged(noteIndex, noteIndex);
791 }
792
793 void NotesStore::refreshNotebooks()
794@@ -149,17 +217,19 @@
795
796 for (int i = 0; i < results.size(); ++i) {
797 evernote::edam::Notebook result = results.at(i);
798- Notebook *notebook = m_notebooks.value(QString::fromStdString(result.guid));
799- if (notebook) {
800- qDebug() << "got notebook update";
801- notebook->setName(QString::fromStdString(result.name));
802- emit notebookChanged(notebook->guid());
803- } else {
804+ Notebook *notebook = m_notebooksHash.value(QString::fromStdString(result.guid));
805+ bool newNoteNotebook = notebook == 0;
806+ if (newNoteNotebook) {
807 notebook = new Notebook(QString::fromStdString(result.guid), this);
808- notebook->setName(QString::fromStdString(result.name));
809- m_notebooks.insert(notebook->guid(), notebook);
810+ }
811+ notebook->setName(QString::fromStdString(result.name));
812+
813+ if (newNoteNotebook) {
814+ m_notebooksHash.insert(notebook->guid(), notebook);
815+ m_notebooks.append(notebook);
816 emit notebookAdded(notebook->guid());
817- qDebug() << "got new notebook" << notebook->guid();
818+ } else {
819+ emit notebookChanged(notebook->guid());
820 }
821 }
822 }
823@@ -178,18 +248,24 @@
824 return;
825 }
826
827- Note *note = new Note(QString::fromStdString(result.guid));
828+ QString guid = QString::fromStdString(result.guid);
829+ QDateTime created = QDateTime::fromMSecsSinceEpoch(result.created);
830+ Note *note = new Note(guid, created, this);
831 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
832 note->setTitle(QString::fromStdString(result.title));
833 note->setContent(QString::fromStdString(result.content));
834
835- m_notes.insert(note->guid(), note);
836- noteAdded(note->guid());
837+ beginInsertRows(QModelIndex(), m_notes.count(), m_notes.count());
838+ m_notesHash.insert(note->guid(), note);
839+ m_notes.append(note);
840+ endInsertRows();
841+
842+ emit noteAdded(note->guid());
843 }
844
845 void NotesStore::saveNote(const QString &guid)
846 {
847- Note *note = m_notes.value(guid);
848+ Note *note = m_notesHash.value(guid);
849
850 QString enml = Html2EnmlConverter::html2enml(note->content());
851 note->setContent(enml);
852@@ -206,12 +282,15 @@
853 return;
854 }
855
856- Note *note = m_notes.value(QString::fromStdString(result.guid));
857+ Note *note = m_notesHash.value(QString::fromStdString(result.guid));
858 if (note) {
859 note->setTitle(QString::fromStdString(result.title));
860 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
861
862 emit noteChanged(note->guid());
863+
864+ QModelIndex noteIndex = index(m_notes.indexOf(note));
865+ emit dataChanged(noteIndex, noteIndex);
866 }
867 }
868
869@@ -229,5 +308,11 @@
870 return;
871 }
872 emit noteRemoved(guid);
873- m_notes.take(guid)->deleteLater();
874+
875+ Note *note = m_notesHash.value(guid);
876+ int noteIndex = m_notes.indexOf(note);
877+ beginRemoveRows(QModelIndex(), noteIndex, noteIndex);
878+ m_notes.takeAt(noteIndex);
879+ m_notesHash.take(guid)->deleteLater();
880+ endRemoveRows();
881 }
882
883=== modified file 'src/plugin/Evernote/notesstore.h'
884--- src/plugin/Evernote/notesstore.h 2013-12-12 21:36:37 +0000
885+++ src/plugin/Evernote/notesstore.h 2013-12-12 21:36:37 +0000
886@@ -15,7 +15,7 @@
887 #include <NoteStore_constants.h>
888 #include <Errors_types.h>
889
890-#include <QObject>
891+#include <QAbstractListModel>
892 #include <QHash>
893
894 class Notebook;
895@@ -23,21 +23,36 @@
896
897 using namespace apache::thrift::transport;
898
899-class NotesStore : public QObject
900+class NotesStore : public QAbstractListModel
901 {
902 Q_OBJECT
903
904 public:
905- Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &content);
906+ enum Roles {
907+ RoleGuid,
908+ RoleNotebookGuid,
909+ RoleCreated,
910+ RoleTitle,
911+ RoleReminder,
912+ RoleReminderTime,
913+ RoleReminderDone,
914+ RoleReminderDoneTime
915+ };
916
917+ ~NotesStore();
918 static NotesStore *instance();
919
920- ~NotesStore();
921+ // reimplemented from QAbstractListModel
922+ int rowCount(const QModelIndex &parent) const;
923+ QVariant data(const QModelIndex &index, int role) const;
924+ QHash<int, QByteArray> roleNames() const;
925
926 QList<Note*> notes() const;
927- Note* note(const QString &guid);
928- void saveNote(const QString &guid);
929- void deleteNote(const QString &guid);
930+
931+ Q_INVOKABLE Note* note(const QString &guid);
932+ Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &content);
933+ Q_INVOKABLE void saveNote(const QString &guid);
934+ Q_INVOKABLE void deleteNote(const QString &guid);
935
936 QList<Notebook*> notebooks() const;
937 Notebook* notebook(const QString &guid);
938@@ -69,9 +84,12 @@
939 explicit NotesStore(QObject *parent = 0);
940 static NotesStore *s_instance;
941
942- QHash<QString, Notebook*> m_notebooks;
943- QHash<QString, Note*> m_notes;
944+ QList<Note*> m_notes;
945+ QList<Notebook*> m_notebooks;
946
947+ // Keep hashes for faster lookups as we always identify notes via guid
948+ QHash<QString, Note*> m_notesHash;
949+ QHash<QString, Notebook*> m_notebooksHash;
950 };
951
952 #endif // NOTESSTORE_H

Subscribers

People subscribed via source and target branches