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

Proposed by Michael Zanetti
Status: Merged
Approved by: Michael Zanetti
Approved revision: 24
Merged at revision: 20
Proposed branch: lp:~mzanetti/reminders-app/find-notes
Merge into: lp:reminders-app
Prerequisite: lp:~mzanetti/reminders-app/create-notebook
Diff against target: 451 lines (+210/-9)
13 files modified
src/app/app.pro (+3/-1)
src/app/qml/components/ToolbarSpacer.qml (+45/-0)
src/app/qml/ui/NotebooksPage.qml (+0/-1)
src/app/qml/ui/NotesPage.qml (+13/-1)
src/app/qml/ui/SearchNotesPage.qml (+73/-0)
src/plugin/Evernote/jobs/fetchnotesjob.cpp (+6/-2)
src/plugin/Evernote/jobs/fetchnotesjob.h (+2/-1)
src/plugin/Evernote/note.cpp (+16/-1)
src/plugin/Evernote/note.h (+6/-0)
src/plugin/Evernote/notes.cpp (+20/-0)
src/plugin/Evernote/notes.h (+6/-1)
src/plugin/Evernote/notesstore.cpp (+17/-0)
src/plugin/Evernote/notesstore.h (+3/-1)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/find-notes
Reviewer Review Type Date Requested Status
Jordan Keyes Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+198852@code.launchpad.net

Commit message

added means to search for notes by content to plugin API

Description of the change

Added NotesStore.findNotes(searchstring) for searching notes (content search). The search follows the grammar defined in here:

http://dev.evernote.com/doc/articles/search_grammar.php

This means, that if you want to search partial words, you need to type "foo*" in order to find the word "foobar". Just "foo" would not match it. I think we want to automatically append the * in the UI code, depending on how we want to expose the capabilities of the search grammar.

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: Approve (continuous-integration)
23. By Michael Zanetti

move searching to a new page as per design

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
24. By Michael Zanetti

add missing file

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
Jordan Keyes (jkeyes0) wrote :

On most of your newer branches, I'm getting an error on my system (Ubuntu 13.10 64-bit) complaining about the "iconName" in the ToolbarItems. Going back through the prerequisite branches, it seems that this one is the first to have the commits with iconName. Are there additional components that I need to install to make this work? I saw something mentioned about a missing "ubuntu.components.extras.browser" in a later branch of code. Are those related?

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

> On most of your newer branches, I'm getting an error on my system (Ubuntu
> 13.10 64-bit) complaining about the "iconName" in the ToolbarItems. Going back
> through the prerequisite branches, it seems that this one is the first to have
> the commits with iconName. Are there additional components that I need to
> install to make this work? I saw something mentioned about a missing
> "ubuntu.components.extras.browser" in a later branch of code. Are those
> related?

Hmm... There's nothing additional to be installed, but you gotta have a recent version of the ubuntu-ui-toolkit. Which version do you have?

I've this one: 0.1.46+14.04.20131129-0ubuntu1

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
Michael Zanetti (mzanetti) wrote :

> On most of your newer branches, I'm getting an error on my system (Ubuntu
> 13.10 64-bit) complaining about the "iconName" in the ToolbarItems. Going back
> through the prerequisite branches, it seems that this one is the first to have
> the commits with iconName. Are there additional components that I need to
> install to make this work? I saw something mentioned about a missing
> "ubuntu.components.extras.browser" in a later branch of code. Are those
> related?

Ok. Seems saucy doesn't ship the lastest ui toolkit packages indeed. Here's a ppa with the latest versions:

https://launchpad.net/~ubuntu-sdk-team/+archive/ppa/+packages?batch=75&memo=75&start=75

We need a decision from David or Alan on whether we need to keep compatibility with saucy or not.

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

I think we should strive to keep compatibility with 13.10, but in any case I think this particular issue can easily be solved by making sure the SDK PPA is installed (and that it is up-to-date)

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

After adding the ubuntu-sdk-team PPA to my system, this MP looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/app.pro'
2--- src/app/app.pro 2013-11-22 21:35:34 +0000
3+++ src/app/app.pro 2013-12-14 00:04:27 +0000
4@@ -10,7 +10,9 @@
5 qml/ui/RemindersPage.qml \
6 qml/ui/NotesPage.qml \
7 qml/ui/AccountSelectorPage.qml \
8- qml/ui/NotePage.qml
9+ qml/ui/NotePage.qml \
10+ qml/ui/SearchNotesPage.qml \
11+ qml/components/ToolbarSpacer.qml \
12
13 # Copy qml to build dir for running with qtcreator
14 qmlfolder.source = src/app/qml
15
16=== added directory 'src/app/qml/components'
17=== added file 'src/app/qml/components/ToolbarSpacer.qml'
18--- src/app/qml/components/ToolbarSpacer.qml 1970-01-01 00:00:00 +0000
19+++ src/app/qml/components/ToolbarSpacer.qml 2013-12-14 00:04:27 +0000
20@@ -0,0 +1,45 @@
21+/*
22+ * Copyright: 2013 Canonical, Ltd
23+ *
24+ * This file is part of reminders-app
25+ *
26+ * reminders-app is free software: you can redistribute it and/or modify
27+ * it under the terms of the GNU General Public License as published by
28+ * the Free Software Foundation; version 3.
29+ *
30+ * reminders-app is distributed in the hope that it will be useful,
31+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33+ * GNU General Public License for more details.
34+ *
35+ * You should have received a copy of the GNU General Public License
36+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
37+ */
38+
39+import QtQuick 2.0
40+import Ubuntu.Components 0.1
41+import Ubuntu.Components.Popups 0.1
42+
43+Item {
44+ id: spacerItem
45+ objectName: "__ToolBarItems.SpacerItem"
46+ height: parent.height
47+ width: {
48+ var othersWidth = 0;
49+
50+ // Hack: the autogenerated back button
51+ if (pageStack != null && pageStack.depth > 1) {
52+ othersWidth = units.gu(6)
53+ }
54+
55+ for (var i = 0; i < parent.children.length; ++i) {
56+ var otherItem = parent.children[i];
57+ if (otherItem.objectName !== "__ToolBarItems.SpacerItem") {
58+ if (otherItem.visible) {
59+ othersWidth += otherItem.width + parent.spacing;
60+ }
61+ }
62+ }
63+ return parent.parent.width - othersWidth - units.gu(4);
64+ }
65+}
66
67=== modified file 'src/app/qml/ui/NotebooksPage.qml'
68--- src/app/qml/ui/NotebooksPage.qml 2013-12-14 00:04:26 +0000
69+++ src/app/qml/ui/NotebooksPage.qml 2013-12-14 00:04:27 +0000
70@@ -33,7 +33,6 @@
71 tools: ToolbarItems {
72 ToolbarButton {
73 text: "add notebook"
74- enabled: notes.filterNotebookGuid.length > 0
75 onTriggered: {
76 NotesStore.createNotebook("new notebook");
77 }
78
79=== modified file 'src/app/qml/ui/NotesPage.qml'
80--- src/app/qml/ui/NotesPage.qml 2013-12-14 00:04:26 +0000
81+++ src/app/qml/ui/NotesPage.qml 2013-12-14 00:04:27 +0000
82@@ -20,6 +20,7 @@
83 import Ubuntu.Components 0.1
84 import Ubuntu.Components.ListItems 0.1
85 import Evernote 0.1
86+import "../components"
87
88 Page {
89 id: notesPage
90@@ -35,6 +36,16 @@
91 // Just for testing
92 tools: ToolbarItems {
93 ToolbarButton {
94+ text: "search"
95+ iconName: "search"
96+ onTriggered: {
97+ pagestack.push(Qt.resolvedUrl("SearchNotesPage.qml"))
98+ }
99+ }
100+
101+ ToolbarSpacer { }
102+
103+ ToolbarButton {
104 text: "add note"
105 enabled: notes.filterNotebookGuid.length > 0
106 onTriggered: {
107@@ -51,7 +62,8 @@
108 }
109
110 ListView {
111- anchors.fill: parent
112+ anchors { left: parent.left; right: parent.right }
113+ height: parent.height - y
114 model: notes
115
116 delegate: Standard {
117
118=== added file 'src/app/qml/ui/SearchNotesPage.qml'
119--- src/app/qml/ui/SearchNotesPage.qml 1970-01-01 00:00:00 +0000
120+++ src/app/qml/ui/SearchNotesPage.qml 2013-12-14 00:04:27 +0000
121@@ -0,0 +1,73 @@
122+/*
123+ * Copyright: 2013 Canonical, Ltd
124+ *
125+ * This file is part of reminders-app
126+ *
127+ * reminders-app is free software: you can redistribute it and/or modify
128+ * it under the terms of the GNU General Public License as published by
129+ * the Free Software Foundation; version 3.
130+ *
131+ * reminders-app is distributed in the hope that it will be useful,
132+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
133+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134+ * GNU General Public License for more details.
135+ *
136+ * You should have received a copy of the GNU General Public License
137+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
138+ */
139+
140+import QtQuick 2.0
141+import Ubuntu.Components 0.1
142+import Ubuntu.Components.ListItems 0.1
143+import Evernote 0.1
144+import "../components"
145+
146+Page {
147+ Column {
148+ anchors { fill: parent; topMargin: units.gu(2); bottomMargin: units.gu(2) }
149+ spacing: units.gu(2)
150+
151+ Row {
152+ anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
153+ spacing: units.gu(1)
154+
155+ TextField {
156+ id: searchField
157+ width: parent.width - searchButton.width - parent.spacing
158+ anchors.verticalCenter: parent.verticalCenter
159+
160+ primaryItem: Icon {
161+ height: searchField.height - units.gu(1)
162+ width: height
163+ name: "search"
164+ }
165+
166+ onAccepted: {
167+ NotesStore.findNotes(searchField.text + "*")
168+ }
169+ }
170+ Button {
171+ id: searchButton
172+ height: searchField.height
173+ text: "search"
174+ onClicked: {
175+ NotesStore.findNotes(searchField.text + "*")
176+ }
177+ }
178+ }
179+
180+ ListView {
181+ anchors { left: parent.left; right: parent.right }
182+ height: parent.height - y
183+
184+ model: Notes {
185+ onlySearchResults: true
186+ }
187+
188+ delegate: Standard {
189+ text: title
190+ }
191+ }
192+
193+ }
194+}
195
196=== modified file 'src/plugin/Evernote/jobs/fetchnotesjob.cpp'
197--- src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-12-14 00:04:26 +0000
198+++ src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-12-14 00:04:27 +0000
199@@ -27,9 +27,10 @@
200
201 #include <QDebug>
202
203-FetchNotesJob::FetchNotesJob( const QString &filterNotebookGuid, QObject *parent) :
204+FetchNotesJob::FetchNotesJob(const QString &filterNotebookGuid, const QString &searchWords, QObject *parent) :
205 NotesStoreJob(parent),
206- m_filterNotebookGuid(filterNotebookGuid)
207+ m_filterNotebookGuid(filterNotebookGuid),
208+ m_searchWords(searchWords)
209 {
210 }
211
212@@ -45,6 +46,9 @@
213 filter.notebookGuid = m_filterNotebookGuid.toStdString();
214 filter.__isset.notebookGuid = !m_filterNotebookGuid.isEmpty();
215
216+ filter.words = m_searchWords.toStdString();
217+ filter.__isset.words = !m_searchWords.isEmpty();
218+
219 // Prepare ResultSpec
220 evernote::edam::NotesMetadataResultSpec resultSpec;
221
222
223=== modified file 'src/plugin/Evernote/jobs/fetchnotesjob.h'
224--- src/plugin/Evernote/jobs/fetchnotesjob.h 2013-12-14 00:04:26 +0000
225+++ src/plugin/Evernote/jobs/fetchnotesjob.h 2013-12-14 00:04:27 +0000
226@@ -7,7 +7,7 @@
227 {
228 Q_OBJECT
229 public:
230- explicit FetchNotesJob(const QString &filterNotebookGuid, QObject *parent = 0);
231+ explicit FetchNotesJob(const QString &filterNotebookGuid = QString(), const QString &searchWords = QString(), QObject *parent = 0);
232
233 signals:
234 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::NotesMetadataList &results);
235@@ -18,6 +18,7 @@
236
237 private:
238 QString m_filterNotebookGuid;
239+ QString m_searchWords;
240 evernote::edam::NotesMetadataList m_results;
241 };
242
243
244=== modified file 'src/plugin/Evernote/note.cpp'
245--- src/plugin/Evernote/note.cpp 2013-12-14 00:04:26 +0000
246+++ src/plugin/Evernote/note.cpp 2013-12-14 00:04:27 +0000
247@@ -27,7 +27,8 @@
248 Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :
249 QObject(parent),
250 m_guid(guid),
251- m_created(created)
252+ m_created(created),
253+ m_isSearchResult(false)
254 {
255 }
256
257@@ -148,6 +149,19 @@
258 }
259 }
260
261+bool Note::isSearchResult() const
262+{
263+ return m_isSearchResult;
264+}
265+
266+void Note::setIsSearchResult(bool isSearchResult)
267+{
268+ if (m_isSearchResult != isSearchResult) {
269+ m_isSearchResult = isSearchResult;
270+ emit isSearchResultChanged();
271+ }
272+}
273+
274 Note *Note::clone()
275 {
276 Note *note = new Note(m_guid, m_created);
277@@ -157,6 +171,7 @@
278 note->setReminderOrder(m_reminderOrder);
279 note->setReminderTime(m_reminderTime);
280 note->setReminderDoneTime(m_reminderDoneTime);
281+ note->setIsSearchResult(m_isSearchResult);
282 return note;
283 }
284
285
286=== modified file 'src/plugin/Evernote/note.h'
287--- src/plugin/Evernote/note.h 2013-12-14 00:04:26 +0000
288+++ src/plugin/Evernote/note.h 2013-12-14 00:04:27 +0000
289@@ -19,6 +19,7 @@
290 Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)
291 Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)
292 Q_PROPERTY(QDateTime reminderDoneTime READ reminderDoneTime WRITE setReminderDoneTime NOTIFY reminderDoneChanged)
293+ Q_PROPERTY(bool isSearchResult READ isSearchResult NOTIFY isSearchResultChanged)
294 // Don't forget to update clone() if you add properties!
295
296 public:
297@@ -58,6 +59,9 @@
298 QDateTime reminderDoneTime() const;
299 void setReminderDoneTime(const QDateTime &reminderDoneTime);
300
301+ bool isSearchResult() const;
302+ void setIsSearchResult(bool isSearchResult);
303+
304 Note* clone();
305
306 public slots:
307@@ -71,6 +75,7 @@
308 void reminderChanged();
309 void reminderTimeChanged();
310 void reminderDoneChanged();
311+ void isSearchResultChanged();
312
313 private:
314 QString m_guid;
315@@ -81,6 +86,7 @@
316 qint64 m_reminderOrder;
317 QDateTime m_reminderTime;
318 QDateTime m_reminderDoneTime;
319+ bool m_isSearchResult;
320 };
321
322 #endif // NOTE_H
323
324=== modified file 'src/plugin/Evernote/notes.cpp'
325--- src/plugin/Evernote/notes.cpp 2013-12-14 00:04:26 +0000
326+++ src/plugin/Evernote/notes.cpp 2013-12-14 00:04:27 +0000
327@@ -60,6 +60,20 @@
328 }
329 }
330
331+bool Notes::onlySearchResults() const
332+{
333+ return m_onlySearchResults;
334+}
335+
336+void Notes::setOnlySearchResults(bool onlySearchResults)
337+{
338+ if (m_onlySearchResults != onlySearchResults) {
339+ m_onlySearchResults = onlySearchResults;
340+ emit onlySearchResultsChanged();
341+ invalidateFilter();
342+ }
343+}
344+
345 bool Notes::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
346 {
347 QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
348@@ -73,5 +87,11 @@
349 return false;
350 }
351 }
352+ if (m_onlySearchResults) {
353+ Note *note = NotesStore::instance()->note(sourceModel()->data(sourceIndex, NotesStore::RoleGuid).toString());
354+ if (!note->isSearchResult()) {
355+ return false;
356+ }
357+ }
358 return true;
359 }
360
361=== modified file 'src/plugin/Evernote/notes.h'
362--- src/plugin/Evernote/notes.h 2013-12-14 00:04:26 +0000
363+++ src/plugin/Evernote/notes.h 2013-12-14 00:04:27 +0000
364@@ -10,6 +10,7 @@
365 Q_OBJECT
366 Q_PROPERTY(QString filterNotebookGuid READ filterNotebookGuid WRITE setFilterNotebookGuid NOTIFY filterNotebookGuidChanged)
367 Q_PROPERTY(bool onlyReminders READ onlyReminders WRITE setOnlyReminders NOTIFY onlyRemindersChanged)
368+ Q_PROPERTY(bool onlySearchResults READ onlySearchResults WRITE setOnlySearchResults NOTIFY onlySearchResultsChanged)
369
370 public:
371 explicit Notes(QObject *parent = 0);
372@@ -20,17 +21,21 @@
373 bool onlyReminders() const;
374 void setOnlyReminders(bool onlyReminders);
375
376+ bool onlySearchResults() const;
377+ void setOnlySearchResults(bool onlySearchResults);
378+
379 protected:
380 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
381
382 signals:
383 void filterNotebookGuidChanged();
384 void onlyRemindersChanged();
385+ void onlySearchResultsChanged();
386
387 private:
388 QString m_filterNotebookGuid;
389 bool m_onlyReminders;
390-
391+ bool m_onlySearchResults;
392 };
393
394 #endif // NOTES_H
395
396=== modified file 'src/plugin/Evernote/notesstore.cpp'
397--- src/plugin/Evernote/notesstore.cpp 2013-12-14 00:04:26 +0000
398+++ src/plugin/Evernote/notesstore.cpp 2013-12-14 00:04:27 +0000
399@@ -168,6 +168,11 @@
400 note->setTitle(QString::fromStdString(result.title));
401 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
402 note->setReminderOrder(result.attributes.reminderOrder);
403+
404+ if (!results.searchedWords.empty()) {
405+ note->setIsSearchResult(true);
406+ }
407+
408 QDateTime reminderDoneTime;
409 if (result.attributes.reminderDoneTime > 0) {
410 reminderDoneTime = QDateTime::fromMSecsSinceEpoch(result.attributes.reminderDoneTime);
411@@ -318,6 +323,18 @@
412 EvernoteConnection::instance()->enqueue(job);
413 }
414
415+void NotesStore::findNotes(const QString &searchWords)
416+{
417+ foreach (Note *note, m_notes) {
418+ note->setIsSearchResult(false);
419+ }
420+ emit dataChanged(index(0), index(m_notes.count()), QVector<int>() << RoleIsSearchResult);
421+
422+ FetchNotesJob *job = new FetchNotesJob(QString(), searchWords);
423+ connect(job, &FetchNotesJob::jobDone, this, &NotesStore::fetchNotesJobDone);
424+ EvernoteConnection::instance()->enqueue(job);
425+}
426+
427 void NotesStore::deleteNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
428 {
429 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
430
431=== modified file 'src/plugin/Evernote/notesstore.h'
432--- src/plugin/Evernote/notesstore.h 2013-12-14 00:04:26 +0000
433+++ src/plugin/Evernote/notesstore.h 2013-12-14 00:04:27 +0000
434@@ -36,7 +36,8 @@
435 RoleReminder,
436 RoleReminderTime,
437 RoleReminderDone,
438- RoleReminderDoneTime
439+ RoleReminderDoneTime,
440+ RoleIsSearchResult
441 };
442
443 ~NotesStore();
444@@ -53,6 +54,7 @@
445 Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &content);
446 Q_INVOKABLE void saveNote(const QString &guid);
447 Q_INVOKABLE void deleteNote(const QString &guid);
448+ Q_INVOKABLE void findNotes(const QString &searchWords);
449
450 QList<Notebook*> notebooks() const;
451 Notebook* notebook(const QString &guid);

Subscribers

People subscribed via source and target branches