Implementing new methods for data handling (files and API targets)

This commit is contained in:
Scharel Clemens 2020-04-05 22:59:18 +02:00
parent ffffd306d6
commit 60e1eb0bdd
16 changed files with 334 additions and 65 deletions

View file

@ -18,12 +18,15 @@ DEFINES += APP_VERSION=\\\"$$VERSION\\\"
HEADERS += src/note.h \ HEADERS += src/note.h \
src/notesapi.h \ src/notesapi.h \
src/notesmodel.h src/notesinterface.h \
src/notesmodel.h \
src/notesstore.h
SOURCES += src/harbour-nextcloudnotes.cpp \ SOURCES += src/harbour-nextcloudnotes.cpp \
src/note.cpp \ src/note.cpp \
src/notesapi.cpp \ src/notesapi.cpp \
src/notesmodel.cpp src/notesmodel.cpp \
src/notesstore.cpp
DISTFILES += qml/harbour-nextcloudnotes.qml \ DISTFILES += qml/harbour-nextcloudnotes.qml \
qml/cover/CoverPage.qml \ qml/cover/CoverPage.qml \

View file

@ -2,7 +2,10 @@ import QtQuick 2.2
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import Nemo.Configuration 1.0 import Nemo.Configuration 1.0
import Nemo.Notifications 1.0 import Nemo.Notifications 1.0
import harbour.nextcloudnotes.note 1.0
import harbour.nextcloudnotes.notesstore 1.0
import harbour.nextcloudnotes.notesapi 1.0 import harbour.nextcloudnotes.notesapi 1.0
import harbour.nextcloudnotes.notesmodel 1.0
import "pages" import "pages"
ApplicationWindow ApplicationWindow
@ -33,7 +36,10 @@ ApplicationWindow
onUsernameChanged: notesApi.username = username onUsernameChanged: notesApi.username = username
onPasswordChanged: notesApi.password = password onPasswordChanged: notesApi.password = password
onDoNotVerifySslChanged: notesApi.sslVerify = !doNotVerifySsl onDoNotVerifySslChanged: notesApi.sslVerify = !doNotVerifySsl
onPathChanged: notesApi.dataFile = appSettings.currentAccount !== "" ? StandardPaths.data + "/" + appSettings.currentAccount + ".json" : "" onPathChanged: {
notesStore.account = appSettings.currentAccount
notesApi.dataFile = appSettings.currentAccount !== "" ? StandardPaths.data + "/" + appSettings.currentAccount + ".json" : ""
}
} }
// General settings of the app // General settings of the app
@ -121,6 +127,7 @@ ApplicationWindow
running: interval > 0 && notesApi.networkAccessible && appWindow.visible running: interval > 0 && notesApi.networkAccessible && appWindow.visible
triggeredOnStart: true triggeredOnStart: true
onTriggered: { onTriggered: {
notesStore.getAllNotes()
if (!notesApi.busy) { if (!notesApi.busy) {
notesApi.getAllNotes(); notesApi.getAllNotes();
} }
@ -135,6 +142,26 @@ ApplicationWindow
} }
} }
NotesStore {
id: notesStore
Component.onCompleted: getAllNotes()
onAccountChanged: {
console.log(account)
if (account !== "")
getAllNotes()
}
onNoteCreated: {
//console.log("Note created", createdNote.id)
}
onNoteUpdated: {
//console.log("Note updated", updatedNote.id)
}
onNoteDeleted: {
//console.log("Note deleted", deletedNoteId)
}
}
NotesApi { NotesApi {
id: notesApi id: notesApi
@ -143,7 +170,8 @@ ApplicationWindow
networkAccessible ? offlineNotification.close(Notification.Closed) : offlineNotification.publish() networkAccessible ? offlineNotification.close(Notification.Closed) : offlineNotification.publish()
} }
onError: { onError: {
console.log("Error (" + error + "): " + errorMessage(error)) if (error)
console.log("Error (" + error + "): " + errorMessage(error))
errorNotification.close() errorNotification.close()
if (error && networkAccessible) { if (error && networkAccessible) {
errorNotification.body = errorMessage(error) errorNotification.body = errorMessage(error)

View file

@ -12,6 +12,9 @@
# * date Author's Name <author's email> version-release # * date Author's Name <author's email> version-release
# - Summary of changes # - Summary of changes
* Sun Apr 05 2020 Scharel Clemens <harbour-nextcloudnotes@scharel.rocks> 0.6-1
- Implementing new methods for data handling (files and API targets)
* Sun Mar 29 2020 Scharel Clemens <harbour-nextcloudnotes@scharel.rocks> 0.6-0 * Sun Mar 29 2020 Scharel Clemens <harbour-nextcloudnotes@scharel.rocks> 0.6-0
- Improved changes of 0.5 - Improved changes of 0.5

View file

@ -14,7 +14,7 @@ Name: harbour-nextcloudnotes
%{?qtc_builddir:%define _builddir %qtc_builddir} %{?qtc_builddir:%define _builddir %qtc_builddir}
Summary: Nextcloud Notes Summary: Nextcloud Notes
Version: 0.6 Version: 0.6
Release: 0 Release: 1
Group: Applications/Editors Group: Applications/Editors
License: MIT License: MIT
URL: https://github.com/scharel/harbour-nextcloudnotes URL: https://github.com/scharel/harbour-nextcloudnotes

View file

@ -1,7 +1,7 @@
Name: harbour-nextcloudnotes Name: harbour-nextcloudnotes
Summary: Nextcloud Notes Summary: Nextcloud Notes
Version: 0.6 Version: 0.6
Release: 0 Release: 1
# The contents of the Group field should be one of the groups listed here: # The contents of the Group field should be one of the groups listed here:
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS # https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
Group: Applications/Editors Group: Applications/Editors

View file

@ -2,8 +2,9 @@
#include <sailfishapp.h> #include <sailfishapp.h>
#include <QtQml> #include <QtQml>
#include <QObject> #include <QObject>
#include "notesapi.h"
#include "note.h" #include "note.h"
#include "notesapi.h"
#include "notesstore.h"
#include "notesmodel.h" #include "notesmodel.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -17,13 +18,13 @@ int main(int argc, char *argv[])
qDebug() << app->applicationDisplayName() << app->applicationVersion(); qDebug() << app->applicationDisplayName() << app->applicationVersion();
qRegisterMetaType<Note>();
qmlRegisterType<Note>("harbour.nextcloudnotes.note", 1, 0, "Note");
qmlRegisterType<NotesApi>("harbour.nextcloudnotes.notesapi", 1, 0, "NotesApi"); qmlRegisterType<NotesApi>("harbour.nextcloudnotes.notesapi", 1, 0, "NotesApi");
qmlRegisterType<NotesStore>("harbour.nextcloudnotes.notesstore", 1, 0, "NotesStore");
qmlRegisterType<NotesProxyModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel"); qmlRegisterType<NotesProxyModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel");
NotesApi notesApi;
QQuickView* view = SailfishApp::createView(); QQuickView* view = SailfishApp::createView();
//view->engine()->rootContext()->setContextProperty("notesApi", &notesApi);
//view->engine()->rootContext()->setContextProperty("notesModel", notesApi.model());
view->setSource(SailfishApp::pathTo("qml/harbour-nextcloudnotes.qml")); view->setSource(SailfishApp::pathTo("qml/harbour-nextcloudnotes.qml"));
#ifdef QT_DEBUG #ifdef QT_DEBUG

View file

@ -4,6 +4,10 @@ Note::Note(QObject *parent) : QObject(parent) {
connectSignals(); connectSignals();
} }
Note::~Note() {
//qDebug() << "Note destroyed: " << id();
}
Note::Note(const Note& note, QObject *parent) : QObject(parent) { Note::Note(const Note& note, QObject *parent) : QObject(parent) {
setId(note.id()); setId(note.id());
setModified(note.modified()); setModified(note.modified());
@ -111,26 +115,26 @@ QJsonDocument Note::toJsonDocument() const {
return QJsonDocument(m_json); return QJsonDocument(m_json);
} }
double Note::id() const { int Note::id() const {
return m_json.value(ID).toDouble(-1); return m_json.value(ID).toInt(-1);
} }
double Note::id(const QJsonObject &jobj) { int Note::id(const QJsonObject &jobj) {
return jobj.value(ID).toDouble(-1); return jobj.value(ID).toInt(-1);
} }
void Note::setId(double id) { void Note::setId(int id) {
if (id != this->id()) { if (id != this->id()) {
m_json.insert(ID, QJsonValue(id)); m_json.insert(ID, QJsonValue(id));
emit idChanged(this->id()); emit idChanged(this->id());
} }
} }
double Note::modified() const { int Note::modified() const {
return m_json.value(MODIFIED).toDouble(); return m_json.value(MODIFIED).toInt();
} }
double Note::modified(const QJsonObject &jobj) { int Note::modified(const QJsonObject &jobj) {
return jobj.value(MODIFIED).toDouble(); return jobj.value(MODIFIED).toInt();
} }
void Note::setModified(double modified) { void Note::setModified(int modified) {
if (modified != this->modified()){ if (modified != this->modified()){
m_json.insert(MODIFIED, QJsonValue(modified)); m_json.insert(MODIFIED, QJsonValue(modified));
emit modifiedChanged(this->modified()); emit modifiedChanged(this->modified());
@ -260,8 +264,8 @@ QDateTime Note::modifiedDateTime(const QJsonObject &jobj) {
} }
void Note::connectSignals() { void Note::connectSignals() {
connect(this, SIGNAL(idChanged(double)), this, SIGNAL(noteChanged())); connect(this, SIGNAL(idChanged(int)), this, SIGNAL(noteChanged()));
connect(this, SIGNAL(modifiedChanged(double)), this, SIGNAL(noteChanged())); connect(this, SIGNAL(modifiedChanged(int)), this, SIGNAL(noteChanged()));
connect(this, SIGNAL(titleChanged(QString)), this, SIGNAL(noteChanged())); connect(this, SIGNAL(titleChanged(QString)), this, SIGNAL(noteChanged()));
connect(this, SIGNAL(categoryChanged(QString)), this, SIGNAL(noteChanged())); connect(this, SIGNAL(categoryChanged(QString)), this, SIGNAL(noteChanged()));
connect(this, SIGNAL(contentChanged(QString)), this, SIGNAL(noteChanged())); connect(this, SIGNAL(contentChanged(QString)), this, SIGNAL(noteChanged()));

View file

@ -24,6 +24,7 @@ public:
Note(QObject *parent = NULL); Note(QObject *parent = NULL);
Note(const Note& note, QObject *parent = NULL); Note(const Note& note, QObject *parent = NULL);
Note(const QJsonObject& note, QObject *parent = NULL); Note(const QJsonObject& note, QObject *parent = NULL);
~Note();
Note& operator =(const Note& note); Note& operator =(const Note& note);
Note& operator =(const QJsonObject& note); Note& operator =(const QJsonObject& note);
@ -40,49 +41,49 @@ public:
QJsonValue toJsonValue() const; QJsonValue toJsonValue() const;
QJsonDocument toJsonDocument() const; QJsonDocument toJsonDocument() const;
Q_PROPERTY(double id READ id WRITE setId NOTIFY idChanged) Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
double id() const; Q_INVOKABLE int id() const;
void setId(double id); void setId(int id);
Q_PROPERTY(double modified READ modified WRITE setModified NOTIFY modifiedChanged) Q_PROPERTY(int modified READ modified WRITE setModified NOTIFY modifiedChanged)
double modified() const; Q_INVOKABLE int modified() const;
void setModified(double modified); void setModified(int modified);
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
QString title() const; Q_INVOKABLE QString title() const;
void setTitle(QString title); void setTitle(QString title);
Q_PROPERTY(QString category READ category WRITE setCategory NOTIFY categoryChanged) Q_PROPERTY(QString category READ category WRITE setCategory NOTIFY categoryChanged)
QString category() const; Q_INVOKABLE QString category() const;
void setCategory(QString category); void setCategory(QString category);
Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged) Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)
QString content() const; Q_INVOKABLE QString content() const;
void setContent(QString content); void setContent(QString content);
Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged) Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
bool favorite() const; Q_INVOKABLE bool favorite() const;
void setFavorite(bool favorite); void setFavorite(bool favorite);
Q_PROPERTY(QString etag READ etag WRITE setEtag NOTIFY etagChanged) Q_PROPERTY(QString etag READ etag WRITE setEtag NOTIFY etagChanged)
QString etag() const; Q_INVOKABLE QString etag() const;
void setEtag(QString etag); void setEtag(QString etag);
Q_PROPERTY(bool error READ error WRITE setError NOTIFY errorChanged) Q_PROPERTY(bool error READ error WRITE setError NOTIFY errorChanged)
bool error() const; Q_INVOKABLE bool error() const;
void setError(bool error); void setError(bool error);
Q_PROPERTY(QString errorMessage READ errorMessage WRITE setErrorMessage NOTIFY errorMessageChanged) Q_PROPERTY(QString errorMessage READ errorMessage WRITE setErrorMessage NOTIFY errorMessageChanged)
QString errorMessage() const; Q_INVOKABLE QString errorMessage() const;
void setErrorMessage(QString errorMessage); void setErrorMessage(QString errorMessage);
Q_PROPERTY(QString modifiedString READ modifiedString NOTIFY modifiedStringChanged) Q_PROPERTY(QString modifiedString READ modifiedString NOTIFY modifiedStringChanged)
QString modifiedString() const; Q_INVOKABLE QString modifiedString() const;
QDateTime modifiedDateTime() const; Q_INVOKABLE QDateTime modifiedDateTime() const;
static double id(const QJsonObject& jobj); static int id(const QJsonObject& jobj);
static double modified(const QJsonObject& jobj); static int modified(const QJsonObject& jobj);
static QString title(const QJsonObject& jobj); static QString title(const QJsonObject& jobj);
static QString category(const QJsonObject& jobj); static QString category(const QJsonObject& jobj);
static QString content(const QJsonObject& jobj); static QString content(const QJsonObject& jobj);
@ -94,8 +95,8 @@ public:
static QDateTime modifiedDateTime(const QJsonObject& jobj); static QDateTime modifiedDateTime(const QJsonObject& jobj);
signals: signals:
void idChanged(double id); void idChanged(int id);
void modifiedChanged(double modified); void modifiedChanged(int modified);
void titleChanged(QString title); void titleChanged(QString title);
void categoryChanged(QString category); void categoryChanged(QString category);
void contentChanged(QString content); void contentChanged(QString content);
@ -113,4 +114,6 @@ private:
void connectSignals(); void connectSignals();
}; };
Q_DECLARE_METATYPE(Note)
#endif // NOTE_H #endif // NOTE_H

View file

@ -261,7 +261,7 @@ void NotesApi::getAllNotes(QStringList excludeFields) {
} }
} }
void NotesApi::getNote(double noteId, QStringList excludeFields) { void NotesApi::getNote(int noteId, QStringList excludeFields) {
QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/notes/%1").arg(noteId)); QUrl url = apiEndpointUrl(m_notesEndpoint + QString("/notes/%1").arg(noteId));
if (!excludeFields.isEmpty()) if (!excludeFields.isEmpty())
url.setQuery(QString("exclude=").append(excludeFields.join(","))); url.setQuery(QString("exclude=").append(excludeFields.join(",")));
@ -288,7 +288,7 @@ void NotesApi::createNote(QVariantMap fields) {
} }
} }
void NotesApi::updateNote(double noteId, QVariantMap fields) { void NotesApi::updateNote(int noteId, QVariantMap fields) {
// Update note in the model // Update note in the model
Note note(QJsonObject::fromVariantMap(fields)); Note note(QJsonObject::fromVariantMap(fields));
mp_model->insertNote(note); mp_model->insertNote(note);
@ -303,7 +303,7 @@ void NotesApi::updateNote(double noteId, QVariantMap fields) {
} }
} }
void NotesApi::deleteNote(double noteId) { void NotesApi::deleteNote(int noteId) {
// Remove note from the model // Remove note from the model
mp_model->removeNote(noteId); mp_model->removeNote(noteId);
@ -350,9 +350,6 @@ const QString NotesApi::errorMessage(ErrorCodes error) const {
void NotesApi::verifyUrl(QUrl url) { void NotesApi::verifyUrl(QUrl url) {
emit urlValidChanged(url.isValid()); emit urlValidChanged(url.isValid());
if (m_url.isValid() && !m_url.scheme().isEmpty() && !m_url.host().isEmpty()) {
getNcStatus();
}
} }
void NotesApi::requireAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) { void NotesApi::requireAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {

View file

@ -53,7 +53,7 @@ public:
const QString loginEndpoint = LOGIN_ENDPOINT, const QString loginEndpoint = LOGIN_ENDPOINT,
const QString ocsEndpoint = OCS_ENDPOINT, const QString ocsEndpoint = OCS_ENDPOINT,
const QString notesEndpoint = NOTES_ENDPOINT, const QString notesEndpoint = NOTES_ENDPOINT,
QObject *parent = NULL); QObject *parent = nullptr);
virtual ~NotesApi(); virtual ~NotesApi();
bool sslVerify() const { return m_authenticatedRequest.sslConfiguration().peerVerifyMode() == QSslSocket::VerifyPeer; } bool sslVerify() const { return m_authenticatedRequest.sslConfiguration().peerVerifyMode() == QSslSocket::VerifyPeer; }
@ -131,10 +131,10 @@ public:
Q_INVOKABLE void abortFlowV2Login(); Q_INVOKABLE void abortFlowV2Login();
Q_INVOKABLE void verifyLogin(QString username = QString(), QString password = QString()); Q_INVOKABLE void verifyLogin(QString username = QString(), QString password = QString());
Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList()); Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList());
Q_INVOKABLE void getNote(double noteId, QStringList excludeFields = QStringList()); Q_INVOKABLE void getNote(int noteId, QStringList excludeFields = QStringList());
Q_INVOKABLE void createNote(QVariantMap fields = QVariantMap()); Q_INVOKABLE void createNote(QVariantMap fields = QVariantMap());
Q_INVOKABLE void updateNote(double noteId, QVariantMap fields = QVariantMap()); Q_INVOKABLE void updateNote(int noteId, QVariantMap fields = QVariantMap());
Q_INVOKABLE void deleteNote(double noteId); Q_INVOKABLE void deleteNote(int noteId);
Q_INVOKABLE NotesProxyModel* model() const { return mp_modelProxy; } Q_INVOKABLE NotesProxyModel* model() const { return mp_modelProxy; }
enum ErrorCodes { enum ErrorCodes {

43
src/notesinterface.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef NOTESINTERFACE_H
#define NOTESINTERFACE_H
#include <QObject>
#include <QVector>
#include "note.h"
class NotesInterface : public QObject
{
Q_OBJECT
Q_PROPERTY(QString account READ account WRITE setAccount NOTIFY accountChanged)
Q_CLASSINFO("author", "Scharel Clemens")
Q_CLASSINFO("url", "https://github.com/scharel/harbour-nextcloudnotes")
public:
explicit NotesInterface(QObject *parent = nullptr) : QObject(parent) {
}
virtual QString account() const = 0;
virtual void setAccount(const QString& account) = 0;
Q_INVOKABLE virtual void getAllNotes() = 0;
Q_INVOKABLE virtual void getNote(const int id) = 0;
Q_INVOKABLE virtual void getNote(const Note& note) = 0;
Q_INVOKABLE virtual void createNote(const Note& note) = 0;
Q_INVOKABLE virtual void updateNote(const Note& note) = 0;
Q_INVOKABLE virtual void deleteNote(const int id) = 0;
Q_INVOKABLE virtual void deleteNote(const Note& note) = 0;
Q_INVOKABLE virtual Note* noteData(const int id) = 0;
Q_INVOKABLE virtual Note* noteData(const Note& note) = 0;
signals:
void accountChanged(const QString& account);
void noteCreated(Note* createdNote);
void noteUpdated(Note* updatedNote);
void noteDeleted(int deletedNoteId);
public slots:
};
#endif // NOTESINTERFACE_H

View file

@ -55,7 +55,7 @@ bool NotesModel::fromJsonDocument(const QJsonDocument &jdoc) {
if (!jdoc.isNull() && !jdoc.isEmpty()) { if (!jdoc.isNull() && !jdoc.isEmpty()) {
if (jdoc.isArray()) { if (jdoc.isArray()) {
//qDebug() << "- It's an array..."; //qDebug() << "- It's an array...";
QVector<double> notesIdsToRemove; QVector<int> notesIdsToRemove;
QJsonArray jarr = jdoc.array(); QJsonArray jarr = jdoc.array();
if (!jarr.empty()) if (!jarr.empty())
notesIdsToRemove = ids(); notesIdsToRemove = ids();
@ -104,8 +104,8 @@ QJsonDocument NotesModel::toJsonDocument() const {
return QJsonDocument(jarr); return QJsonDocument(jarr);
} }
QVector<double> NotesModel::ids() const { QVector<int> NotesModel::ids() const {
QVector<double> ids; QVector<int> ids;
for (int i = 0; i < m_notes.size(); ++i) { for (int i = 0; i < m_notes.size(); ++i) {
ids.append(m_notes[i].id()); ids.append(m_notes[i].id());
} }
@ -149,7 +149,7 @@ bool NotesModel::removeNote(const Note &note) {
return false; return false;
} }
bool NotesModel::removeNote(double id) { bool NotesModel::removeNote(int id) {
return removeNote(Note(QJsonObject{ {"id", id} } )); return removeNote(Note(QJsonObject{ {"id", id} } ));
} }
@ -202,7 +202,7 @@ bool NotesModel::setData(const QModelIndex &index, const QVariant &value, int ro
if (index.isValid()) { if (index.isValid()) {
switch (role) { switch (role) {
case IdRole: { case IdRole: {
double id = value.toDouble(&retval); double id = value.toInt(&retval);
if (retval && id != m_notes[index.row()].id()) { if (retval && id != m_notes[index.row()].id()) {
m_notes[index.row()].setId(id); m_notes[index.row()].setId(id);
emit dataChanged(index, index, QVector<int>{ IdRole }); emit dataChanged(index, index, QVector<int>{ IdRole });
@ -210,7 +210,7 @@ bool NotesModel::setData(const QModelIndex &index, const QVariant &value, int ro
break; break;
} }
case ModifiedRole: { case ModifiedRole: {
double modified = value.toDouble(&retval); double modified = value.toInt(&retval);
if (retval && modified != m_notes[index.row()].modified()) { if (retval && modified != m_notes[index.row()].modified()) {
m_notes[index.row()].setModified(modified); m_notes[index.row()].setModified(modified);
emit dataChanged(index, index, QVector<int>{ ModifiedRole }); emit dataChanged(index, index, QVector<int>{ ModifiedRole });

View file

@ -43,7 +43,7 @@ public:
int insertNote(const Note &note); int insertNote(const Note &note);
bool removeNote(const Note &note); bool removeNote(const Note &note);
bool removeNote(double id); bool removeNote(int id);
enum NoteRoles { enum NoteRoles {
IdRole = Qt::UserRole, IdRole = Qt::UserRole,
@ -69,7 +69,7 @@ public:
protected: protected:
//void addNote(const QJsonValue &note); //void addNote(const QJsonValue &note);
QVector<double> ids() const; QVector<int> ids() const;
//int indexOf(const Note &note) const; //int indexOf(const Note &note) const;
//int indexOf(int id) const; //int indexOf(int id) const;
//bool replaceNote(const Note &note); //bool replaceNote(const Note &note);

147
src/notesstore.cpp Normal file
View file

@ -0,0 +1,147 @@
#include "notesstore.h"
#include <QDebug>
NotesStore::NotesStore(QString directory, QObject *parent) : NotesInterface(parent)
{
m_dir.setCurrent(directory);
m_dir.setPath("");
m_dir.setFilter(QDir::Files);
m_dir.setNameFilters( { "*.json" } );
m_note = nullptr;
}
NotesStore::~NotesStore() {
if (m_note)
m_note->deleteLater();
m_note = nullptr;
}
QString NotesStore::account() const {
QString dir;
if (m_dir != QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation))) {
dir = m_dir.dirName();
}
return dir;
}
void NotesStore::setAccount(const QString& account) {
//qDebug() << account << m_dir.path();
if (account != m_dir.path()) {
if (m_dir != QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation))) {
m_dir.cdUp();
}
if (!account.isEmpty()) {
m_dir.setPath(account);
if (!m_dir.mkpath(".")) {
qDebug() << "Failed to create or already present: " << m_dir.path();
}
}
//qDebug() << account << m_dir.path();
emit accountChanged(m_dir.path());
}
}
void NotesStore::getAllNotes() {
QFileInfoList files = m_dir.entryInfoList();
for (int i = 0; i < files.size(); ++i) {
bool ok;
int id = files[i].baseName().toInt(&ok);
if (ok) {
getNote(id);
}
}
}
void NotesStore::getNote(const int id) {
QFileInfo file(m_dir, QString("%1.json").arg(id));
if (file.exists()) {
emit noteUpdated(noteData(id));
}
}
void NotesStore::getNote(const Note& note) {
getNote(note.id());
}
void NotesStore::createNote(const Note& note) {
if (note.id() < 0) {
// TODO probably crate files with an '.json.<NUMBER>.new' extension
qDebug() << "Creating notes without the server API is not supported yet!";
}
else {
updateNote(note);
}
}
void NotesStore::updateNote(const Note& note) {
if (note.id() >= 0) {
QFileInfo fileinfo(m_dir, QString("%1.json").arg(note.id()));
QFile file(fileinfo.filePath());
if (file.exists()) {
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QJsonDocument fileJson = QJsonDocument::fromBinaryData(file.readAll());
file.close();
if (!note.equal(fileJson.object())) {
if (file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) {
QByteArray data = note.toJsonDocument().toJson();
if (file.write(data) == data.size()) {
emit noteUpdated(noteData(note));
}
}
}
file.close();
}
}
else {
if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {
QByteArray data = note.toJsonDocument().toJson();
if (file.write(data) == data.size()) {
emit noteCreated(noteData(note));
}
file.close();
}
}
}
else {
createNote(note);
}
}
void NotesStore::deleteNote(const int id) {
QFileInfo fileinfo(m_dir, QString("%1.json").arg(id));
if (fileinfo.exists()) {
QFile file(fileinfo.filePath());
if (file.remove()) {
emit noteDeleted(id);
if (m_note)
m_note->deleteLater();
m_note = nullptr;
}
}
}
void NotesStore::deleteNote(const Note& note) {
deleteNote(note.id());
}
Note* NotesStore::noteData(const int id) {
if (m_note)
m_note->deleteLater();
m_note = nullptr;
QFileInfo fileinfo(m_dir, QString("%1.json").arg(id));
QFile file(fileinfo.filePath());
if (file.exists()) {
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray data = file.readAll();
QJsonDocument json = QJsonDocument::fromJson(data);
m_note = new Note(json.object());
file.close();
}
}
return m_note;
}
Note* NotesStore::noteData(const Note& note) {
return noteData(note.id());
}

40
src/notesstore.h Normal file
View file

@ -0,0 +1,40 @@
#ifndef NOTESSTORE_H
#define NOTESSTORE_H
#include "notesinterface.h"
#include <QObject>
#include <QStandardPaths>
#include <QDir>
class NotesStore : public NotesInterface
{
Q_OBJECT
public:
explicit NotesStore(
QString directory = QStandardPaths::writableLocation(QStandardPaths::DataLocation),
QObject *parent = nullptr);
virtual ~NotesStore();
QString account() const;
void setAccount(const QString& account);
signals:
public slots:
Q_INVOKABLE void getAllNotes();
Q_INVOKABLE void getNote(const int id);
Q_INVOKABLE void getNote(const Note& note);
Q_INVOKABLE void createNote(const Note& note);
Q_INVOKABLE void updateNote(const Note& note);
Q_INVOKABLE void deleteNote(const int id);
Q_INVOKABLE void deleteNote(const Note& note);
Q_INVOKABLE Note* noteData(const int id);
Q_INVOKABLE Note* noteData(const Note& note);
private:
QDir m_dir;
Note* m_note;
};
#endif // NOTESSTORE_H

View file

@ -245,12 +245,12 @@
<context> <context>
<name>Note</name> <name>Note</name>
<message> <message>
<location filename="../src/note.cpp" line="241"/> <location filename="../src/note.cpp" line="245"/>
<source>Today</source> <source>Today</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/note.cpp" line="243"/> <location filename="../src/note.cpp" line="247"/>
<source>Yesterday</source> <source>Yesterday</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -840,22 +840,22 @@ You can also use other markdown syntax inside them.</source>
<context> <context>
<name>harbour-nextcloudnotes</name> <name>harbour-nextcloudnotes</name>
<message> <message>
<location filename="../qml/harbour-nextcloudnotes.qml" line="104"/> <location filename="../qml/harbour-nextcloudnotes.qml" line="110"/>
<source>Notes</source> <source>Notes</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/harbour-nextcloudnotes.qml" line="105"/> <location filename="../qml/harbour-nextcloudnotes.qml" line="111"/>
<source>Offline</source> <source>Offline</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/harbour-nextcloudnotes.qml" line="106"/> <location filename="../qml/harbour-nextcloudnotes.qml" line="112"/>
<source>Synced</source> <source>Synced</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/harbour-nextcloudnotes.qml" line="113"/> <location filename="../qml/harbour-nextcloudnotes.qml" line="119"/>
<source>Error</source> <source>Error</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>