diff --git a/qml/harbour-nextcloudnotes.qml b/qml/harbour-nextcloudnotes.qml index ee4613c..9aea9c0 100644 --- a/qml/harbour-nextcloudnotes.qml +++ b/qml/harbour-nextcloudnotes.qml @@ -58,7 +58,6 @@ ApplicationWindow account.path = "/apps/harbour-nextcloudnotes/accounts/" + currentAccount notesStore.account = currentAccount notesStore.getAllNotes() - notesApi.account = currentAccount notesApi.getAllNotes() } diff --git a/rpm/harbour-nextcloudnotes.changes b/rpm/harbour-nextcloudnotes.changes index 6a7975e..579387c 100644 --- a/rpm/harbour-nextcloudnotes.changes +++ b/rpm/harbour-nextcloudnotes.changes @@ -12,6 +12,9 @@ # * date Author's Name version-release # - Summary of changes +* Thu Apr 13 2020 Scharel Clemens 0.8-1 +- Updated Signals and Slots between the modules + * Mon Apr 13 2020 Scharel Clemens 0.8-0 - New methods for data handling improved diff --git a/rpm/harbour-nextcloudnotes.spec b/rpm/harbour-nextcloudnotes.spec index 8c047e2..d1aa964 100644 --- a/rpm/harbour-nextcloudnotes.spec +++ b/rpm/harbour-nextcloudnotes.spec @@ -14,7 +14,7 @@ Name: harbour-nextcloudnotes %{?qtc_builddir:%define _builddir %qtc_builddir} Summary: Nextcloud Notes Version: 0.8 -Release: 0 +Release: 1 Group: Applications/Editors License: MIT URL: https://github.com/scharel/harbour-nextcloudnotes diff --git a/rpm/harbour-nextcloudnotes.yaml b/rpm/harbour-nextcloudnotes.yaml index 91e02e5..d0db891 100644 --- a/rpm/harbour-nextcloudnotes.yaml +++ b/rpm/harbour-nextcloudnotes.yaml @@ -1,7 +1,7 @@ Name: harbour-nextcloudnotes Summary: Nextcloud Notes Version: 0.8 -Release: 0 +Release: 1 # The contents of the Group field should be one of the groups listed here: # https://github.com/mer-tools/spectacle/blob/master/data/GROUPS Group: Applications/Editors diff --git a/src/harbour-nextcloudnotes.cpp b/src/harbour-nextcloudnotes.cpp index e7707ff..7bccc3d 100644 --- a/src/harbour-nextcloudnotes.cpp +++ b/src/harbour-nextcloudnotes.cpp @@ -30,15 +30,17 @@ int main(int argc, char *argv[]) NotesStore* notesStore = new NotesStore; NotesApi* notesApi = new NotesApi; - QObject::connect(notesApi, SIGNAL(noteUpdated(int, QJsonObject)), notesStore, SLOT(updateNote(int, QJsonObject))); - //QObject::connect(notesStore, SIGNAL(noteUpdated(int, QJsonObject)), notesApi, SLOT(updateNote(int, QJsonObject))); - QObject::connect(notesApi, SIGNAL(noteDeleted(int)), notesStore, SLOT(deleteNote(int))); - //QObject::connect(notesStore, SIGNAL(noteDeleted(int)), notesApi, SLOT(deleteNote(int))); + //QObject::connect(notesApi, SIGNAL(allNotesReceived(QList)), notesModel, SLOT()); + QObject::connect(notesApi, SIGNAL(noteCreated(int,QJsonObject)), notesModel, SLOT(insertNote(int,QJsonObject))); + QObject::connect(notesApi, SIGNAL(noteUpdated(int,QJsonObject)), notesModel, SLOT(updateNote(int,QJsonObject))); + QObject::connect(notesApi, SIGNAL(noteDeleted(int)), notesModel, SLOT(removeNote(int))); - QObject::connect(notesStore, SIGNAL(noteUpdated(int, QJsonObject)), notesModel, SLOT(insertNote(int, QJsonObject))); + QObject::connect(notesApi, SIGNAL(noteCreated(int,QJsonObject)), notesStore, SLOT(insertNote(int,QJsonObject))); + QObject::connect(notesApi, SIGNAL(noteUpdated(int,QJsonObject)), notesStore, SLOT(updateNote(int,QJsonObject))); + QObject::connect(notesApi, SIGNAL(noteDeleted(int)), notesStore, SLOT(removeNote(int))); + + QObject::connect(notesStore, SIGNAL(noteUpdated(int,QJsonObject)), notesModel, SLOT(updateNote(int,QJsonObject))); QObject::connect(notesStore, SIGNAL(noteDeleted(int)), notesModel, SLOT(removeNote(int))); - //QObject::connect(notesApi, SIGNAL(noteUpdated(Note)), notesModel, SLOT(insertNote(Note))); - //QObject::connect(notesApi, SIGNAL(noteDeleted(int)), notesModel, SLOT(removeNote(int))); QQuickView* view = SailfishApp::createView(); #ifdef QT_DEBUG @@ -55,15 +57,6 @@ int main(int argc, char *argv[]) view->show(); int retval = app->exec(); - //QObject::disconnect(notesApi, SIGNAL(noteDeleted(int)), notesModel, SLOT(removeNote(int))); - //QObject::disconnect(notesApi, SIGNAL(noteUpdated(Note)), notesModel, SLOT(insertNote(Note))); - QObject::disconnect(notesStore, SIGNAL(noteDeleted(int)), notesModel, SLOT(removeNote(int))); - QObject::disconnect(notesStore, SIGNAL(noteUpdated(int, QJsonObject)), notesModel, SLOT(insertNote(int, QJsonObject))); - - //QObject::disconnect(notesStore, SIGNAL(noteDeleted(int)), notesApi, SLOT(deleteNote(int))); - QObject::disconnect(notesApi, SIGNAL(noteDeleted(int)), notesStore, SLOT(deleteNote(int))); - //QObject::disconnect(notesStore, SIGNAL(noteUpdated(Note)), notesApi, SLOT(updateNote(Note))); - QObject::disconnect(notesApi, SIGNAL(noteUpdated(int, QJsonObject)), notesStore, SLOT(updateNote(int, QJsonObject))); notesApi->deleteLater(); notesStore->deleteLater(); diff --git a/src/notesapi.cpp b/src/notesapi.cpp index 645a148..ba39b32 100644 --- a/src/notesapi.cpp +++ b/src/notesapi.cpp @@ -7,7 +7,7 @@ #include NotesApi::NotesApi(const QString statusEndpoint, const QString loginEndpoint, const QString ocsEndpoint, const QString notesEndpoint, QObject *parent) - : m_statusEndpoint(statusEndpoint), m_loginEndpoint(loginEndpoint), m_ocsEndpoint(ocsEndpoint), m_notesEndpoint(notesEndpoint) + : QObject(parent), m_statusEndpoint(statusEndpoint), m_loginEndpoint(loginEndpoint), m_ocsEndpoint(ocsEndpoint), m_notesEndpoint(notesEndpoint) { // TODO verify connections (also in destructor) m_loginPollTimer.setInterval(POLL_INTERVALL); @@ -42,7 +42,7 @@ NotesApi::~NotesApi() { disconnect(&m_manager, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(sslError(QNetworkReply*,QList))); } -void NotesApi::getAllNotes(const QStringList& exclude) { +bool NotesApi::getAllNotes(const QStringList& exclude) { qDebug() << "Getting all notes"; QUrl url = apiEndpointUrl(m_notesEndpoint); @@ -54,10 +54,12 @@ void NotesApi::getAllNotes(const QStringList& exclude) { m_authenticatedRequest.setUrl(url); m_getAllNotesReplies << m_manager.get(m_authenticatedRequest); emit busyChanged(true); + return true; } + return false; } -void NotesApi::getNote(const int id, const QStringList& exclude) { +bool NotesApi::getNote(const int id, const QStringList& exclude) { qDebug() << "Getting note: " << id; QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/%1").arg(id)); if (!exclude.isEmpty()) @@ -68,10 +70,12 @@ void NotesApi::getNote(const int id, const QStringList& exclude) { m_authenticatedRequest.setUrl(url); m_getNoteReplies << m_manager.get(m_authenticatedRequest); emit busyChanged(true); + return true; } + return false; } -void NotesApi::createNote(const QJsonObject& note) { +bool NotesApi::createNote(const QJsonObject& note) { qDebug() << "Creating note"; QUrl url = apiEndpointUrl(m_notesEndpoint); if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) { @@ -79,10 +83,12 @@ void NotesApi::createNote(const QJsonObject& note) { m_authenticatedRequest.setUrl(url); m_createNoteReplies << m_manager.post(m_authenticatedRequest, QJsonDocument(note).toJson()); emit busyChanged(true); + return true; } + return false; } -void NotesApi::updateNote(const int id, const QJsonObject& note) { +bool NotesApi::updateNote(const int id, const QJsonObject& note) { qDebug() << "Updating note: " << id; QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/%1").arg(id)); if (id >= 0 && url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) { @@ -90,10 +96,12 @@ void NotesApi::updateNote(const int id, const QJsonObject& note) { m_authenticatedRequest.setUrl(url); m_updateNoteReplies << m_manager.put(m_authenticatedRequest, QJsonDocument(note).toJson()); emit busyChanged(true); + return true; } + return false; } -void NotesApi::deleteNote(const int id) { +bool NotesApi::deleteNote(const int id) { qDebug() << "Deleting note: " << id; QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/%1").arg(id)); if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) { @@ -101,7 +109,9 @@ void NotesApi::deleteNote(const int id) { m_authenticatedRequest.setUrl(url); m_deleteNoteReplies << m_manager.deleteResource(m_authenticatedRequest); emit busyChanged(true); + return true; } + return false; } bool NotesApi::busy() const { @@ -356,8 +366,9 @@ void NotesApi::replyFinished(QNetworkReply *reply) { if (m_getAllNotesReplies.contains(reply)) { qDebug() << "Get all notes reply"; - if (reply->error() == QNetworkReply::NoError && json.isArray()) + if (reply->error() == QNetworkReply::NoError && json.isArray()) { updateApiNotes(json.array()); + } m_getAllNotesReplies.removeOne(reply); } else if (m_getNoteReplies.contains(reply)) { @@ -369,7 +380,7 @@ void NotesApi::replyFinished(QNetworkReply *reply) { else if (m_createNoteReplies.contains(reply)) { qDebug() << "Create note reply"; if (reply->error() == QNetworkReply::NoError && json.isObject()) - updateApiNote(json.object()); + createApiNote(json.object()); m_createNoteReplies.removeOne(reply); } else if (m_updateNoteReplies.contains(reply)) { @@ -576,10 +587,17 @@ void NotesApi::setLoginStatus(LoginStatus status, bool *changed) { } void NotesApi::updateApiNotes(const QJsonArray &json) { + QList ids; for (int i = 0; i < json.size(); ++i) { - if (json[i].isObject()) - updateApiNote(json[i].toObject()); + if (json[i].isObject()) { + QJsonObject object = json[i].toObject(); + if (!object.isEmpty()) { + updateApiNote(json[i].toObject()); + ids << object.value("id").toInt(-1); + } + } } + emit allNotesReceived(ids); } void NotesApi::updateApiNote(const QJsonObject &json) { @@ -587,3 +605,9 @@ void NotesApi::updateApiNote(const QJsonObject &json) { if (id >= 0) emit noteUpdated(id, json); } + +void NotesApi::createApiNote(const QJsonObject &json) { + int id = json["id"].toInt(-1); + if (id >= 0) + emit noteCreated(id, json); +} diff --git a/src/notesapi.h b/src/notesapi.h index 8f0b238..1f24390 100644 --- a/src/notesapi.h +++ b/src/notesapi.h @@ -21,9 +21,8 @@ class NotesApi : public QObject { Q_OBJECT - Q_PROPERTY(bool verifySsl READ verifySsl() WRITE setVerifySsl NOTIFY verifySslChanged) + Q_PROPERTY(bool verifySsl READ verifySsl WRITE setVerifySsl NOTIFY verifySslChanged) Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) - Q_PROPERTY(bool urlValid READ urlValid NOTIFY urlValidChanged) Q_PROPERTY(QString server READ server WRITE setServer NOTIFY serverChanged) Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged) Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged) @@ -31,6 +30,8 @@ class NotesApi : public QObject Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + + Q_PROPERTY(bool urlValid READ urlValid NOTIFY urlValidChanged) Q_PROPERTY(bool networkAccessible READ networkAccessible NOTIFY networkAccessibleChanged) Q_PROPERTY(QDateTime lastSync READ lastSync NOTIFY lastSyncChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) @@ -139,15 +140,11 @@ public: Q_INVOKABLE const QString errorMessage(int error) const; public slots: - Q_INVOKABLE void getAllNotes(const QStringList& exclude = QStringList()); - //void getAllNotes(Note::NoteField exclude); - Q_INVOKABLE void getNote(const int id, const QStringList& exclude = QStringList()); - //void getNote(const int id, Note::NoteField exclude); - Q_INVOKABLE void createNote(const QJsonObject& note); - //void createNote(const Note& note); - Q_INVOKABLE void updateNote(const int id, const QJsonObject& note); - //void updateNote(const Note& note); - Q_INVOKABLE void deleteNote(const int id); + Q_INVOKABLE bool getAllNotes(const QStringList& exclude = QStringList()); + Q_INVOKABLE bool getNote(const int id, const QStringList& exclude = QStringList()); + Q_INVOKABLE bool createNote(const QJsonObject& note); + Q_INVOKABLE bool updateNote(const int id, const QJsonObject& note); + Q_INVOKABLE bool deleteNote(const int id); signals: void verifySslChanged(bool verify); @@ -178,10 +175,11 @@ signals: void loginStatusChanged(LoginStatus status); void loginUrlChanged(QUrl url); + void allNotesReceived(const QList& ids); void noteCreated(const int id, const QJsonObject& note); void noteUpdated(const int id, const QJsonObject& note); void noteDeleted(const int id); - void noteError(ErrorCodes error); + void noteError(const ErrorCodes error); public slots: @@ -242,6 +240,7 @@ private: QVector m_deleteNoteReplies; void updateApiNotes(const QJsonArray& json); void updateApiNote(const QJsonObject& json); + void createApiNote(const QJsonObject& json); QDateTime m_lastSync; }; diff --git a/src/notesmodel.cpp b/src/notesmodel.cpp index 0662f86..f0a6c59 100644 --- a/src/notesmodel.cpp +++ b/src/notesmodel.cpp @@ -91,22 +91,28 @@ const QJsonObject NotesModel::getNote(const int id, const QStringList &exclude) return m_notes.value(id); } -void NotesModel::createNote(const int id, const QJsonObject ¬e) { - qDebug() << "New note, adding it"; - if (!m_notes.contains(id)) { - beginInsertRows(QModelIndex(), indexOfNoteById(id), indexOfNoteById(id)); - m_notes.insert(id, note); - emit noteUpdated(id, note); - endInsertRows(); +void NotesModel::insertNote(const int id, const QJsonObject& note) { + qDebug() << "Inserting note: " << id; + if (m_notes.contains(id)) { + qDebug() << "Note already present"; + updateNote(id, note); } else { - qDebug() << "Note already present"; + beginInsertRows(QModelIndex(), indexOfNoteById(id), indexOfNoteById(id)); + m_notes.insert(id, note); + endInsertRows(); + emit noteInserted(id, note); + qDebug() << "Note inserted"; } } -void NotesModel::updateNote(const int id, const QJsonObject& note) { +void NotesModel::updateNote(const int id, const QJsonObject ¬e) { qDebug() << "Updating note: " << id; - if (m_notes.contains(id)) { + if (!m_notes.contains(id)) { + qDebug() << "Note is new"; + insertNote(id, note); + } + else { if (m_notes.value(id) == note) { qDebug() << "Note unchanged"; } @@ -117,12 +123,9 @@ void NotesModel::updateNote(const int id, const QJsonObject& note) { qDebug() << "Note changed"; } } - else { - qDebug() << "Note not found"; - } } -void NotesModel::deleteNote(const int id) { +void NotesModel::removeNote(const int id) { qDebug() << "Removing note: " << id; if (m_notes.contains(id)) { beginRemoveRows(QModelIndex(), indexOfNoteById(id), indexOfNoteById(id)); @@ -130,7 +133,7 @@ void NotesModel::deleteNote(const int id) { qDebug() << "Note not found"; } else { - emit noteDeleted(id); + emit noteRemoved(id); } endRemoveRows(); } diff --git a/src/notesmodel.h b/src/notesmodel.h index 4088f6f..e053bd1 100644 --- a/src/notesmodel.h +++ b/src/notesmodel.h @@ -66,18 +66,18 @@ public: public slots: Q_INVOKABLE const QJsonArray getAllNotes(const QStringList& exclude = QStringList()); Q_INVOKABLE const QJsonObject getNote(const int id, const QStringList& exclude = QStringList()); - Q_INVOKABLE void createNote(const int id, const QJsonObject& note); + Q_INVOKABLE void insertNote(const int id, const QJsonObject& note); Q_INVOKABLE void updateNote(const int id, const QJsonObject& note); - Q_INVOKABLE void deleteNote(const int id); + Q_INVOKABLE void removeNote(const int id); Q_INVOKABLE void clear(); Q_INVOKABLE int indexOfNoteById(int id) const; signals: void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector ()); - void noteCreated(const int id, const QJsonObject& note); + void noteInserted(const int id, const QJsonObject& note); void noteUpdated(const int id, const QJsonObject& note); - void noteDeleted(const int id); + void noteRemoved(const int id); private: QMap m_notes; diff --git a/src/notesstore.cpp b/src/notesstore.cpp index 866beff..fddd8a4 100644 --- a/src/notesstore.cpp +++ b/src/notesstore.cpp @@ -6,7 +6,7 @@ const QString NotesStore::m_suffix = "json"; -NotesStore::NotesStore(QString directory, QObject *parent) +NotesStore::NotesStore(QString directory, QObject *parent) : QObject(parent) { m_dir.setCurrent(directory); m_dir.setPath(""); @@ -101,15 +101,15 @@ const QJsonObject NotesStore::getNote(const int id, const QStringList& exclude) QJsonObject note; if (id >= 0) { note = readNoteFile(id, exclude); + emit noteUpdated(id, note); } else { qDebug() << "Skipping, invalid ID"; } return note; } - -bool NotesStore::createNote(const QJsonObject& note) { - int id = note.value("id").toInt(-1); +/* +bool NotesStore::createNote(const int id, const QJsonObject& note) { qDebug() << "Creating note: " << id; if (id < 0) { // TODO probably crate files with an '.json..new' extension @@ -126,8 +126,8 @@ bool NotesStore::createNote(const QJsonObject& note) { } return false; } - -const QJsonObject NotesStore::updateNote(const int id, const QJsonObject& note) { +*/ +bool NotesStore::updateNote(const int id, const QJsonObject& note) { qDebug() << "Updating note: " << id; if (id >= 0) { QJsonObject tmpNote = readNoteFile(id); @@ -142,6 +142,7 @@ const QJsonObject NotesStore::updateNote(const int id, const QJsonObject& note) } if (writeNoteFile(id, tmpNote)) { emit noteUpdated(id, tmpNote); + return true; } } else { @@ -155,13 +156,16 @@ const QJsonObject NotesStore::updateNote(const int id, const QJsonObject& note) else { qDebug() << "Skipping, invalid ID"; } + return false; } bool NotesStore::deleteNote(const int id) { qDebug() << "Deleting note: " << id; if (removeNoteFile(id)) { emit noteDeleted(id); + return true; } + return false; } bool NotesStore::noteFileExists(const int id) const { diff --git a/src/notesstore.h b/src/notesstore.h index 14187e1..3443488 100644 --- a/src/notesstore.h +++ b/src/notesstore.h @@ -17,6 +17,8 @@ public: QObject *parent = nullptr); virtual ~NotesStore(); + Q_PROPERTY(QString account READ account WRITE setAccount NOTIFY accountChanged) + QString account() const; void setAccount(const QString& account); @@ -35,13 +37,13 @@ public: public slots: Q_INVOKABLE const QJsonArray getAllNotes(const QStringList& exclude = QStringList()); Q_INVOKABLE const QJsonObject getNote(const int id, const QStringList& exclude = QStringList()); - Q_INVOKABLE bool createNote(const QJsonObject& note); - Q_INVOKABLE const QJsonObject updateNote(const int id, const QJsonObject& note); + //Q_INVOKABLE bool createNote(const int id, const QJsonObject& note); + Q_INVOKABLE bool updateNote(const int id, const QJsonObject& note); Q_INVOKABLE bool deleteNote(const int id); signals: void accountChanged(const QString& account); - void noteCreated(const int id, const QJsonObject& note); + //void noteCreated(const int id, const QJsonObject& note); void noteUpdated(const int id, const QJsonObject& note); void noteDeleted(const int id); void noteError(const ErrorCodes error); diff --git a/translations/harbour-nextcloudnotes.ts b/translations/harbour-nextcloudnotes.ts index d7d80d7..9d89be7 100644 --- a/translations/harbour-nextcloudnotes.ts +++ b/translations/harbour-nextcloudnotes.ts @@ -311,32 +311,32 @@ NotesApi - + No error - + No network connection available - + Failed to communicate with the Nextcloud server - + An error occured while establishing an encrypted connection - + Could not authenticate to the Nextcloud instance - + Unknown error @@ -878,27 +878,27 @@ You can also use other markdown syntax inside them. harbour-nextcloudnotes - + Notes - + Offline - + Synced - + API error - + File error