Began implementing the data model in C++
This commit is contained in:
parent
03098b7354
commit
86a3755ad2
11 changed files with 581 additions and 75 deletions
|
@ -1,58 +1,60 @@
|
||||||
# NOTICE:
|
# NOTICE:
|
||||||
#
|
#
|
||||||
# Application name defined in TARGET has a corresponding QML filename.
|
# Application name defined in TARGET has a corresponding QML filename.
|
||||||
# If name defined in TARGET is changed, the following needs to be done
|
# If name defined in TARGET is changed, the following needs to be done
|
||||||
# to match new name:
|
# to match new name:
|
||||||
# - corresponding QML filename must be changed
|
# - corresponding QML filename must be changed
|
||||||
# - desktop icon filename must be changed
|
# - desktop icon filename must be changed
|
||||||
# - desktop filename must be changed
|
# - desktop filename must be changed
|
||||||
# - icon definition filename in desktop file must be changed
|
# - icon definition filename in desktop file must be changed
|
||||||
# - translation filenames have to be changed
|
# - translation filenames have to be changed
|
||||||
|
|
||||||
# The name of your application
|
# The name of your application
|
||||||
TARGET = harbour-nextcloudnotes
|
TARGET = harbour-nextcloudnotes
|
||||||
|
|
||||||
CONFIG += sailfishapp
|
CONFIG += sailfishapp
|
||||||
|
|
||||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/sslconfiguration.h
|
src/sslconfiguration.h \
|
||||||
|
src/notesmodel.h
|
||||||
SOURCES += src/harbour-nextcloudnotes.cpp \
|
|
||||||
src/sslconfiguration.cpp
|
SOURCES += src/harbour-nextcloudnotes.cpp \
|
||||||
|
src/sslconfiguration.cpp \
|
||||||
DISTFILES += qml/harbour-nextcloudnotes.qml \
|
src/notesmodel.cpp
|
||||||
qml/cover/CoverPage.qml \
|
|
||||||
rpm/harbour-nextcloudnotes.changes.run.in \
|
DISTFILES += qml/harbour-nextcloudnotes.qml \
|
||||||
rpm/harbour-nextcloudnotes.changes \
|
qml/cover/CoverPage.qml \
|
||||||
rpm/harbour-nextcloudnotes.spec \
|
rpm/harbour-nextcloudnotes.changes.run.in \
|
||||||
rpm/harbour-nextcloudnotes.yaml \
|
rpm/harbour-nextcloudnotes.changes \
|
||||||
translations/*.ts \
|
rpm/harbour-nextcloudnotes.spec \
|
||||||
harbour-nextcloudnotes.desktop \
|
rpm/harbour-nextcloudnotes.yaml \
|
||||||
qml/pages/NotePage.qml \
|
translations/*.ts \
|
||||||
qml/pages/NotesPage.qml \
|
harbour-nextcloudnotes.desktop \
|
||||||
qml/pages/LoginDialog.qml \
|
qml/pages/NotePage.qml \
|
||||||
qml/pages/EditPage.qml \
|
qml/pages/NotesPage.qml \
|
||||||
qml/pages/SettingsPage.qml \
|
qml/pages/LoginDialog.qml \
|
||||||
qml/pages/AboutPage.qml \
|
qml/pages/EditPage.qml \
|
||||||
qml/pages/UnencryptedDialog.qml \
|
qml/pages/SettingsPage.qml \
|
||||||
qml/pages/NotesApi.qml \
|
qml/pages/AboutPage.qml \
|
||||||
qml/pages/MITLicense.qml \
|
qml/pages/UnencryptedDialog.qml \
|
||||||
qml/pages/GPLLicense.qml \
|
qml/pages/NotesApi.qml \
|
||||||
qml/pages/SyntaxPage.qml \
|
qml/pages/MITLicense.qml \
|
||||||
qml/components/NotesApi.qml \
|
qml/pages/GPLLicense.qml \
|
||||||
qml/components/NoteDelegateModel.qml
|
qml/pages/SyntaxPage.qml \
|
||||||
|
qml/components/NotesApi.qml \
|
||||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
qml/components/NoteDelegateModel.qml
|
||||||
|
|
||||||
# to disable building translations every time, comment out the
|
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||||
# following CONFIG line
|
|
||||||
CONFIG += sailfishapp_i18n
|
# to disable building translations every time, comment out the
|
||||||
|
# following CONFIG line
|
||||||
# German translation is enabled as an example. If you aren't
|
CONFIG += sailfishapp_i18n
|
||||||
# planning to localize your app, remember to comment out the
|
|
||||||
# following TRANSLATIONS line. And also do not forget to
|
# German translation is enabled as an example. If you aren't
|
||||||
# modify the localized app name in the the .desktop file.
|
# planning to localize your app, remember to comment out the
|
||||||
TRANSLATIONS += translations/harbour-nextcloudnotes-de.ts \
|
# following TRANSLATIONS line. And also do not forget to
|
||||||
translations/harbour-nextcloudnotes-sv.ts
|
# modify the localized app name in the the .desktop file.
|
||||||
|
TRANSLATIONS += translations/harbour-nextcloudnotes-de.ts \
|
||||||
|
translations/harbour-nextcloudnotes-sv.ts
|
||||||
|
|
|
@ -11,7 +11,7 @@ Item {
|
||||||
property bool saveFile: false
|
property bool saveFile: false
|
||||||
property bool busy: jobsRunning > 0
|
property bool busy: jobsRunning > 0
|
||||||
property int jobsRunning: 0
|
property int jobsRunning: 0
|
||||||
property int status: 204
|
property int status: 0 //204
|
||||||
property string statusText: "No Content"
|
property string statusText: "No Content"
|
||||||
|
|
||||||
signal noteCreated(int id)
|
signal noteCreated(int id)
|
||||||
|
@ -22,10 +22,10 @@ Item {
|
||||||
console.log("Network status: " + statusText + " (" + status + ")")
|
console.log("Network status: " + statusText + " (" + status + ")")
|
||||||
}
|
}
|
||||||
onUuidChanged: {
|
onUuidChanged: {
|
||||||
onUuidChanged: console.log("Account : " + uuid)
|
appSettings.currentAccount = uuid
|
||||||
account.path = "/apps/harbour-nextcloudnotes/accounts/" + uuid
|
account.path = "/apps/harbour-nextcloudnotes/accounts/" + uuid
|
||||||
model.clear()
|
model.clear()
|
||||||
appSettings.currentAccount = uuid
|
onUuidChanged: console.log("Account : " + account.name)
|
||||||
}
|
}
|
||||||
function clear() {
|
function clear() {
|
||||||
model.clear()
|
model.clear()
|
||||||
|
@ -38,10 +38,12 @@ Item {
|
||||||
var endpoint = account.server + "/index.php/apps/notes/api/" + account.version + "/notes"
|
var endpoint = account.server + "/index.php/apps/notes/api/" + account.version + "/notes"
|
||||||
if (data) {
|
if (data) {
|
||||||
if (method === "POST" || method === "PUT") {
|
if (method === "POST" || method === "PUT") {
|
||||||
addToModel(data)
|
console.log("Adding note...")
|
||||||
|
//addToModel(data)
|
||||||
}
|
}
|
||||||
else if (data.id && method === "DELETE") {
|
else if (data.id && method === "DELETE") {
|
||||||
removeFromModel(data.id)
|
console.log("Deleting note...")
|
||||||
|
//removeFromModel(data.id)
|
||||||
}
|
}
|
||||||
if (method === "GET" || method === "PUT" || method === "DELETE") {
|
if (method === "GET" || method === "PUT" || method === "DELETE") {
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import Nemo.Configuration 1.0
|
import Nemo.Configuration 1.0
|
||||||
import SslConfiguration 1.0
|
import harbour.nextcloudnotes.notesmodel 1.0
|
||||||
|
import harbour.nextcloudnotes.sslconfiguration 1.0
|
||||||
import "pages"
|
import "pages"
|
||||||
import "components"
|
import "components"
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ ApplicationWindow
|
||||||
|
|
||||||
ConfigurationGroup {
|
ConfigurationGroup {
|
||||||
id: account
|
id: account
|
||||||
//path: "/apps/harbour-nextcloudnotes/accounts/" + appSettings.currentAccount
|
path: "/apps/harbour-nextcloudnotes/accounts/" + appSettings.currentAccount
|
||||||
property string name: value("name", "", String)
|
property string name: value("name", "", String)
|
||||||
property url server: value("server", "", String)
|
property url server: value("server", "", String)
|
||||||
property string version: value("version", "v0.2", String)
|
property string version: value("version", "v0.2", String)
|
||||||
|
@ -27,7 +28,6 @@ ApplicationWindow
|
||||||
property bool unencryptedConnection: account.value("unencryptedConnection", false, Boolean)
|
property bool unencryptedConnection: account.value("unencryptedConnection", false, Boolean)
|
||||||
property date update: value("update", "", Date)
|
property date update: value("update", "", Date)
|
||||||
onValuesChanged: console.log("A property of the current account has changed")
|
onValuesChanged: console.log("A property of the current account has changed")
|
||||||
//onUnsecureConnectionChanged: ssl.checkCert = !unsecureConnection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigurationGroup {
|
ConfigurationGroup {
|
||||||
|
@ -43,7 +43,6 @@ ApplicationWindow
|
||||||
property bool showSeparator: value("showSeparator", false, Boolean)
|
property bool showSeparator: value("showSeparator", false, Boolean)
|
||||||
property bool useMonoFont: value("useMonoFont", false, Boolean)
|
property bool useMonoFont: value("useMonoFont", false, Boolean)
|
||||||
property bool useCapitalX: value("useCapitalX", false, Boolean)
|
property bool useCapitalX: value("useCapitalX", false, Boolean)
|
||||||
|
|
||||||
onCurrentAccountChanged: api.uuid = currentAccount
|
onCurrentAccountChanged: api.uuid = currentAccount
|
||||||
|
|
||||||
function addAccount() {
|
function addAccount() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
* Fri Dec 28 2018 Scharel Clemens <harbour-nextcloudnotes@scharel.name> 0.3-0
|
||||||
|
- Began implementing the data model in C++
|
||||||
|
|
||||||
* Thu Dec 27 2018 Scharel Clemens <harbour-nextcloudnotes@scharel.name> 0.2-10
|
* Thu Dec 27 2018 Scharel Clemens <harbour-nextcloudnotes@scharel.name> 0.2-10
|
||||||
- Implemented #24: "Option to show favorite notes on the top of the list"
|
- Implemented #24: "Option to show favorite notes on the top of the list"
|
||||||
- Implemented #32: "Allow selfsigned SSL certificates" (not tested!)
|
- Implemented #32: "Allow selfsigned SSL certificates" (not tested!)
|
||||||
|
|
|
@ -13,8 +13,8 @@ Name: harbour-nextcloudnotes
|
||||||
%{!?qtc_make:%define qtc_make make}
|
%{!?qtc_make:%define qtc_make make}
|
||||||
%{?qtc_builddir:%define _builddir %qtc_builddir}
|
%{?qtc_builddir:%define _builddir %qtc_builddir}
|
||||||
Summary: Nextcloud Notes
|
Summary: Nextcloud Notes
|
||||||
Version: 0.2
|
Version: 0.3
|
||||||
Release: 10
|
Release: 0
|
||||||
Group: Applications/Editors
|
Group: Applications/Editors
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://github.com/scharel/harbour-nextcloudnotes
|
URL: https://github.com/scharel/harbour-nextcloudnotes
|
||||||
|
|
72
rpm/harbour-nextcloudnotes.spec.22312
Normal file
72
rpm/harbour-nextcloudnotes.spec.22312
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#
|
||||||
|
# Do NOT Edit the Auto-generated Part!
|
||||||
|
# Generated by: spectacle version 0.27
|
||||||
|
#
|
||||||
|
|
||||||
|
Name: harbour-nextcloudnotes
|
||||||
|
|
||||||
|
# >> macros
|
||||||
|
# << macros
|
||||||
|
|
||||||
|
%{!?qtc_qmake:%define qtc_qmake %qmake}
|
||||||
|
%{!?qtc_qmake5:%define qtc_qmake5 %qmake5}
|
||||||
|
%{!?qtc_make:%define qtc_make make}
|
||||||
|
%{?qtc_builddir:%define _builddir %qtc_builddir}
|
||||||
|
Summary: Nextcloud Notes
|
||||||
|
Version: 0.3
|
||||||
|
Release: 0
|
||||||
|
Group: Applications/Editors
|
||||||
|
License: MIT
|
||||||
|
URL: https://github.com/scharel/harbour-nextcloudnotes
|
||||||
|
Source0: %{name}-%{version}.tar.bz2
|
||||||
|
Source100: harbour-nextcloudnotes.yaml
|
||||||
|
Requires: sailfishsilica-qt5 >= 0.10.9
|
||||||
|
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
|
||||||
|
BuildRequires: pkgconfig(Qt5Core)
|
||||||
|
BuildRequires: pkgconfig(Qt5Qml)
|
||||||
|
BuildRequires: pkgconfig(Qt5Quick)
|
||||||
|
BuildRequires: desktop-file-utils
|
||||||
|
|
||||||
|
%description
|
||||||
|
A client app for the Nextcloud Notes server app
|
||||||
|
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q -n %{name}-%{version}
|
||||||
|
|
||||||
|
# >> setup
|
||||||
|
# << setup
|
||||||
|
|
||||||
|
%build
|
||||||
|
# >> build pre
|
||||||
|
# << build pre
|
||||||
|
|
||||||
|
%qtc_qmake5 \
|
||||||
|
VERSION='%{version}-%{release}'
|
||||||
|
|
||||||
|
%qtc_make %{?_smp_mflags}
|
||||||
|
|
||||||
|
# >> build post
|
||||||
|
# << build post
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf %{buildroot}
|
||||||
|
# >> install pre
|
||||||
|
# << install pre
|
||||||
|
%qmake5_install
|
||||||
|
|
||||||
|
# >> install post
|
||||||
|
# << install post
|
||||||
|
|
||||||
|
desktop-file-install --delete-original \
|
||||||
|
--dir %{buildroot}%{_datadir}/applications \
|
||||||
|
%{buildroot}%{_datadir}/applications/*.desktop
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_bindir}
|
||||||
|
%{_datadir}/%{name}
|
||||||
|
%{_datadir}/applications/%{name}.desktop
|
||||||
|
%{_datadir}/icons/hicolor/*/apps/%{name}.png
|
||||||
|
# >> files
|
||||||
|
# << files
|
|
@ -1,7 +1,7 @@
|
||||||
Name: harbour-nextcloudnotes
|
Name: harbour-nextcloudnotes
|
||||||
Summary: Nextcloud Notes
|
Summary: Nextcloud Notes
|
||||||
Version: 0.2
|
Version: 0.3
|
||||||
Release: 10
|
Release: 0
|
||||||
# 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
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <QtQuick>
|
#include <QtQuick>
|
||||||
#include <sailfishapp.h>
|
#include <sailfishapp.h>
|
||||||
|
#include <QtQml>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include "notesmodel.h"
|
||||||
#include "sslconfiguration.h"
|
#include "sslconfiguration.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -13,7 +15,8 @@ int main(int argc, char *argv[])
|
||||||
app->setOrganizationName("harbour-nextcloudnotes");
|
app->setOrganizationName("harbour-nextcloudnotes");
|
||||||
|
|
||||||
qDebug() << app->applicationDisplayName() << app->applicationVersion();
|
qDebug() << app->applicationDisplayName() << app->applicationVersion();
|
||||||
qmlRegisterType<SslConfiguration>("SslConfiguration", 1, 0, "SslConfiguration");
|
qmlRegisterType<NotesModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel");
|
||||||
|
qmlRegisterType<SslConfiguration>("harbour.nextcloudnotes.sslconfiguration", 1, 0, "SslConfiguration");
|
||||||
|
|
||||||
QQuickView* view = SailfishApp::createView();
|
QQuickView* view = SailfishApp::createView();
|
||||||
|
|
||||||
|
|
347
src/notesmodel.cpp
Normal file
347
src/notesmodel.cpp
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
#include "notesmodel.h"
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
const QHash<int, QByteArray> noteRoles = QHash<int, QByteArray>{
|
||||||
|
{NotesModel::idRole, "id"},
|
||||||
|
{NotesModel::modifiedRole, "modified"},
|
||||||
|
{NotesModel::titleRole, "title"},
|
||||||
|
{NotesModel::categoryRole, "category"},
|
||||||
|
{NotesModel::contentRole, "content"},
|
||||||
|
{NotesModel::favoriteRole, "favorite"},
|
||||||
|
{NotesModel::etagRole, "etag"},
|
||||||
|
{NotesModel::errorRole, "error"},
|
||||||
|
{NotesModel::errorMessageRole, "errorMessage"}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Note {
|
||||||
|
int id;
|
||||||
|
uint modified;
|
||||||
|
QString title;
|
||||||
|
QString category;
|
||||||
|
QString content;
|
||||||
|
bool favorite;
|
||||||
|
QString etag;
|
||||||
|
bool error;
|
||||||
|
QString errorMessage;
|
||||||
|
bool operator==(const Note& n) {
|
||||||
|
return id == n.id;
|
||||||
|
}
|
||||||
|
void fromjson(const QJsonObject& jobj) {
|
||||||
|
id = jobj.value(noteRoles[NotesModel::idRole]).toInt();
|
||||||
|
modified = jobj.value(noteRoles[NotesModel::modifiedRole]).toInt();
|
||||||
|
title = jobj.value(noteRoles[NotesModel::titleRole]).toString();
|
||||||
|
category = jobj.value(noteRoles[NotesModel::categoryRole]).toString();
|
||||||
|
content = jobj.value(noteRoles[NotesModel::contentRole]).toString();
|
||||||
|
favorite = jobj.value(noteRoles[NotesModel::favoriteRole]).toBool();
|
||||||
|
etag = jobj.value(noteRoles[NotesModel::etagRole]).toString();
|
||||||
|
error = jobj.value(noteRoles[NotesModel::errorRole]).toBool(true);
|
||||||
|
errorMessage = jobj.value(noteRoles[NotesModel::errorMessageRole]).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NotesModel::NotesModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
m_sortBy = sortByDate;
|
||||||
|
m_favoritesOnTop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotesModel::~NotesModel() {
|
||||||
|
m_notes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotesModel::setSortBy(int sortBy) {
|
||||||
|
if (sortBy != m_sortBy) {
|
||||||
|
m_sortBy = sortBy;
|
||||||
|
sort();
|
||||||
|
emit sortByChanged(m_sortBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotesModel::setFavoritesOnTop(bool favoritesOnTop) {
|
||||||
|
if (favoritesOnTop != m_favoritesOnTop) {
|
||||||
|
m_favoritesOnTop = favoritesOnTop;
|
||||||
|
sort();
|
||||||
|
emit favoritesOnTopChanged(m_favoritesOnTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::applyJSON(QString json, bool replaceIfArray) {
|
||||||
|
QJsonDocument jdoc = QJsonDocument::fromJson(json.toUtf8());
|
||||||
|
if (!jdoc.isNull()) {
|
||||||
|
if (jdoc.isArray()) {
|
||||||
|
QJsonArray jarr = jdoc.array();
|
||||||
|
while (!jarr.empty()) {
|
||||||
|
QJsonValue jval = jarr.first();
|
||||||
|
if (jval.isObject()) {
|
||||||
|
QJsonObject jobj = jval.toObject();
|
||||||
|
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
||||||
|
Note note;
|
||||||
|
note.fromjson(jobj);
|
||||||
|
int index = m_notes.indexOf(note);
|
||||||
|
if (index >= 0) {
|
||||||
|
m_notes.replace(index, note);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jarr.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (jdoc.isObject()) {
|
||||||
|
QJsonObject jobj = jdoc.object();
|
||||||
|
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
||||||
|
Note note;
|
||||||
|
note.fromjson(jobj);
|
||||||
|
int index = m_notes.indexOf(note);
|
||||||
|
if (index >= 0) {
|
||||||
|
m_notes.replace(index, note);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::removeNote(int id) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotesModel::search(QString query) const {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotesModel::clearSearch() const {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool NotesModel::addNote(Note ¬e) {
|
||||||
|
m_notes.append(note);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::addNotes(QList<Note> ¬es) {
|
||||||
|
for (int i = 0; i < notes.length(); i++) {
|
||||||
|
addNote(notes[i]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
QHash<int, QByteArray> NotesModel::roleNames() const {
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles[idRole] = "id";
|
||||||
|
roles[modifiedRole] = "modified";
|
||||||
|
roles[titleRole] = "title";
|
||||||
|
roles[categoryRole] = "category";
|
||||||
|
roles[contentRole] = "content";
|
||||||
|
roles[favoriteRole] = "favorite";
|
||||||
|
roles[etagRole] = "etag";
|
||||||
|
roles[errorRole] = "error";
|
||||||
|
roles[errorMessageRole] = "errorMessage";
|
||||||
|
return noteRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> NotesModel::sortingNames() const {
|
||||||
|
QHash<int, QByteArray> criteria;
|
||||||
|
criteria[sortByDate] = "date";
|
||||||
|
criteria[sortByCategory] = "category";
|
||||||
|
criteria[sortByTitle] = "title";
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags NotesModel::flags(const QModelIndex &index) const {
|
||||||
|
return Qt::ItemIsEnabled; //| Qt::ItemIsEditable | Qt::ItemIsSelectable
|
||||||
|
}
|
||||||
|
|
||||||
|
int NotesModel::rowCount(const QModelIndex &parent) const {
|
||||||
|
return m_notes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NotesModel::data(const QModelIndex &index, int role) const {
|
||||||
|
if (!index.isValid()) return QVariant();
|
||||||
|
else if (role == idRole) return m_notes[index.row()].id;
|
||||||
|
else if (role == modifiedRole) return m_notes[index.row()].modified;
|
||||||
|
else if (role == titleRole) return m_notes[index.row()].title;
|
||||||
|
else if (role == categoryRole) return m_notes[index.row()].category;
|
||||||
|
else if (role == contentRole) return m_notes[index.row()].content;
|
||||||
|
else if (role == favoriteRole) return m_notes[index.row()].favorite;
|
||||||
|
else if (role == etagRole) return m_notes[index.row()].etag;
|
||||||
|
else if (role == errorRole) return m_notes[index.row()].error;
|
||||||
|
else if (role == errorMessageRole) return m_notes[index.row()].errorMessage;
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotesModel::sort() {
|
||||||
|
QList<Note> notes;
|
||||||
|
QMap<QString, Note> map;
|
||||||
|
QMap<QString, Note> favorites;
|
||||||
|
switch (m_sortBy) {
|
||||||
|
case sortByDate:
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
foreach (const Note ¬e, m_notes) {
|
||||||
|
if (m_favoritesOnTop && note.favorite)
|
||||||
|
favorites.insert(QString::number(note.modified), note);
|
||||||
|
else
|
||||||
|
map.insert(QString::number(note.modified), note);
|
||||||
|
}
|
||||||
|
notes = favorites.values();
|
||||||
|
notes.append(map.values());
|
||||||
|
m_notes = notes;
|
||||||
|
emit layoutChanged();
|
||||||
|
break;
|
||||||
|
case sortByCategory:
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
foreach (const Note ¬e, m_notes) {
|
||||||
|
if (m_favoritesOnTop && note.favorite)
|
||||||
|
favorites.insert(note.category, note);
|
||||||
|
else
|
||||||
|
map.insert(note.category, note);
|
||||||
|
}
|
||||||
|
notes = favorites.values();
|
||||||
|
notes.append(map.values());
|
||||||
|
m_notes = notes;
|
||||||
|
emit layoutChanged();
|
||||||
|
break;
|
||||||
|
case sortByTitle:
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
foreach (const Note ¬e, m_notes) {
|
||||||
|
if (m_favoritesOnTop && note.favorite)
|
||||||
|
favorites.insert(note.title, note);
|
||||||
|
else
|
||||||
|
map.insert(note.title, note);
|
||||||
|
}
|
||||||
|
notes = favorites.values();
|
||||||
|
notes.append(map.values());
|
||||||
|
m_notes = notes;
|
||||||
|
emit layoutChanged();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*bool NotesModel::noteLessThanByDate(const Note &n1, const Note &n2) {
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.modified > n2.modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::noteLessThanByCategory(const Note &n1, const Note &n2) {
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.category < n2.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::noteLessThanByTitle(const Note &n1, const Note &n2) {
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.title < n2.title;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*bool NotesModel::noteLessThan(const Note &n1, const Note &n2) const {
|
||||||
|
switch (m_sortBy) {
|
||||||
|
case sortByDate:
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.modified > n2.modified;
|
||||||
|
break;
|
||||||
|
case sortByCategory:
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.category < n2.category;
|
||||||
|
break;
|
||||||
|
case sortByTitle:
|
||||||
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
|
return n1.favorite;
|
||||||
|
else
|
||||||
|
return n1.title < n2.title;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool NotesModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
||||||
|
if (!index.isValid()) return false;
|
||||||
|
else if (role == modifiedRole) {
|
||||||
|
m_notes[index.row()].modified = value.toDateTime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == categoryRole) {
|
||||||
|
m_notes[index.row()].category = value.toString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == contentRole) {
|
||||||
|
m_notes[index.row()].content = value.toString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == favoriteRole) {
|
||||||
|
m_notes[index.row()].favorite = value.toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::insertRow(int row, const QModelIndex &parent) {
|
||||||
|
beginInsertRows(parent, row, row);
|
||||||
|
m_notes.insert(row, Note());
|
||||||
|
endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::insertRows(int row, int count, const QModelIndex &parent) {
|
||||||
|
if (count > 0) {
|
||||||
|
beginInsertRows(parent, row, row+count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
m_notes.insert(row + i, Note());
|
||||||
|
}
|
||||||
|
endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::removeRow(int row, const QModelIndex &parent) {
|
||||||
|
if (row >= 0 && row < m_notes.size()) {
|
||||||
|
beginRemoveRows(parent, row, row);
|
||||||
|
m_notes.removeAt(row);
|
||||||
|
endRemoveRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotesModel::removeRows(int row, int count, const QModelIndex &parent) {
|
||||||
|
if (row >= 0 && row < m_notes.size()) {
|
||||||
|
beginRemoveRows(parent, row, count);
|
||||||
|
for (int i = 0; i < count && row + i < m_notes.size(); i++) {
|
||||||
|
m_notes.removeAt(row);
|
||||||
|
}
|
||||||
|
endRemoveRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
78
src/notesmodel.h
Normal file
78
src/notesmodel.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef NOTESMODEL_H
|
||||||
|
#define NOTESMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
struct Note;
|
||||||
|
|
||||||
|
class NotesModel : public QAbstractListModel {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NotesModel(QObject *parent = 0);
|
||||||
|
virtual ~NotesModel();
|
||||||
|
|
||||||
|
Q_PROPERTY(int sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
|
||||||
|
int sortBy() { return m_sortBy; }
|
||||||
|
void setSortBy(int sortBy);
|
||||||
|
|
||||||
|
Q_PROPERTY(bool favoritesOnTop READ favoritesOnTop WRITE setFavoritesOnTop NOTIFY favoritesOnTopChanged)
|
||||||
|
bool favoritesOnTop() { return m_favoritesOnTop; }
|
||||||
|
void setFavoritesOnTop(bool favoritesOnTop);
|
||||||
|
|
||||||
|
Q_INVOKABLE bool applyJSON(QString json, bool replaceIfArray = true);
|
||||||
|
Q_INVOKABLE bool removeNote(int id);
|
||||||
|
|
||||||
|
Q_INVOKABLE void search(QString query) const;
|
||||||
|
Q_INVOKABLE void clearSearch() const;
|
||||||
|
|
||||||
|
enum NoteRoles {
|
||||||
|
idRole = Qt::UserRole + 1,
|
||||||
|
modifiedRole = Qt::UserRole + 2,
|
||||||
|
titleRole = Qt::UserRole + 3,
|
||||||
|
categoryRole = Qt::UserRole + 4,
|
||||||
|
contentRole = Qt::UserRole + 5,
|
||||||
|
favoriteRole = Qt::UserRole + 6,
|
||||||
|
etagRole = Qt::UserRole + 7,
|
||||||
|
errorRole = Qt::UserRole + 8,
|
||||||
|
errorMessageRole = Qt::UserRole + 9
|
||||||
|
};
|
||||||
|
QHash<int, QByteArray> roleNames() const;
|
||||||
|
|
||||||
|
enum SortingCriteria {
|
||||||
|
sortByDate,
|
||||||
|
sortByCategory,
|
||||||
|
sortByTitle
|
||||||
|
};
|
||||||
|
QHash<int, QByteArray> sortingNames() const;
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
virtual int rowCount(const QModelIndex &parent) const;
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
//virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
//virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
|
|
||||||
|
//bool insertRow(int row, const QModelIndex &parent);
|
||||||
|
//bool insertRows(int row, int count, const QModelIndex &parent);
|
||||||
|
//bool removeRow(int row, const QModelIndex &parent);
|
||||||
|
//bool removeRows(int row, int count, const QModelIndex &parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static bool noteLessThanByDate(const Note &n1, const Note &n2);
|
||||||
|
static bool noteLessThanByCategory(const Note &n1, const Note &n2);
|
||||||
|
static bool noteLessThanByTitle(const Note &n1, const Note &n2);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sortByChanged(int sortBy);
|
||||||
|
void favoritesOnTopChanged(bool favoritesOnTop);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<Note> m_notes;
|
||||||
|
int m_sortBy;
|
||||||
|
bool m_favoritesOnTop;
|
||||||
|
|
||||||
|
void sort();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NOTESMODEL_H
|
|
@ -272,17 +272,17 @@
|
||||||
<context>
|
<context>
|
||||||
<name>NotesApi</name>
|
<name>NotesApi</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/components/NotesApi.qml" line="118"/>
|
<location filename="../qml/components/NotesApi.qml" line="107"/>
|
||||||
<source>Unable to connect</source>
|
<source>Unable to connect</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/components/NotesApi.qml" line="256"/>
|
<location filename="../qml/components/NotesApi.qml" line="245"/>
|
||||||
<source>Today</source>
|
<source>Today</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/components/NotesApi.qml" line="258"/>
|
<location filename="../qml/components/NotesApi.qml" line="247"/>
|
||||||
<source>Yesterday</source>
|
<source>Yesterday</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
Loading…
Reference in a new issue