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
=== modified file 'src/app/qml/components/NotebooksDelegate.qml'
--- src/app/qml/components/NotebooksDelegate.qml 2015-03-15 20:00:21 +0000
+++ src/app/qml/components/NotebooksDelegate.qml 2015-06-11 21:38:48 +0000
@@ -89,6 +89,7 @@
89 color: root.notebookColor89 color: root.notebookColor
90 fontSize: "large"90 fontSize: "large"
91 Layout.fillWidth: true91 Layout.fillWidth: true
92 font.strikeout: model.deleted
92 }93 }
9394
94 Label {95 Label {
9596
=== modified file 'src/app/qml/components/TagsDelegate.qml'
--- src/app/qml/components/TagsDelegate.qml 2015-03-15 20:00:21 +0000
+++ src/app/qml/components/TagsDelegate.qml 2015-06-11 21:38:48 +0000
@@ -80,6 +80,7 @@
80 text: model.name80 text: model.name
81 fontSize: "large"81 fontSize: "large"
82 Layout.fillWidth: true82 Layout.fillWidth: true
83 font.strikeout: model.deleted
83 }84 }
84 }85 }
8586
8687
=== modified file 'src/app/qml/reminders.qml'
--- src/app/qml/reminders.qml 2015-06-01 09:56:30 +0000
+++ src/app/qml/reminders.qml 2015-06-11 21:38:48 +0000
@@ -383,7 +383,8 @@
383 onAuthenticated: {383 onAuthenticated: {
384 EvernoteConnection.token = reply.AccessToken;384 EvernoteConnection.token = reply.AccessToken;
385 print("token is:", EvernoteConnection.token)385 print("token is:", EvernoteConnection.token)
386 if (NetworkingStatus.online) {386 print("NetworkingStatus.online:", NetworkingStatus.Online)
387 if (NetworkingStatus.Online) {
387 EvernoteConnection.connectToEvernote();388 EvernoteConnection.connectToEvernote();
388 }389 }
389 }390 }
390391
=== modified file 'src/libqtevernote/CMakeLists.txt'
--- src/libqtevernote/CMakeLists.txt 2015-03-06 00:42:42 +0000
+++ src/libqtevernote/CMakeLists.txt 2015-06-11 21:38:48 +0000
@@ -32,6 +32,7 @@
32 jobs/fetchtagsjob.cpp32 jobs/fetchtagsjob.cpp
33 jobs/createtagjob.cpp33 jobs/createtagjob.cpp
34 jobs/savetagjob.cpp34 jobs/savetagjob.cpp
35 jobs/expungetagjob.cpp
35 resourceimageprovider.cpp36 resourceimageprovider.cpp
36 utils/enmldocument.cpp37 utils/enmldocument.cpp
37 utils/organizeradapter.cpp38 utils/organizeradapter.cpp
3839
=== added file 'src/libqtevernote/jobs/expungetagjob.cpp'
--- src/libqtevernote/jobs/expungetagjob.cpp 1970-01-01 00:00:00 +0000
+++ src/libqtevernote/jobs/expungetagjob.cpp 2015-06-11 21:38:48 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright: 2015 Canonical, Ltd
3 *
4 * This file is part of reminders
5 *
6 * reminders is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "expungetagjob.h"
22
23ExpungeTagJob::ExpungeTagJob(const QString &guid, QObject *parent) :
24 NotesStoreJob(parent),
25 m_guid(guid)
26{
27}
28
29bool ExpungeTagJob::operator==(const EvernoteJob *other) const
30{
31 const ExpungeTagJob *otherJob = qobject_cast<const ExpungeTagJob*>(other);
32 if (!otherJob) {
33 return false;
34 }
35 return this->m_guid == otherJob->m_guid;
36}
37
38void ExpungeTagJob::attachToDuplicate(const EvernoteJob *other)
39{
40 const ExpungeTagJob *otherJob = static_cast<const ExpungeTagJob*>(other);
41 connect(otherJob, &ExpungeTagJob::jobDone, this, &ExpungeTagJob::jobDone);
42}
43
44void ExpungeTagJob::startJob()
45{
46 client()->expungeTag(token().toStdString(), m_guid.toStdString());
47}
48
49void ExpungeTagJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
50{
51 emit jobDone(errorCode, errorMessage, m_guid);
52}
053
=== added file 'src/libqtevernote/jobs/expungetagjob.h'
--- src/libqtevernote/jobs/expungetagjob.h 1970-01-01 00:00:00 +0000
+++ src/libqtevernote/jobs/expungetagjob.h 2015-06-11 21:38:48 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright: 2015 Canonical, Ltd
3 *
4 * This file is part of reminders
5 *
6 * reminders is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef EXPUNGETAGJOB_H
22#define EXPUNGETAGJOB_H
23
24#include "notesstorejob.h"
25
26class ExpungeTagJob : public NotesStoreJob
27{
28 Q_OBJECT
29public:
30 explicit ExpungeTagJob(const QString &guid, QObject *parent = 0);
31
32 virtual bool operator==(const EvernoteJob *other) const override;
33 virtual void attachToDuplicate(const EvernoteJob *other) override;
34
35signals:
36 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
37
38private slots:
39 void startJob();
40 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
41
42private:
43 QString m_guid;
44};
45
46#endif // EXPUNGETAGJOB_H
047
=== modified file 'src/libqtevernote/notebook.cpp'
--- src/libqtevernote/notebook.cpp 2015-03-06 00:47:45 +0000
+++ src/libqtevernote/notebook.cpp 2015-06-11 21:38:48 +0000
@@ -33,6 +33,7 @@
33 m_guid(guid),33 m_guid(guid),
34 m_published(false),34 m_published(false),
35 m_isDefaultNotebook(false),35 m_isDefaultNotebook(false),
36 m_deleted(false),
36 m_loading(false),37 m_loading(false),
37 m_syncError(false)38 m_syncError(false)
38{39{
@@ -44,6 +45,7 @@
44 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();45 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();
45 m_isDefaultNotebook = infoFile.value("isDefaultNotebook", false).toBool();46 m_isDefaultNotebook = infoFile.value("isDefaultNotebook", false).toBool();
46 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;47 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;
48 m_deleted = infoFile.value("deleted", false).toBool();
4749
48 foreach (Note *note, NotesStore::instance()->notes()) {50 foreach (Note *note, NotesStore::instance()->notes()) {
49 if (note->notebookGuid() == m_guid) {51 if (note->notebookGuid() == m_guid) {
@@ -155,6 +157,7 @@
155 notebook->setName(m_name);157 notebook->setName(m_name);
156 notebook->setLastUpdated(m_lastUpdated);158 notebook->setLastUpdated(m_lastUpdated);
157 notebook->setPublished(m_published);159 notebook->setPublished(m_published);
160 notebook->setDeleted(m_deleted);
158161
159 return notebook;162 return notebook;
160}163}
@@ -232,6 +235,7 @@
232 infoFile.value("lastUpdated", m_lastUpdated);235 infoFile.value("lastUpdated", m_lastUpdated);
233 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);236 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);
234 infoFile.setValue("isDefaultNotebook", m_isDefaultNotebook);237 infoFile.setValue("isDefaultNotebook", m_isDefaultNotebook);
238 infoFile.setValue("deleted", m_deleted);
235}239}
236240
237void Notebook::deleteInfoFile()241void Notebook::deleteInfoFile()
@@ -257,6 +261,11 @@
257 return m_syncError;261 return m_syncError;
258}262}
259263
264bool Notebook::deleted() const
265{
266 return m_deleted;
267}
268
260qint32 Notebook::updateSequenceNumber() const269qint32 Notebook::updateSequenceNumber() const
261{270{
262 return m_updateSequenceNumber;271 return m_updateSequenceNumber;
@@ -287,6 +296,14 @@
287 }296 }
288}297}
289298
299void Notebook::setDeleted(bool deleted)
300{
301 if (m_deleted != deleted) {
302 m_deleted = deleted;
303 emit deletedChanged();
304 }
305}
306
290void Notebook::setLoading(bool loading)307void Notebook::setLoading(bool loading)
291{308{
292 if (m_loading != loading) {309 if (m_loading != loading) {
293310
=== modified file 'src/libqtevernote/notebook.h'
--- src/libqtevernote/notebook.h 2015-03-04 20:30:55 +0000
+++ src/libqtevernote/notebook.h 2015-06-11 21:38:48 +0000
@@ -37,6 +37,7 @@
37 Q_PROPERTY(QDateTime lastUpdated READ lastUpdated NOTIFY lastUpdatedChanged)37 Q_PROPERTY(QDateTime lastUpdated READ lastUpdated NOTIFY lastUpdatedChanged)
38 Q_PROPERTY(QString lastUpdatedString READ lastUpdatedString NOTIFY lastUpdatedChanged)38 Q_PROPERTY(QString lastUpdatedString READ lastUpdatedString NOTIFY lastUpdatedChanged)
39 Q_PROPERTY(bool isDefaultNotebook READ isDefaultNotebook WRITE setIsDefaultNotebook NOTIFY isDefaultNotebookChanged)39 Q_PROPERTY(bool isDefaultNotebook READ isDefaultNotebook WRITE setIsDefaultNotebook NOTIFY isDefaultNotebookChanged)
40 Q_PROPERTY(bool deleted READ deleted NOTIFY deletedChanged)
40 // Don't forget to update clone() if you add new properties41 // Don't forget to update clone() if you add new properties
4142
42 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)43 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
@@ -71,6 +72,7 @@
71 bool loading() const;72 bool loading() const;
72 bool synced() const;73 bool synced() const;
73 bool syncError() const;74 bool syncError() const;
75 bool deleted() const;
7476
75 Notebook *clone();77 Notebook *clone();
7678
@@ -87,6 +89,7 @@
87 void syncedChanged();89 void syncedChanged();
88 void syncErrorChanged();90 void syncErrorChanged();
89 void isDefaultNotebookChanged();91 void isDefaultNotebookChanged();
92 void deletedChanged();
9093
91private slots:94private slots:
92 void noteAdded(const QString &noteGuid, const QString &notebookGuid);95 void noteAdded(const QString &noteGuid, const QString &notebookGuid);
@@ -101,6 +104,7 @@
101 void setSyncError(bool syncError);104 void setSyncError(bool syncError);
102 void setUpdateSequenceNumber(qint32 updateSequenceNumber);105 void setUpdateSequenceNumber(qint32 updateSequenceNumber);
103 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);106 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);
107 void setDeleted(bool deleted);
104108
105 void syncToInfoFile();109 void syncToInfoFile();
106 void deleteInfoFile();110 void deleteInfoFile();
@@ -114,6 +118,7 @@
114 QDateTime m_lastUpdated;118 QDateTime m_lastUpdated;
115 bool m_isDefaultNotebook;119 bool m_isDefaultNotebook;
116 QList<QString> m_notesList;120 QList<QString> m_notesList;
121 bool m_deleted;
117122
118 QString m_infoFile;123 QString m_infoFile;
119124
120125
=== modified file 'src/libqtevernote/notebooks.cpp'
--- src/libqtevernote/notebooks.cpp 2015-03-06 00:47:45 +0000
+++ src/libqtevernote/notebooks.cpp 2015-06-11 21:38:48 +0000
@@ -70,6 +70,8 @@
70 return notebook->syncError();70 return notebook->syncError();
71 case RoleIsDefaultNotebook:71 case RoleIsDefaultNotebook:
72 return notebook->isDefaultNotebook();72 return notebook->isDefaultNotebook();
73 case RoleDeleted:
74 return notebook->deleted();
73 }75 }
74 return QVariant();76 return QVariant();
75}77}
@@ -94,6 +96,7 @@
94 roles.insert(RoleSynced, "synced");96 roles.insert(RoleSynced, "synced");
95 roles.insert(RoleSyncError, "syncError");97 roles.insert(RoleSyncError, "syncError");
96 roles.insert(RoleIsDefaultNotebook, "isDefaultNotebook");98 roles.insert(RoleIsDefaultNotebook, "isDefaultNotebook");
99 roles.insert(RoleDeleted, "deleted");
97 return roles;100 return roles;
98}101}
99102
@@ -121,6 +124,7 @@
121 connect(notebook, &Notebook::loadingChanged, this, &Notebooks::notebookLoadingChanged);124 connect(notebook, &Notebook::loadingChanged, this, &Notebooks::notebookLoadingChanged);
122 connect(notebook, &Notebook::syncErrorChanged, this, &Notebooks::syncErrorChanged);125 connect(notebook, &Notebook::syncErrorChanged, this, &Notebooks::syncErrorChanged);
123 connect(notebook, &Notebook::isDefaultNotebookChanged, this, &Notebooks::isDefaultNotebookChanged);126 connect(notebook, &Notebook::isDefaultNotebookChanged, this, &Notebooks::isDefaultNotebookChanged);
127 connect(notebook, &Notebook::deletedChanged, this, &Notebooks::deletedChanged);
124128
125 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());129 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
126 m_list.append(guid);130 m_list.append(guid);
@@ -150,6 +154,13 @@
150 emit dataChanged(idx, idx, QVector<int>() << RoleIsDefaultNotebook);154 emit dataChanged(idx, idx, QVector<int>() << RoleIsDefaultNotebook);
151}155}
152156
157void Notebooks::deletedChanged()
158{
159 Notebook *notebook = static_cast<Notebook*>(sender());
160 QModelIndex idx = index(m_list.indexOf(notebook->guid()));
161 emit dataChanged(idx, idx, QVector<int>() << RoleDeleted);
162}
163
153void Notebooks::nameChanged()164void Notebooks::nameChanged()
154{165{
155 Notebook *notebook = static_cast<Notebook*>(sender());166 Notebook *notebook = static_cast<Notebook*>(sender());
156167
=== modified file 'src/libqtevernote/notebooks.h'
--- src/libqtevernote/notebooks.h 2015-03-04 00:23:45 +0000
+++ src/libqtevernote/notebooks.h 2015-06-11 21:38:48 +0000
@@ -42,7 +42,8 @@
42 RoleLoading,42 RoleLoading,
43 RoleSynced,43 RoleSynced,
44 RoleSyncError,44 RoleSyncError,
45 RoleIsDefaultNotebook45 RoleIsDefaultNotebook,
46 RoleDeleted
46 };47 };
47 explicit Notebooks(QObject *parent = 0);48 explicit Notebooks(QObject *parent = 0);
4849
@@ -76,6 +77,7 @@
76 void notebookLoadingChanged();77 void notebookLoadingChanged();
77 void syncErrorChanged();78 void syncErrorChanged();
78 void isDefaultNotebookChanged();79 void isDefaultNotebookChanged();
80 void deletedChanged();
7981
80private:82private:
81 QList<QString> m_list;83 QList<QString> m_list;
8284
=== modified file 'src/libqtevernote/notesstore.cpp'
--- src/libqtevernote/notesstore.cpp 2015-03-30 19:01:49 +0000
+++ src/libqtevernote/notesstore.cpp 2015-06-11 21:38:48 +0000
@@ -41,6 +41,7 @@
41#include "jobs/fetchtagsjob.h"41#include "jobs/fetchtagsjob.h"
42#include "jobs/createtagjob.h"42#include "jobs/createtagjob.h"
43#include "jobs/savetagjob.h"43#include "jobs/savetagjob.h"
44#include "jobs/expungetagjob.h"
4445
45#include "libintl.h"46#include "libintl.h"
4647
@@ -404,12 +405,17 @@
404405
405void NotesStore::expungeNotebook(const QString &guid)406void NotesStore::expungeNotebook(const QString &guid)
406{407{
408#ifdef NO_EXPUNGE_NOTEBOOKS
409 // This snipped can be used if the app is compiled with a restricted api key
410 // that can't expunge notebooks on Evernote. Compile with
411 // cmake -DNO_EXPUNGE_NOTEBOOKS=1
407 if (m_username != "@local") {412 if (m_username != "@local") {
408 qCWarning(dcNotesStore) << "Account managed by Evernote. Cannot delete notebooks.";413 qCWarning(dcNotesStore) << "Account managed by Evernote. Cannot delete notebooks.";
409 m_errorQueue.append(QString(gettext("This account is managed by Evernote. Use the Evernote website to delete notebooks.")));414 m_errorQueue.append(QString(gettext("This account is managed by Evernote. Use the Evernote website to delete notebooks.")));
410 emit errorChanged();415 emit errorChanged();
411 return;416 return;
412 }417 }
418#endif
413419
414 Notebook* notebook = m_notebooksHash.value(guid);420 Notebook* notebook = m_notebooksHash.value(guid);
415 if (!notebook) {421 if (!notebook) {
@@ -453,17 +459,32 @@
453 }459 }
454 }460 }
455461
456 m_notebooks.removeAll(notebook);462 if (notebook->lastSyncedSequenceNumber() == 0) {
457 m_notebooksHash.remove(notebook->guid());463 emit notebookRemoved(notebook->guid());
458 emit notebookRemoved(notebook->guid());464 m_notebooks.removeAll(notebook);
459465 m_notebooksHash.remove(notebook->guid());
460 QSettings settings(m_cacheFile, QSettings::IniFormat);466 emit notebookRemoved(notebook->guid());
461 settings.beginGroup("notebooks");467
462 settings.remove(notebook->guid());468 QSettings settings(m_cacheFile, QSettings::IniFormat);
463 settings.endGroup();469 settings.beginGroup("notebooks");
464470 settings.remove(notebook->guid());
465 notebook->deleteInfoFile();471 settings.endGroup();
466 notebook->deleteLater();472
473 notebook->deleteInfoFile();
474 notebook->deleteLater();
475 } else {
476 qCDebug(dcNotesStore) << "Setting notebook to deleted:" << notebook->guid();
477 notebook->setDeleted(true);
478 notebook->setUpdateSequenceNumber(notebook->updateSequenceNumber()+1);
479 emit notebookChanged(notebook->guid());
480 syncToCacheFile(notebook);
481
482 if (EvernoteConnection::instance()->isConnected()) {
483 ExpungeNotebookJob *job = new ExpungeNotebookJob(guid, this);
484 connect(job, &ExpungeNotebookJob::jobDone, this, &NotesStore::expungeNotebookJobDone);
485 EvernoteConnection::instance()->enqueue(job);
486 }
487 }
467}488}
468489
469QList<Tag *> NotesStore::tags() const490QList<Tag *> NotesStore::tags() const
@@ -560,6 +581,33 @@
560 syncToCacheFile(tag);581 syncToCacheFile(tag);
561}582}
562583
584void NotesStore::expungeTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
585{
586 handleUserError(errorCode);
587 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
588 qCWarning(dcSync) << "Error expunging tag:" << errorMessage;
589 return;
590 }
591
592 if (!m_tagsHash.contains(guid)) {
593 qCWarning(dcSync) << "Received a response for a expungeTag call, but can't find tag around any more.";
594 return;
595 }
596
597 emit tagRemoved(guid);
598 Tag *tag = m_tagsHash.take(guid);
599 m_tags.removeAll(tag);
600
601 QSettings cacheFile(m_cacheFile, QSettings::IniFormat);
602 cacheFile.beginGroup("tags");
603 cacheFile.remove(guid);
604 cacheFile.endGroup();
605 tag->syncToInfoFile();
606
607 tag->deleteInfoFile();
608 tag->deleteLater();
609}
610
563void NotesStore::tagNote(const QString &noteGuid, const QString &tagGuid)611void NotesStore::tagNote(const QString &noteGuid, const QString &tagGuid)
564{612{
565 Note *note = m_notesHash.value(noteGuid);613 Note *note = m_notesHash.value(noteGuid);
@@ -1030,14 +1078,19 @@
1030 syncToCacheFile(notebook);1078 syncToCacheFile(notebook);
1031 }1079 }
1032 } else {1080 } else {
1033 // Local notebook changed. See if we can push our changes
1034 if (result.updateSequenceNum == notebook->lastSyncedSequenceNumber()) {1081 if (result.updateSequenceNum == notebook->lastSyncedSequenceNumber()) {
1035 qCDebug(dcNotesStore) << "Local Notebook changed. Uploading changes to Evernote:" << notebook->guid();1082 // Local notebook changed. See if we can push our changes
1036 SaveNotebookJob *job = new SaveNotebookJob(notebook);1083 if (notebook->deleted()) {
1037 connect(job, &SaveNotebookJob::jobDone, this, &NotesStore::saveNotebookJobDone);1084 qCDebug(dcNotesStore) << "Local notebook has been deleted. Deleting from server";
1038 EvernoteConnection::instance()->enqueue(job);1085 expungeNotebook(notebook->guid());
1039 notebook->setLoading(true);1086 } else {
1040 emit notebookChanged(notebook->guid());1087 qCDebug(dcNotesStore) << "Local Notebook changed. Uploading changes to Evernote:" << notebook->guid();
1088 SaveNotebookJob *job = new SaveNotebookJob(notebook);
1089 connect(job, &SaveNotebookJob::jobDone, this, &NotesStore::saveNotebookJobDone);
1090 EvernoteConnection::instance()->enqueue(job);
1091 notebook->setLoading(true);
1092 emit notebookChanged(notebook->guid());
1093 }
1041 } else {1094 } else {
1042 qCWarning(dcNotesStore) << "Sync conflict in notebook:" << notebook->name();1095 qCWarning(dcNotesStore) << "Sync conflict in notebook:" << notebook->name();
1043 qCWarning(dcNotesStore) << "Resolving of sync conflicts is not implemented yet.";1096 qCWarning(dcNotesStore) << "Resolving of sync conflicts is not implemented yet.";
@@ -1134,11 +1187,16 @@
1134 } else {1187 } else {
1135 // local tag changed. See if we can sync it to the server1188 // local tag changed. See if we can sync it to the server
1136 if (result.updateSequenceNum == tag->lastSyncedSequenceNumber()) {1189 if (result.updateSequenceNum == tag->lastSyncedSequenceNumber()) {
1137 SaveTagJob *job = new SaveTagJob(tag);1190 if (tag->deleted()) {
1138 connect(job, &SaveTagJob::jobDone, this, &NotesStore::saveTagJobDone);1191 qCDebug(dcNotesStore) << "Tag has been deleted locally";
1139 EvernoteConnection::instance()->enqueue(job);1192 expungeTag(tag->guid());
1140 tag->setLoading(true);1193 } else {
1141 emit tagChanged(tag->guid());1194 SaveTagJob *job = new SaveTagJob(tag);
1195 connect(job, &SaveTagJob::jobDone, this, &NotesStore::saveTagJobDone);
1196 EvernoteConnection::instance()->enqueue(job);
1197 tag->setLoading(true);
1198 emit tagChanged(tag->guid());
1199 }
1142 } else {1200 } else {
1143 qCWarning(dcSync) << "CONFLICT in tag" << tag->name();1201 qCWarning(dcSync) << "CONFLICT in tag" << tag->name();
1144 tag->setSyncError(true);1202 tag->setSyncError(true);
@@ -1473,9 +1531,22 @@
1473 qCWarning(dcSync) << "Error expunging notebook:" << errorMessage;1531 qCWarning(dcSync) << "Error expunging notebook:" << errorMessage;
1474 return;1532 return;
1475 }1533 }
1534
1535 if (!m_notebooksHash.contains(guid)) {
1536 qCWarning(dcSync) << "Received a response for a expungeNotebook call, but can't find notebook around any more.";
1537 return;
1538 }
1539
1476 emit notebookRemoved(guid);1540 emit notebookRemoved(guid);
1477 Notebook *notebook = m_notebooksHash.take(guid);1541 Notebook *notebook = m_notebooksHash.take(guid);
1478 m_notebooks.removeAll(notebook);1542 m_notebooks.removeAll(notebook);
1543
1544 QSettings settings(m_cacheFile, QSettings::IniFormat);
1545 settings.beginGroup("notebooks");
1546 settings.remove(notebook->guid());
1547 settings.endGroup();
1548
1549 notebook->deleteInfoFile();
1479 notebook->deleteLater();1550 notebook->deleteLater();
1480}1551}
14811552
@@ -1712,12 +1783,18 @@
17121783
1713void NotesStore::expungeTag(const QString &guid)1784void NotesStore::expungeTag(const QString &guid)
1714{1785{
1786#ifdef NO_EXPUNGE_TAGS
1787 // This snipped can be used if the app is compiled with a restricted api key
1788 // that can't expunge tags on Evernote. Compile with
1789 // cmake -DNO_EXPUNGE_TAGS=1
1790
1715 if (m_username != "@local") {1791 if (m_username != "@local") {
1716 qCWarning(dcNotesStore) << "This account is managed by Evernote. Cannot delete tags.";1792 qCWarning(dcNotesStore) << "This account is managed by Evernote. Cannot delete tags.";
1717 m_errorQueue.append(gettext("This account is managed by Evernote. Please use the Evernote website to delete tags."));1793 m_errorQueue.append(gettext("This account is managed by Evernote. Please use the Evernote website to delete tags."));
1718 emit errorChanged();1794 emit errorChanged();
1719 return;1795 return;
1720 }1796 }
1797#endif
17211798
1722 Tag *tag = m_tagsHash.value(guid);1799 Tag *tag = m_tagsHash.value(guid);
1723 if (!tag) {1800 if (!tag) {
@@ -1730,23 +1807,38 @@
1730 Note *note = m_notesHash.value(noteGuid);1807 Note *note = m_notesHash.value(noteGuid);
1731 if (!note) {1808 if (!note) {
1732 qCWarning(dcNotesStore) << "Tag holds note" << noteGuid << "which hasn't been found in Notes Store";1809 qCWarning(dcNotesStore) << "Tag holds note" << noteGuid << "which hasn't been found in Notes Store";
1810 Q_ASSERT(false);
1733 continue;1811 continue;
1734 }1812 }
1735 untagNote(noteGuid, guid);1813 untagNote(noteGuid, guid);
1736 }1814 }
17371815
1738 emit tagRemoved(guid);1816 if (tag->lastSyncedSequenceNumber() == 0) {
1739 m_tagsHash.remove(guid);1817 emit tagRemoved(guid);
1740 m_tags.removeAll(tag);1818 m_tagsHash.remove(guid);
17411819 m_tags.removeAll(tag);
1742 QSettings cacheFile(m_cacheFile, QSettings::IniFormat);1820
1743 cacheFile.beginGroup("tags");1821 QSettings cacheFile(m_cacheFile, QSettings::IniFormat);
1744 cacheFile.remove(guid);1822 cacheFile.beginGroup("tags");
1745 cacheFile.endGroup();1823 cacheFile.remove(guid);
1746 tag->syncToInfoFile();1824 cacheFile.endGroup();
17471825 tag->syncToInfoFile();
1748 tag->deleteInfoFile();1826
1749 tag->deleteLater();1827 tag->deleteInfoFile();
1828 tag->deleteLater();
1829 } else {
1830 qCDebug(dcNotesStore) << "Setting tag to deleted:" << tag->guid();
1831 tag->setDeleted(true);
1832 tag->setUpdateSequenceNumber(tag->updateSequenceNumber()+1);
1833 emit tagChanged(tag->guid());
1834 syncToCacheFile(tag);
1835
1836 if (EvernoteConnection::instance()->isConnected()) {
1837 ExpungeTagJob *job = new ExpungeTagJob(guid, this);
1838 connect(job, &ExpungeTagJob::jobDone, this, &NotesStore::expungeTagJobDone);
1839 EvernoteConnection::instance()->enqueue(job);
1840 }
1841 }
1750}1842}
17511843
1752void NotesStore::resolveConflict(const QString &noteGuid, NotesStore::ConflictResolveMode mode)1844void NotesStore::resolveConflict(const QString &noteGuid, NotesStore::ConflictResolveMode mode)
17531845
=== modified file 'src/libqtevernote/notesstore.h'
--- src/libqtevernote/notesstore.h 2015-03-15 20:00:21 +0000
+++ src/libqtevernote/notesstore.h 2015-06-11 21:38:48 +0000
@@ -197,6 +197,7 @@
197 void fetchTagsJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Tag> &results);197 void fetchTagsJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Tag> &results);
198 void createTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &tmpGuid, const evernote::edam::Tag &result);198 void createTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &tmpGuid, const evernote::edam::Tag &result);
199 void saveTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Tag &result);199 void saveTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Tag &result);
200 void expungeTagJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
200201
201 void syncToCacheFile(Note *note);202 void syncToCacheFile(Note *note);
202 void deleteFromCacheFile(Note* note);203 void deleteFromCacheFile(Note* note);
203204
=== modified file 'src/libqtevernote/tag.cpp'
--- src/libqtevernote/tag.cpp 2015-03-04 20:30:55 +0000
+++ src/libqtevernote/tag.cpp 2015-06-11 21:38:48 +0000
@@ -29,12 +29,14 @@
29 QObject(parent),29 QObject(parent),
30 m_updateSequenceNumber(updateSequenceNumber),30 m_updateSequenceNumber(updateSequenceNumber),
31 m_guid(guid),31 m_guid(guid),
32 m_deleted(false),
32 m_loading(false),33 m_loading(false),
33 m_syncError(false)34 m_syncError(false)
34{35{
35 setGuid(guid);36 setGuid(guid);
36 QSettings infoFile(m_infoFile, QSettings::IniFormat);37 QSettings infoFile(m_infoFile, QSettings::IniFormat);
37 m_name = infoFile.value("name").toString();38 m_name = infoFile.value("name").toString();
39 m_deleted = infoFile.value("deleted").toBool();
38 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();40 m_lastSyncedSequenceNumber = infoFile.value("lastSyncedSequenceNumber", 0).toUInt();
39 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;41 m_synced = m_lastSyncedSequenceNumber == m_updateSequenceNumber;
4042
@@ -129,6 +131,7 @@
129{131{
130 Tag *tag = new Tag(m_guid, m_updateSequenceNumber);132 Tag *tag = new Tag(m_guid, m_updateSequenceNumber);
131 tag->setName(m_name);133 tag->setName(m_name);
134 tag->setDeleted(m_deleted);
132 return tag;135 return tag;
133}136}
134137
@@ -178,6 +181,7 @@
178{181{
179 QSettings infoFile(m_infoFile, QSettings::IniFormat);182 QSettings infoFile(m_infoFile, QSettings::IniFormat);
180 infoFile.setValue("name", m_name);183 infoFile.setValue("name", m_name);
184 infoFile.setValue("deleted", m_deleted);
181 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);185 infoFile.setValue("lastSyncedSequenceNumber", m_lastSyncedSequenceNumber);
182}186}
183187
@@ -212,6 +216,11 @@
212 return m_syncError;216 return m_syncError;
213}217}
214218
219bool Tag::deleted() const
220{
221 return m_deleted;
222}
223
215void Tag::setSyncError(bool syncError)224void Tag::setSyncError(bool syncError)
216{225{
217 if (m_syncError != syncError) {226 if (m_syncError != syncError) {
@@ -220,6 +229,14 @@
220 }229 }
221}230}
222231
232void Tag::setDeleted(bool deleted)
233{
234 if (m_deleted != deleted) {
235 m_deleted = deleted;
236 emit deletedChanged();
237 }
238}
239
223240
224QString Tag::noteAt(int index) const241QString Tag::noteAt(int index) const
225{242{
226243
=== modified file 'src/libqtevernote/tag.h'
--- src/libqtevernote/tag.h 2015-03-06 00:42:42 +0000
+++ src/libqtevernote/tag.h 2015-06-11 21:38:48 +0000
@@ -38,6 +38,7 @@
38 Q_PROPERTY(QString guid READ guid NOTIFY guidChanged)38 Q_PROPERTY(QString guid READ guid NOTIFY guidChanged)
39 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)39 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
40 Q_PROPERTY(int noteCount READ noteCount NOTIFY noteCountChanged)40 Q_PROPERTY(int noteCount READ noteCount NOTIFY noteCountChanged)
41 Q_PROPERTY(bool deleted READ deleted NOTIFY deletedChanged)
41 // Don't forget to update clone() if you add new properties42 // Don't forget to update clone() if you add new properties
4243
43 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)44 Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
@@ -65,6 +66,7 @@
65 bool loading() const;66 bool loading() const;
66 bool synced() const;67 bool synced() const;
67 bool syncError() const;68 bool syncError() const;
69 bool deleted() const;
6870
69 Tag *clone();71 Tag *clone();
7072
@@ -75,6 +77,7 @@
75 void loadingChanged();77 void loadingChanged();
76 void syncedChanged();78 void syncedChanged();
77 void syncErrorChanged();79 void syncErrorChanged();
80 void deletedChanged();
7881
79private slots:82private slots:
80 void noteAdded(const QString &noteGuid, const QString &notebookGuid);83 void noteAdded(const QString &noteGuid, const QString &notebookGuid);
@@ -88,12 +91,14 @@
88 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);91 void setLastSyncedSequenceNumber(qint32 lastSyncedSequenceNumber);
89 void setLoading(bool loading);92 void setLoading(bool loading);
90 void setSyncError(bool syncError);93 void setSyncError(bool syncError);
94 void setDeleted(bool deleted);
9195
92private:96private:
93 qint32 m_updateSequenceNumber;97 qint32 m_updateSequenceNumber;
94 qint32 m_lastSyncedSequenceNumber;98 qint32 m_lastSyncedSequenceNumber;
95 QString m_guid;99 QString m_guid;
96 QString m_name;100 QString m_name;
101 bool m_deleted;
97102
98 QList<QString> m_notesList;103 QList<QString> m_notesList;
99104
100105
=== modified file 'src/libqtevernote/tags.cpp'
--- src/libqtevernote/tags.cpp 2015-03-06 00:47:45 +0000
+++ src/libqtevernote/tags.cpp 2015-06-11 21:38:48 +0000
@@ -61,6 +61,8 @@
61 return tag->synced();61 return tag->synced();
62 case RoleSyncError:62 case RoleSyncError:
63 return tag->syncError();63 return tag->syncError();
64 case RoleDeleted:
65 return tag->deleted();
64 }66 }
65 return QVariant();67 return QVariant();
66}68}
@@ -80,6 +82,7 @@
80 roles.insert(RoleLoading, "loading");82 roles.insert(RoleLoading, "loading");
81 roles.insert(RoleSynced, "synced");83 roles.insert(RoleSynced, "synced");
82 roles.insert(RoleSyncError, "syncError");84 roles.insert(RoleSyncError, "syncError");
85 roles.insert(RoleDeleted, "deleted");
83 return roles;86 return roles;
84}87}
8588
@@ -104,6 +107,7 @@
104 connect(tag, &Tag::loadingChanged, this, &Tags::tagLoadingChanged);107 connect(tag, &Tag::loadingChanged, this, &Tags::tagLoadingChanged);
105 connect(tag, &Tag::syncedChanged, this, &Tags::syncedChanged);108 connect(tag, &Tag::syncedChanged, this, &Tags::syncedChanged);
106 connect(tag, &Tag::syncErrorChanged, this, &Tags::syncErrorChanged);109 connect(tag, &Tag::syncErrorChanged, this, &Tags::syncErrorChanged);
110 connect(tag, &Tag::deletedChanged, this, &Tags::deletedChanged);
107111
108 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());112 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
109 m_list.append(guid);113 m_list.append(guid);
@@ -128,6 +132,13 @@
128 }132 }
129}133}
130134
135void Tags::deletedChanged()
136{
137 Tag *tag = static_cast<Tag*>(sender());
138 int idx = m_list.indexOf(tag->guid());
139 emit dataChanged(index(idx), index(idx), QVector<int>() << RoleDeleted);
140}
141
131void Tags::nameChanged()142void Tags::nameChanged()
132{143{
133 Tag *tag = static_cast<Tag*>(sender());144 Tag *tag = static_cast<Tag*>(sender());
134145
=== modified file 'src/libqtevernote/tags.h'
--- src/libqtevernote/tags.h 2015-03-04 00:23:45 +0000
+++ src/libqtevernote/tags.h 2015-06-11 21:38:48 +0000
@@ -38,7 +38,8 @@
38 RoleNoteCount,38 RoleNoteCount,
39 RoleLoading,39 RoleLoading,
40 RoleSynced,40 RoleSynced,
41 RoleSyncError41 RoleSyncError,
42 RoleDeleted
42 };43 };
43 explicit Tags(QObject *parent = 0);44 explicit Tags(QObject *parent = 0);
4445
@@ -62,6 +63,7 @@
62 void tagAdded(const QString &guid);63 void tagAdded(const QString &guid);
63 void tagRemoved(const QString &guid);64 void tagRemoved(const QString &guid);
64 void tagGuidChanged(const QString &oldGuid, const QString &newGuid);65 void tagGuidChanged(const QString &oldGuid, const QString &newGuid);
66 void deletedChanged();
6567
66 void nameChanged();68 void nameChanged();
67 void noteCountChanged();69 void noteCountChanged();

Subscribers

People subscribed via source and target branches