Merge lp:~mzanetti/reminders-app/enable-deleting-notebooks-and-tags into lp:reminders-app

Proposed by Michael Zanetti
Status: Merged
Approved by: Riccardo Padovani
Approved revision: 453
Merged at revision: 451
Proposed branch: lp:~mzanetti/reminders-app/enable-deleting-notebooks-and-tags
Merge into: lp:reminders-app
Diff against target: 761 lines (+303/-38)
16 files modified
src/app/qml/components/NotebooksDelegate.qml (+1/-0)
src/app/qml/components/TagsDelegate.qml (+1/-0)
src/app/qml/reminders.qml (+2/-1)
src/libqtevernote/CMakeLists.txt (+1/-0)
src/libqtevernote/jobs/expungetagjob.cpp (+52/-0)
src/libqtevernote/jobs/expungetagjob.h (+46/-0)
src/libqtevernote/notebook.cpp (+17/-0)
src/libqtevernote/notebook.h (+5/-0)
src/libqtevernote/notebooks.cpp (+11/-0)
src/libqtevernote/notebooks.h (+3/-1)
src/libqtevernote/notesstore.cpp (+127/-35)
src/libqtevernote/notesstore.h (+1/-0)
src/libqtevernote/tag.cpp (+17/-0)
src/libqtevernote/tag.h (+5/-0)
src/libqtevernote/tags.cpp (+11/-0)
src/libqtevernote/tags.h (+3/-1)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/enable-deleting-notebooks-and-tags
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Riccardo Padovani Approve
Review via email: mp+261774@code.launchpad.net

Commit message

Enable deleting notebooks and tags on Evernote

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)
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

There are a lot of warnings due your changes: http://paste.ubuntu.com/11698283/

Also, there is a strange warning in qml when you delete a tag which has notes attached: it says

`Sync: Save tag job finished, but tag can't be found any more`

This is really a minor issue, but as console output doesn't make any sense

review: Needs Fixing
452. By Michael Zanetti

fix networkingstatus check

453. By Michael Zanetti

fix warnings, drop unneeded save call before deleting

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

> There are a lot of warnings due your changes:
> http://paste.ubuntu.com/11698283/
>
> Also, there is a strange warning in qml when you delete a tag which has notes
> attached: it says
>
> `Sync: Save tag job finished, but tag can't be found any more`
>
> This is really a minor issue, but as console output doesn't make any sense

All fixed. thanks a lot

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Tested deeply, looks all good to me now, thanks!

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/components/NotebooksDelegate.qml'
2--- src/app/qml/components/NotebooksDelegate.qml 2015-03-15 20:00:21 +0000
3+++ src/app/qml/components/NotebooksDelegate.qml 2015-06-11 21:38:48 +0000
4@@ -89,6 +89,7 @@
5 color: root.notebookColor
6 fontSize: "large"
7 Layout.fillWidth: true
8+ font.strikeout: model.deleted
9 }
10
11 Label {
12
13=== modified file 'src/app/qml/components/TagsDelegate.qml'
14--- src/app/qml/components/TagsDelegate.qml 2015-03-15 20:00:21 +0000
15+++ src/app/qml/components/TagsDelegate.qml 2015-06-11 21:38:48 +0000
16@@ -80,6 +80,7 @@
17 text: model.name
18 fontSize: "large"
19 Layout.fillWidth: true
20+ font.strikeout: model.deleted
21 }
22 }
23
24
25=== modified file 'src/app/qml/reminders.qml'
26--- src/app/qml/reminders.qml 2015-06-01 09:56:30 +0000
27+++ src/app/qml/reminders.qml 2015-06-11 21:38:48 +0000
28@@ -383,7 +383,8 @@
29 onAuthenticated: {
30 EvernoteConnection.token = reply.AccessToken;
31 print("token is:", EvernoteConnection.token)
32- if (NetworkingStatus.online) {
33+ print("NetworkingStatus.online:", NetworkingStatus.Online)
34+ if (NetworkingStatus.Online) {
35 EvernoteConnection.connectToEvernote();
36 }
37 }
38
39=== modified file 'src/libqtevernote/CMakeLists.txt'
40--- src/libqtevernote/CMakeLists.txt 2015-03-06 00:42:42 +0000
41+++ src/libqtevernote/CMakeLists.txt 2015-06-11 21:38:48 +0000
42@@ -32,6 +32,7 @@
43 jobs/fetchtagsjob.cpp
44 jobs/createtagjob.cpp
45 jobs/savetagjob.cpp
46+ jobs/expungetagjob.cpp
47 resourceimageprovider.cpp
48 utils/enmldocument.cpp
49 utils/organizeradapter.cpp
50
51=== added file 'src/libqtevernote/jobs/expungetagjob.cpp'
52--- src/libqtevernote/jobs/expungetagjob.cpp 1970-01-01 00:00:00 +0000
53+++ src/libqtevernote/jobs/expungetagjob.cpp 2015-06-11 21:38:48 +0000
54@@ -0,0 +1,52 @@
55+/*
56+ * Copyright: 2015 Canonical, Ltd
57+ *
58+ * This file is part of reminders
59+ *
60+ * reminders is free software: you can redistribute it and/or modify
61+ * it under the terms of the GNU General Public License as published by
62+ * the Free Software Foundation; version 3.
63+ *
64+ * reminders is distributed in the hope that it will be useful,
65+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
66+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67+ * GNU General Public License for more details.
68+ *
69+ * You should have received a copy of the GNU General Public License
70+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
71+ *
72+ * Authors: Michael Zanetti <michael.zanetti@canonical.com>
73+ */
74+
75+#include "expungetagjob.h"
76+
77+ExpungeTagJob::ExpungeTagJob(const QString &guid, QObject *parent) :
78+ NotesStoreJob(parent),
79+ m_guid(guid)
80+{
81+}
82+
83+bool ExpungeTagJob::operator==(const EvernoteJob *other) const
84+{
85+ const ExpungeTagJob *otherJob = qobject_cast<const ExpungeTagJob*>(other);
86+ if (!otherJob) {
87+ return false;
88+ }
89+ return this->m_guid == otherJob->m_guid;
90+}
91+
92+void ExpungeTagJob::attachToDuplicate(const EvernoteJob *other)
93+{
94+ const ExpungeTagJob *otherJob = static_cast<const ExpungeTagJob*>(other);
95+ connect(otherJob, &ExpungeTagJob::jobDone, this, &ExpungeTagJob::jobDone);
96+}
97+
98+void ExpungeTagJob::startJob()
99+{
100+ client()->expungeTag(token().toStdString(), m_guid.toStdString());
101+}
102+
103+void ExpungeTagJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
104+{
105+ emit jobDone(errorCode, errorMessage, m_guid);
106+}
107
108=== added file 'src/libqtevernote/jobs/expungetagjob.h'
109--- src/libqtevernote/jobs/expungetagjob.h 1970-01-01 00:00:00 +0000
110+++ src/libqtevernote/jobs/expungetagjob.h 2015-06-11 21:38:48 +0000
111@@ -0,0 +1,46 @@
112+/*
113+ * Copyright: 2015 Canonical, Ltd
114+ *
115+ * This file is part of reminders
116+ *
117+ * reminders is free software: you can redistribute it and/or modify
118+ * it under the terms of the GNU General Public License as published by
119+ * the Free Software Foundation; version 3.
120+ *
121+ * reminders is distributed in the hope that it will be useful,
122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124+ * GNU General Public License for more details.
125+ *
126+ * You should have received a copy of the GNU General Public License
127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
128+ *
129+ * Authors: Michael Zanetti <michael.zanetti@canonical.com>
130+ */
131+
132+#ifndef EXPUNGETAGJOB_H
133+#define EXPUNGETAGJOB_H
134+
135+#include "notesstorejob.h"
136+
137+class ExpungeTagJob : public NotesStoreJob
138+{
139+ Q_OBJECT
140+public:
141+ explicit ExpungeTagJob(const QString &guid, QObject *parent = 0);
142+
143+ virtual bool operator==(const EvernoteJob *other) const override;
144+ virtual void attachToDuplicate(const EvernoteJob *other) override;
145+
146+signals:
147+ void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
148+
149+private slots:
150+ void startJob();
151+ void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
152+
153+private:
154+ QString m_guid;
155+};
156+
157+#endif // EXPUNGETAGJOB_H
158
159=== modified file 'src/libqtevernote/notebook.cpp'
160--- src/libqtevernote/notebook.cpp 2015-03-06 00:47:45 +0000
161+++ src/libqtevernote/notebook.cpp 2015-06-11 21:38:48 +0000
162@@ -33,6 +33,7 @@
163 m_guid(guid),
164 m_published(false),
165 m_isDefaultNotebook(false),
166+ m_deleted(false),
167 m_loading(false),
168 m_syncError(false)
169 {
170@@ -44,6 +45,7 @@
171 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();
172 m_isDefaultNotebook = infoFile.value("isDefaultNotebook", false).toBool();
173 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;
174+ m_deleted = infoFile.value("deleted", false).toBool();
175
176 foreach (Note *note, NotesStore::instance()->notes()) {
177 if (note->notebookGuid() == m_guid) {
178@@ -155,6 +157,7 @@
179 notebook->setName(m_name);
180 notebook->setLastUpdated(m_lastUpdated);
181 notebook->setPublished(m_published);
182+ notebook->setDeleted(m_deleted);
183
184 return notebook;
185 }
186@@ -232,6 +235,7 @@
187 infoFile.value("lastUpdated", m_lastUpdated);
188 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);
189 infoFile.setValue("isDefaultNotebook", m_isDefaultNotebook);
190+ infoFile.setValue("deleted", m_deleted);
191 }
192
193 void Notebook::deleteInfoFile()
194@@ -257,6 +261,11 @@
195 return m_syncError;
196 }
197
198+bool Notebook::deleted() const
199+{
200+ return m_deleted;
201+}
202+
203 qint32 Notebook::updateSequenceNumber() const
204 {
205 return m_updateSequenceNumber;
206@@ -287,6 +296,14 @@
207 }
208 }
209
210+void Notebook::setDeleted(bool deleted)
211+{
212+ if (m_deleted != deleted) {
213+ m_deleted = deleted;
214+ emit deletedChanged();
215+ }
216+}
217+
218 void Notebook::setLoading(bool loading)
219 {
220 if (m_loading != loading) {
221
222=== modified file 'src/libqtevernote/notebook.h'
223--- src/libqtevernote/notebook.h 2015-03-04 20:30:55 +0000
224+++ src/libqtevernote/notebook.h 2015-06-11 21:38:48 +0000
225@@ -37,6 +37,7 @@
226 Q_PROPERTY(QDateTime lastUpdated READ lastUpdated NOTIFY lastUpdatedChanged)
227 Q_PROPERTY(QString lastUpdatedString READ lastUpdatedString NOTIFY lastUpdatedChanged)
228 Q_PROPERTY(bool isDefaultNotebook READ isDefaultNotebook WRITE setIsDefaultNotebook NOTIFY isDefaultNotebookChanged)
229+ Q_PROPERTY(bool deleted READ deleted NOTIFY deletedChanged)
230 // Don't forget to update clone() if you add new properties
231
232 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
233@@ -71,6 +72,7 @@
234 bool loading() const;
235 bool synced() const;
236 bool syncError() const;
237+ bool deleted() const;
238
239 Notebook *clone();
240
241@@ -87,6 +89,7 @@
242 void syncedChanged();
243 void syncErrorChanged();
244 void isDefaultNotebookChanged();
245+ void deletedChanged();
246
247 private slots:
248 void noteAdded(const QString &noteGuid, const QString &notebookGuid);
249@@ -101,6 +104,7 @@
250 void setSyncError(bool syncError);
251 void setUpdateSequenceNumber(qint32 updateSequenceNumber);
252 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);
253+ void setDeleted(bool deleted);
254
255 void syncToInfoFile();
256 void deleteInfoFile();
257@@ -114,6 +118,7 @@
258 QDateTime m_lastUpdated;
259 bool m_isDefaultNotebook;
260 QList<QString> m_notesList;
261+ bool m_deleted;
262
263 QString m_infoFile;
264
265
266=== modified file 'src/libqtevernote/notebooks.cpp'
267--- src/libqtevernote/notebooks.cpp 2015-03-06 00:47:45 +0000
268+++ src/libqtevernote/notebooks.cpp 2015-06-11 21:38:48 +0000
269@@ -70,6 +70,8 @@
270 return notebook->syncError();
271 case RoleIsDefaultNotebook:
272 return notebook->isDefaultNotebook();
273+ case RoleDeleted:
274+ return notebook->deleted();
275 }
276 return QVariant();
277 }
278@@ -94,6 +96,7 @@
279 roles.insert(RoleSynced, "synced");
280 roles.insert(RoleSyncError, "syncError");
281 roles.insert(RoleIsDefaultNotebook, "isDefaultNotebook");
282+ roles.insert(RoleDeleted, "deleted");
283 return roles;
284 }
285
286@@ -121,6 +124,7 @@
287 connect(notebook, &Notebook::loadingChanged, this, &Notebooks::notebookLoadingChanged);
288 connect(notebook, &Notebook::syncErrorChanged, this, &Notebooks::syncErrorChanged);
289 connect(notebook, &Notebook::isDefaultNotebookChanged, this, &Notebooks::isDefaultNotebookChanged);
290+ connect(notebook, &Notebook::deletedChanged, this, &Notebooks::deletedChanged);
291
292 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
293 m_list.append(guid);
294@@ -150,6 +154,13 @@
295 emit dataChanged(idx, idx, QVector<int>() << RoleIsDefaultNotebook);
296 }
297
298+void Notebooks::deletedChanged()
299+{
300+ Notebook *notebook = static_cast<Notebook*>(sender());
301+ QModelIndex idx = index(m_list.indexOf(notebook->guid()));
302+ emit dataChanged(idx, idx, QVector<int>() << RoleDeleted);
303+}
304+
305 void Notebooks::nameChanged()
306 {
307 Notebook *notebook = static_cast<Notebook*>(sender());
308
309=== modified file 'src/libqtevernote/notebooks.h'
310--- src/libqtevernote/notebooks.h 2015-03-04 00:23:45 +0000
311+++ src/libqtevernote/notebooks.h 2015-06-11 21:38:48 +0000
312@@ -42,7 +42,8 @@
313 RoleLoading,
314 RoleSynced,
315 RoleSyncError,
316- RoleIsDefaultNotebook
317+ RoleIsDefaultNotebook,
318+ RoleDeleted
319 };
320 explicit Notebooks(QObject *parent = 0);
321
322@@ -76,6 +77,7 @@
323 void notebookLoadingChanged();
324 void syncErrorChanged();
325 void isDefaultNotebookChanged();
326+ void deletedChanged();
327
328 private:
329 QList<QString> m_list;
330
331=== modified file 'src/libqtevernote/notesstore.cpp'
332--- src/libqtevernote/notesstore.cpp 2015-03-30 19:01:49 +0000
333+++ src/libqtevernote/notesstore.cpp 2015-06-11 21:38:48 +0000
334@@ -41,6 +41,7 @@
335 #include "jobs/fetchtagsjob.h"
336 #include "jobs/createtagjob.h"
337 #include "jobs/savetagjob.h"
338+#include "jobs/expungetagjob.h"
339
340 #include "libintl.h"
341
342@@ -404,12 +405,17 @@
343
344 void NotesStore::expungeNotebook(const QString &guid)
345 {
346+#ifdef NO_EXPUNGE_NOTEBOOKS
347+ // This snipped can be used if the app is compiled with a restricted api key
348+ // that can't expunge notebooks on Evernote. Compile with
349+ // cmake -DNO_EXPUNGE_NOTEBOOKS=1
350 if (m_username != "@local") {
351 qCWarning(dcNotesStore) << "Account managed by Evernote. Cannot delete notebooks.";
352 m_errorQueue.append(QString(gettext("This account is managed by Evernote. Use the Evernote website to delete notebooks.")));
353 emit errorChanged();
354 return;
355 }
356+#endif
357
358 Notebook* notebook = m_notebooksHash.value(guid);
359 if (!notebook) {
360@@ -453,17 +459,32 @@
361 }
362 }
363
364- m_notebooks.removeAll(notebook);
365- m_notebooksHash.remove(notebook->guid());
366- emit notebookRemoved(notebook->guid());
367-
368- QSettings settings(m_cacheFile, QSettings::IniFormat);
369- settings.beginGroup("notebooks");
370- settings.remove(notebook->guid());
371- settings.endGroup();
372-
373- notebook->deleteInfoFile();
374- notebook->deleteLater();
375+ if (notebook->lastSyncedSequenceNumber() == 0) {
376+ emit notebookRemoved(notebook->guid());
377+ m_notebooks.removeAll(notebook);
378+ m_notebooksHash.remove(notebook->guid());
379+ emit notebookRemoved(notebook->guid());
380+
381+ QSettings settings(m_cacheFile, QSettings::IniFormat);
382+ settings.beginGroup("notebooks");
383+ settings.remove(notebook->guid());
384+ settings.endGroup();
385+
386+ notebook->deleteInfoFile();
387+ notebook->deleteLater();
388+ } else {
389+ qCDebug(dcNotesStore) << "Setting notebook to deleted:" << notebook->guid();
390+ notebook->setDeleted(true);
391+ notebook->setUpdateSequenceNumber(notebook->updateSequenceNumber()+1);
392+ emit notebookChanged(notebook->guid());
393+ syncToCacheFile(notebook);
394+
395+ if (EvernoteConnection::instance()->isConnected()) {
396+ ExpungeNotebookJob *job = new ExpungeNotebookJob(guid, this);
397+ connect(job, &ExpungeNotebookJob::jobDone, this, &NotesStore::expungeNotebookJobDone);
398+ EvernoteConnection::instance()->enqueue(job);
399+ }
400+ }
401 }
402
403 QList<Tag *> NotesStore::tags() const
404@@ -560,6 +581,33 @@
405 syncToCacheFile(tag);
406 }
407
408+void NotesStore::expungeTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
409+{
410+ handleUserError(errorCode);
411+ if (errorCode != EvernoteConnection::ErrorCodeNoError) {
412+ qCWarning(dcSync) << "Error expunging tag:" << errorMessage;
413+ return;
414+ }
415+
416+ if (!m_tagsHash.contains(guid)) {
417+ qCWarning(dcSync) << "Received a response for a expungeTag call, but can't find tag around any more.";
418+ return;
419+ }
420+
421+ emit tagRemoved(guid);
422+ Tag *tag = m_tagsHash.take(guid);
423+ m_tags.removeAll(tag);
424+
425+ QSettings cacheFile(m_cacheFile, QSettings::IniFormat);
426+ cacheFile.beginGroup("tags");
427+ cacheFile.remove(guid);
428+ cacheFile.endGroup();
429+ tag->syncToInfoFile();
430+
431+ tag->deleteInfoFile();
432+ tag->deleteLater();
433+}
434+
435 void NotesStore::tagNote(const QString &noteGuid, const QString &tagGuid)
436 {
437 Note *note = m_notesHash.value(noteGuid);
438@@ -1030,14 +1078,19 @@
439 syncToCacheFile(notebook);
440 }
441 } else {
442- // Local notebook changed. See if we can push our changes
443 if (result.updateSequenceNum == notebook->lastSyncedSequenceNumber()) {
444- qCDebug(dcNotesStore) << "Local Notebook changed. Uploading changes to Evernote:" << notebook->guid();
445- SaveNotebookJob *job = new SaveNotebookJob(notebook);
446- connect(job, &SaveNotebookJob::jobDone, this, &NotesStore::saveNotebookJobDone);
447- EvernoteConnection::instance()->enqueue(job);
448- notebook->setLoading(true);
449- emit notebookChanged(notebook->guid());
450+ // Local notebook changed. See if we can push our changes
451+ if (notebook->deleted()) {
452+ qCDebug(dcNotesStore) << "Local notebook has been deleted. Deleting from server";
453+ expungeNotebook(notebook->guid());
454+ } else {
455+ qCDebug(dcNotesStore) << "Local Notebook changed. Uploading changes to Evernote:" << notebook->guid();
456+ SaveNotebookJob *job = new SaveNotebookJob(notebook);
457+ connect(job, &SaveNotebookJob::jobDone, this, &NotesStore::saveNotebookJobDone);
458+ EvernoteConnection::instance()->enqueue(job);
459+ notebook->setLoading(true);
460+ emit notebookChanged(notebook->guid());
461+ }
462 } else {
463 qCWarning(dcNotesStore) << "Sync conflict in notebook:" << notebook->name();
464 qCWarning(dcNotesStore) << "Resolving of sync conflicts is not implemented yet.";
465@@ -1134,11 +1187,16 @@
466 } else {
467 // local tag changed. See if we can sync it to the server
468 if (result.updateSequenceNum == tag->lastSyncedSequenceNumber()) {
469- SaveTagJob *job = new SaveTagJob(tag);
470- connect(job, &SaveTagJob::jobDone, this, &NotesStore::saveTagJobDone);
471- EvernoteConnection::instance()->enqueue(job);
472- tag->setLoading(true);
473- emit tagChanged(tag->guid());
474+ if (tag->deleted()) {
475+ qCDebug(dcNotesStore) << "Tag has been deleted locally";
476+ expungeTag(tag->guid());
477+ } else {
478+ SaveTagJob *job = new SaveTagJob(tag);
479+ connect(job, &SaveTagJob::jobDone, this, &NotesStore::saveTagJobDone);
480+ EvernoteConnection::instance()->enqueue(job);
481+ tag->setLoading(true);
482+ emit tagChanged(tag->guid());
483+ }
484 } else {
485 qCWarning(dcSync) << "CONFLICT in tag" << tag->name();
486 tag->setSyncError(true);
487@@ -1473,9 +1531,22 @@
488 qCWarning(dcSync) << "Error expunging notebook:" << errorMessage;
489 return;
490 }
491+
492+ if (!m_notebooksHash.contains(guid)) {
493+ qCWarning(dcSync) << "Received a response for a expungeNotebook call, but can't find notebook around any more.";
494+ return;
495+ }
496+
497 emit notebookRemoved(guid);
498 Notebook *notebook = m_notebooksHash.take(guid);
499 m_notebooks.removeAll(notebook);
500+
501+ QSettings settings(m_cacheFile, QSettings::IniFormat);
502+ settings.beginGroup("notebooks");
503+ settings.remove(notebook->guid());
504+ settings.endGroup();
505+
506+ notebook->deleteInfoFile();
507 notebook->deleteLater();
508 }
509
510@@ -1712,12 +1783,18 @@
511
512 void NotesStore::expungeTag(const QString &guid)
513 {
514+#ifdef NO_EXPUNGE_TAGS
515+ // This snipped can be used if the app is compiled with a restricted api key
516+ // that can't expunge tags on Evernote. Compile with
517+ // cmake -DNO_EXPUNGE_TAGS=1
518+
519 if (m_username != "@local") {
520 qCWarning(dcNotesStore) << "This account is managed by Evernote. Cannot delete tags.";
521 m_errorQueue.append(gettext("This account is managed by Evernote. Please use the Evernote website to delete tags."));
522 emit errorChanged();
523 return;
524 }
525+#endif
526
527 Tag *tag = m_tagsHash.value(guid);
528 if (!tag) {
529@@ -1730,23 +1807,38 @@
530 Note *note = m_notesHash.value(noteGuid);
531 if (!note) {
532 qCWarning(dcNotesStore) << "Tag holds note" << noteGuid << "which hasn't been found in Notes Store";
533+ Q_ASSERT(false);
534 continue;
535 }
536 untagNote(noteGuid, guid);
537 }
538
539- emit tagRemoved(guid);
540- m_tagsHash.remove(guid);
541- m_tags.removeAll(tag);
542-
543- QSettings cacheFile(m_cacheFile, QSettings::IniFormat);
544- cacheFile.beginGroup("tags");
545- cacheFile.remove(guid);
546- cacheFile.endGroup();
547- tag->syncToInfoFile();
548-
549- tag->deleteInfoFile();
550- tag->deleteLater();
551+ if (tag->lastSyncedSequenceNumber() == 0) {
552+ emit tagRemoved(guid);
553+ m_tagsHash.remove(guid);
554+ m_tags.removeAll(tag);
555+
556+ QSettings cacheFile(m_cacheFile, QSettings::IniFormat);
557+ cacheFile.beginGroup("tags");
558+ cacheFile.remove(guid);
559+ cacheFile.endGroup();
560+ tag->syncToInfoFile();
561+
562+ tag->deleteInfoFile();
563+ tag->deleteLater();
564+ } else {
565+ qCDebug(dcNotesStore) << "Setting tag to deleted:" << tag->guid();
566+ tag->setDeleted(true);
567+ tag->setUpdateSequenceNumber(tag->updateSequenceNumber()+1);
568+ emit tagChanged(tag->guid());
569+ syncToCacheFile(tag);
570+
571+ if (EvernoteConnection::instance()->isConnected()) {
572+ ExpungeTagJob *job = new ExpungeTagJob(guid, this);
573+ connect(job, &ExpungeTagJob::jobDone, this, &NotesStore::expungeTagJobDone);
574+ EvernoteConnection::instance()->enqueue(job);
575+ }
576+ }
577 }
578
579 void NotesStore::resolveConflict(const QString &noteGuid, NotesStore::ConflictResolveMode mode)
580
581=== modified file 'src/libqtevernote/notesstore.h'
582--- src/libqtevernote/notesstore.h 2015-03-15 20:00:21 +0000
583+++ src/libqtevernote/notesstore.h 2015-06-11 21:38:48 +0000
584@@ -197,6 +197,7 @@
585 void fetchTagsJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Tag> &results);
586 void createTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &tmpGuid, const evernote::edam::Tag &result);
587 void saveTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Tag &result);
588+ void expungeTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
589
590 void syncToCacheFile(Note *note);
591 void deleteFromCacheFile(Note* note);
592
593=== modified file 'src/libqtevernote/tag.cpp'
594--- src/libqtevernote/tag.cpp 2015-03-04 20:30:55 +0000
595+++ src/libqtevernote/tag.cpp 2015-06-11 21:38:48 +0000
596@@ -29,12 +29,14 @@
597 QObject(parent),
598 m_updateSequenceNumber(updateSequenceNumber),
599 m_guid(guid),
600+ m_deleted(false),
601 m_loading(false),
602 m_syncError(false)
603 {
604 setGuid(guid);
605 QSettings infoFile(m_infoFile, QSettings::IniFormat);
606 m_name = infoFile.value("name").toString();
607+ m_deleted = infoFile.value("deleted").toBool();
608 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();
609 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;
610
611@@ -129,6 +131,7 @@
612 {
613 Tag *tag = new Tag(m_guid, m_updateSequenceNumber);
614 tag->setName(m_name);
615+ tag->setDeleted(m_deleted);
616 return tag;
617 }
618
619@@ -178,6 +181,7 @@
620 {
621 QSettings infoFile(m_infoFile, QSettings::IniFormat);
622 infoFile.setValue("name", m_name);
623+ infoFile.setValue("deleted", m_deleted);
624 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);
625 }
626
627@@ -212,6 +216,11 @@
628 return m_syncError;
629 }
630
631+bool Tag::deleted() const
632+{
633+ return m_deleted;
634+}
635+
636 void Tag::setSyncError(bool syncError)
637 {
638 if (m_syncError != syncError) {
639@@ -220,6 +229,14 @@
640 }
641 }
642
643+void Tag::setDeleted(bool deleted)
644+{
645+ if (m_deleted != deleted) {
646+ m_deleted = deleted;
647+ emit deletedChanged();
648+ }
649+}
650+
651
652 QString Tag::noteAt(int index) const
653 {
654
655=== modified file 'src/libqtevernote/tag.h'
656--- src/libqtevernote/tag.h 2015-03-06 00:42:42 +0000
657+++ src/libqtevernote/tag.h 2015-06-11 21:38:48 +0000
658@@ -38,6 +38,7 @@
659 Q_PROPERTY(QString guid READ guid NOTIFY guidChanged)
660 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
661 Q_PROPERTY(int noteCount READ noteCount NOTIFY noteCountChanged)
662+ Q_PROPERTY(bool deleted READ deleted NOTIFY deletedChanged)
663 // Don't forget to update clone() if you add new properties
664
665 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
666@@ -65,6 +66,7 @@
667 bool loading() const;
668 bool synced() const;
669 bool syncError() const;
670+ bool deleted() const;
671
672 Tag *clone();
673
674@@ -75,6 +77,7 @@
675 void loadingChanged();
676 void syncedChanged();
677 void syncErrorChanged();
678+ void deletedChanged();
679
680 private slots:
681 void noteAdded(const QString &noteGuid, const QString &notebookGuid);
682@@ -88,12 +91,14 @@
683 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);
684 void setLoading(bool loading);
685 void setSyncError(bool syncError);
686+ void setDeleted(bool deleted);
687
688 private:
689 qint32 m_updateSequenceNumber;
690 qint32 m_lastSyncedSequenceNumber;
691 QString m_guid;
692 QString m_name;
693+ bool m_deleted;
694
695 QList<QString> m_notesList;
696
697
698=== modified file 'src/libqtevernote/tags.cpp'
699--- src/libqtevernote/tags.cpp 2015-03-06 00:47:45 +0000
700+++ src/libqtevernote/tags.cpp 2015-06-11 21:38:48 +0000
701@@ -61,6 +61,8 @@
702 return tag->synced();
703 case RoleSyncError:
704 return tag->syncError();
705+ case RoleDeleted:
706+ return tag->deleted();
707 }
708 return QVariant();
709 }
710@@ -80,6 +82,7 @@
711 roles.insert(RoleLoading, "loading");
712 roles.insert(RoleSynced, "synced");
713 roles.insert(RoleSyncError, "syncError");
714+ roles.insert(RoleDeleted, "deleted");
715 return roles;
716 }
717
718@@ -104,6 +107,7 @@
719 connect(tag, &Tag::loadingChanged, this, &Tags::tagLoadingChanged);
720 connect(tag, &Tag::syncedChanged, this, &Tags::syncedChanged);
721 connect(tag, &Tag::syncErrorChanged, this, &Tags::syncErrorChanged);
722+ connect(tag, &Tag::deletedChanged, this, &Tags::deletedChanged);
723
724 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
725 m_list.append(guid);
726@@ -128,6 +132,13 @@
727 }
728 }
729
730+void Tags::deletedChanged()
731+{
732+ Tag *tag = static_cast<Tag*>(sender());
733+ int idx = m_list.indexOf(tag->guid());
734+ emit dataChanged(index(idx), index(idx), QVector<int>() << RoleDeleted);
735+}
736+
737 void Tags::nameChanged()
738 {
739 Tag *tag = static_cast<Tag*>(sender());
740
741=== modified file 'src/libqtevernote/tags.h'
742--- src/libqtevernote/tags.h 2015-03-04 00:23:45 +0000
743+++ src/libqtevernote/tags.h 2015-06-11 21:38:48 +0000
744@@ -38,7 +38,8 @@
745 RoleNoteCount,
746 RoleLoading,
747 RoleSynced,
748- RoleSyncError
749+ RoleSyncError,
750+ RoleDeleted
751 };
752 explicit Tags(QObject *parent = 0);
753
754@@ -62,6 +63,7 @@
755 void tagAdded(const QString &guid);
756 void tagRemoved(const QString &guid);
757 void tagGuidChanged(const QString &oldGuid, const QString &newGuid);
758+ void deletedChanged();
759
760 void nameChanged();
761 void noteCountChanged();

Subscribers

People subscribed via source and target branches