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:
|
||||
#
|
||||
# Application name defined in TARGET has a corresponding QML filename.
|
||||
# If name defined in TARGET is changed, the following needs to be done
|
||||
# to match new name:
|
||||
# - corresponding QML filename must be changed
|
||||
# - desktop icon filename must be changed
|
||||
# - desktop filename must be changed
|
||||
# - icon definition filename in desktop file must be changed
|
||||
# - translation filenames have to be changed
|
||||
|
||||
# The name of your application
|
||||
TARGET = harbour-nextcloudnotes
|
||||
|
||||
CONFIG += sailfishapp
|
||||
|
||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
HEADERS += \
|
||||
src/sslconfiguration.h
|
||||
|
||||
SOURCES += src/harbour-nextcloudnotes.cpp \
|
||||
src/sslconfiguration.cpp
|
||||
|
||||
DISTFILES += qml/harbour-nextcloudnotes.qml \
|
||||
qml/cover/CoverPage.qml \
|
||||
rpm/harbour-nextcloudnotes.changes.run.in \
|
||||
rpm/harbour-nextcloudnotes.changes \
|
||||
rpm/harbour-nextcloudnotes.spec \
|
||||
rpm/harbour-nextcloudnotes.yaml \
|
||||
translations/*.ts \
|
||||
harbour-nextcloudnotes.desktop \
|
||||
qml/pages/NotePage.qml \
|
||||
qml/pages/NotesPage.qml \
|
||||
qml/pages/LoginDialog.qml \
|
||||
qml/pages/EditPage.qml \
|
||||
qml/pages/SettingsPage.qml \
|
||||
qml/pages/AboutPage.qml \
|
||||
qml/pages/UnencryptedDialog.qml \
|
||||
qml/pages/NotesApi.qml \
|
||||
qml/pages/MITLicense.qml \
|
||||
qml/pages/GPLLicense.qml \
|
||||
qml/pages/SyntaxPage.qml \
|
||||
qml/components/NotesApi.qml \
|
||||
qml/components/NoteDelegateModel.qml
|
||||
|
||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||
|
||||
# to disable building translations every time, comment out the
|
||||
# following CONFIG line
|
||||
CONFIG += sailfishapp_i18n
|
||||
|
||||
# German translation is enabled as an example. If you aren't
|
||||
# planning to localize your app, remember to comment out the
|
||||
# following TRANSLATIONS line. And also do not forget to
|
||||
# modify the localized app name in the the .desktop file.
|
||||
TRANSLATIONS += translations/harbour-nextcloudnotes-de.ts \
|
||||
translations/harbour-nextcloudnotes-sv.ts
|
||||
# NOTICE:
|
||||
#
|
||||
# Application name defined in TARGET has a corresponding QML filename.
|
||||
# If name defined in TARGET is changed, the following needs to be done
|
||||
# to match new name:
|
||||
# - corresponding QML filename must be changed
|
||||
# - desktop icon filename must be changed
|
||||
# - desktop filename must be changed
|
||||
# - icon definition filename in desktop file must be changed
|
||||
# - translation filenames have to be changed
|
||||
|
||||
# The name of your application
|
||||
TARGET = harbour-nextcloudnotes
|
||||
|
||||
CONFIG += sailfishapp
|
||||
|
||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
HEADERS += \
|
||||
src/sslconfiguration.h \
|
||||
src/notesmodel.h
|
||||
|
||||
SOURCES += src/harbour-nextcloudnotes.cpp \
|
||||
src/sslconfiguration.cpp \
|
||||
src/notesmodel.cpp
|
||||
|
||||
DISTFILES += qml/harbour-nextcloudnotes.qml \
|
||||
qml/cover/CoverPage.qml \
|
||||
rpm/harbour-nextcloudnotes.changes.run.in \
|
||||
rpm/harbour-nextcloudnotes.changes \
|
||||
rpm/harbour-nextcloudnotes.spec \
|
||||
rpm/harbour-nextcloudnotes.yaml \
|
||||
translations/*.ts \
|
||||
harbour-nextcloudnotes.desktop \
|
||||
qml/pages/NotePage.qml \
|
||||
qml/pages/NotesPage.qml \
|
||||
qml/pages/LoginDialog.qml \
|
||||
qml/pages/EditPage.qml \
|
||||
qml/pages/SettingsPage.qml \
|
||||
qml/pages/AboutPage.qml \
|
||||
qml/pages/UnencryptedDialog.qml \
|
||||
qml/pages/NotesApi.qml \
|
||||
qml/pages/MITLicense.qml \
|
||||
qml/pages/GPLLicense.qml \
|
||||
qml/pages/SyntaxPage.qml \
|
||||
qml/components/NotesApi.qml \
|
||||
qml/components/NoteDelegateModel.qml
|
||||
|
||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||
|
||||
# to disable building translations every time, comment out the
|
||||
# following CONFIG line
|
||||
CONFIG += sailfishapp_i18n
|
||||
|
||||
# German translation is enabled as an example. If you aren't
|
||||
# planning to localize your app, remember to comment out the
|
||||
# following TRANSLATIONS line. And also do not forget to
|
||||
# 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 busy: jobsRunning > 0
|
||||
property int jobsRunning: 0
|
||||
property int status: 204
|
||||
property int status: 0 //204
|
||||
property string statusText: "No Content"
|
||||
|
||||
signal noteCreated(int id)
|
||||
|
@ -22,10 +22,10 @@ Item {
|
|||
console.log("Network status: " + statusText + " (" + status + ")")
|
||||
}
|
||||
onUuidChanged: {
|
||||
onUuidChanged: console.log("Account : " + uuid)
|
||||
appSettings.currentAccount = uuid
|
||||
account.path = "/apps/harbour-nextcloudnotes/accounts/" + uuid
|
||||
model.clear()
|
||||
appSettings.currentAccount = uuid
|
||||
onUuidChanged: console.log("Account : " + account.name)
|
||||
}
|
||||
function clear() {
|
||||
model.clear()
|
||||
|
@ -38,10 +38,12 @@ Item {
|
|||
var endpoint = account.server + "/index.php/apps/notes/api/" + account.version + "/notes"
|
||||
if (data) {
|
||||
if (method === "POST" || method === "PUT") {
|
||||
addToModel(data)
|
||||
console.log("Adding note...")
|
||||
//addToModel(data)
|
||||
}
|
||||
else if (data.id && method === "DELETE") {
|
||||
removeFromModel(data.id)
|
||||
console.log("Deleting note...")
|
||||
//removeFromModel(data.id)
|
||||
}
|
||||
if (method === "GET" || method === "PUT" || method === "DELETE") {
|
||||
if (data.id) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 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 "components"
|
||||
|
||||
|
@ -17,7 +18,7 @@ ApplicationWindow
|
|||
|
||||
ConfigurationGroup {
|
||||
id: account
|
||||
//path: "/apps/harbour-nextcloudnotes/accounts/" + appSettings.currentAccount
|
||||
path: "/apps/harbour-nextcloudnotes/accounts/" + appSettings.currentAccount
|
||||
property string name: value("name", "", String)
|
||||
property url server: value("server", "", String)
|
||||
property string version: value("version", "v0.2", String)
|
||||
|
@ -27,7 +28,6 @@ ApplicationWindow
|
|||
property bool unencryptedConnection: account.value("unencryptedConnection", false, Boolean)
|
||||
property date update: value("update", "", Date)
|
||||
onValuesChanged: console.log("A property of the current account has changed")
|
||||
//onUnsecureConnectionChanged: ssl.checkCert = !unsecureConnection
|
||||
}
|
||||
|
||||
ConfigurationGroup {
|
||||
|
@ -43,7 +43,6 @@ ApplicationWindow
|
|||
property bool showSeparator: value("showSeparator", false, Boolean)
|
||||
property bool useMonoFont: value("useMonoFont", false, Boolean)
|
||||
property bool useCapitalX: value("useCapitalX", false, Boolean)
|
||||
|
||||
onCurrentAccountChanged: api.uuid = currentAccount
|
||||
|
||||
function addAccount() {
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
# * date Author's Name <author's email> version-release
|
||||
# - 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
|
||||
- Implemented #24: "Option to show favorite notes on the top of the list"
|
||||
- Implemented #32: "Allow selfsigned SSL certificates" (not tested!)
|
||||
|
|
|
@ -13,8 +13,8 @@ Name: harbour-nextcloudnotes
|
|||
%{!?qtc_make:%define qtc_make make}
|
||||
%{?qtc_builddir:%define _builddir %qtc_builddir}
|
||||
Summary: Nextcloud Notes
|
||||
Version: 0.2
|
||||
Release: 10
|
||||
Version: 0.3
|
||||
Release: 0
|
||||
Group: Applications/Editors
|
||||
License: MIT
|
||||
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
|
||||
Summary: Nextcloud Notes
|
||||
Version: 0.2
|
||||
Release: 10
|
||||
Version: 0.3
|
||||
Release: 0
|
||||
# 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
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <QtQuick>
|
||||
#include <sailfishapp.h>
|
||||
#include <QtQml>
|
||||
#include <QObject>
|
||||
#include "notesmodel.h"
|
||||
#include "sslconfiguration.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -13,7 +15,8 @@ int main(int argc, char *argv[])
|
|||
app->setOrganizationName("harbour-nextcloudnotes");
|
||||
|
||||
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();
|
||||
|
||||
|
|
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>
|
||||
<name>NotesApi</name>
|
||||
<message>
|
||||
<location filename="../qml/components/NotesApi.qml" line="118"/>
|
||||
<location filename="../qml/components/NotesApi.qml" line="107"/>
|
||||
<source>Unable to connect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/components/NotesApi.qml" line="256"/>
|
||||
<location filename="../qml/components/NotesApi.qml" line="245"/>
|
||||
<source>Today</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/components/NotesApi.qml" line="258"/>
|
||||
<location filename="../qml/components/NotesApi.qml" line="247"/>
|
||||
<source>Yesterday</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
Loading…
Reference in a new issue