Further worked on C++ implementation of the notes Model.
This commit is contained in:
parent
86a3755ad2
commit
72f3b3f44c
3 changed files with 214 additions and 192 deletions
|
@ -1,72 +0,0 @@
|
||||||
#
|
|
||||||
# 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,8 +1,10 @@
|
||||||
#include "notesmodel.h"
|
#include "notesmodel.h"
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
const QHash<int, QByteArray> noteRoles = QHash<int, QByteArray>{
|
const QHash<int, QByteArray> noteRoles = QHash<int, QByteArray>{
|
||||||
|
{NotesModel::visible, "visible"},
|
||||||
{NotesModel::idRole, "id"},
|
{NotesModel::idRole, "id"},
|
||||||
{NotesModel::modifiedRole, "modified"},
|
{NotesModel::modifiedRole, "modified"},
|
||||||
{NotesModel::titleRole, "title"},
|
{NotesModel::titleRole, "title"},
|
||||||
|
@ -27,18 +29,42 @@ struct Note {
|
||||||
bool operator==(const Note& n) {
|
bool operator==(const Note& n) {
|
||||||
return id == n.id;
|
return id == n.id;
|
||||||
}
|
}
|
||||||
void fromjson(const QJsonObject& jobj) {
|
enum SearchAttribute {
|
||||||
id = jobj.value(noteRoles[NotesModel::idRole]).toInt();
|
NoSearchAttribute = 0x0,
|
||||||
modified = jobj.value(noteRoles[NotesModel::modifiedRole]).toInt();
|
SearchInTitle = 0x1,
|
||||||
title = jobj.value(noteRoles[NotesModel::titleRole]).toString();
|
SearchInCategory = 0x2,
|
||||||
category = jobj.value(noteRoles[NotesModel::categoryRole]).toString();
|
SearchInContent = 0x4,
|
||||||
content = jobj.value(noteRoles[NotesModel::contentRole]).toString();
|
SearchAll = 0x7
|
||||||
favorite = jobj.value(noteRoles[NotesModel::favoriteRole]).toBool();
|
};
|
||||||
etag = jobj.value(noteRoles[NotesModel::etagRole]).toString();
|
Q_DECLARE_FLAGS(SearchAttributes, SearchAttribute)
|
||||||
error = jobj.value(noteRoles[NotesModel::errorRole]).toBool(true);
|
static const Note fromjson(const QJsonObject& jobj) {
|
||||||
errorMessage = jobj.value(noteRoles[NotesModel::errorMessageRole]).toString();
|
Note note;
|
||||||
|
note.id = jobj.value(noteRoles[NotesModel::idRole]).toInt();
|
||||||
|
note.modified = jobj.value(noteRoles[NotesModel::modifiedRole]).toInt();
|
||||||
|
note.title = jobj.value(noteRoles[NotesModel::titleRole]).toString();
|
||||||
|
note.category = jobj.value(noteRoles[NotesModel::categoryRole]).toString();
|
||||||
|
note.content = jobj.value(noteRoles[NotesModel::contentRole]).toString();
|
||||||
|
note.favorite = jobj.value(noteRoles[NotesModel::favoriteRole]).toBool();
|
||||||
|
note.etag = jobj.value(noteRoles[NotesModel::etagRole]).toString();
|
||||||
|
note.error = jobj.value(noteRoles[NotesModel::errorRole]).toBool(true);
|
||||||
|
note.errorMessage = jobj.value(noteRoles[NotesModel::errorMessageRole]).toString();
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
static bool searchInNote(const QString &query, const Note ¬e, SearchAttributes criteria = QFlag(SearchAll)) {
|
||||||
|
bool queryFound = false;
|
||||||
|
if (criteria.testFlag(SearchInTitle)) {
|
||||||
|
queryFound |= note.title.contains(query, Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
if (criteria.testFlag(SearchInContent)) {
|
||||||
|
queryFound |= note.content.contains(query, Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
if (criteria.testFlag(SearchInCategory)) {
|
||||||
|
queryFound |= note.category.contains(query, Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
return queryFound;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(Note::SearchAttributes)
|
||||||
|
|
||||||
NotesModel::NotesModel(QObject *parent) : QAbstractListModel(parent)
|
NotesModel::NotesModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
@ -68,43 +94,75 @@ void NotesModel::setFavoritesOnTop(bool favoritesOnTop) {
|
||||||
|
|
||||||
bool NotesModel::applyJSON(QString json, bool replaceIfArray) {
|
bool NotesModel::applyJSON(QString json, bool replaceIfArray) {
|
||||||
QJsonDocument jdoc = QJsonDocument::fromJson(json.toUtf8());
|
QJsonDocument jdoc = QJsonDocument::fromJson(json.toUtf8());
|
||||||
|
int notesModified = 0;
|
||||||
if (!jdoc.isNull()) {
|
if (!jdoc.isNull()) {
|
||||||
if (jdoc.isArray()) {
|
if (jdoc.isArray()) {
|
||||||
QJsonArray jarr = jdoc.array();
|
QJsonArray jarr = jdoc.array();
|
||||||
|
QList<int> notesToRemove;
|
||||||
|
QList<ModelNote<Note, int> > notesToAdd;
|
||||||
|
for (int i = 0; i < m_notes.size(); i++)
|
||||||
|
notesToRemove << i;
|
||||||
while (!jarr.empty()) {
|
while (!jarr.empty()) {
|
||||||
QJsonValue jval = jarr.first();
|
QJsonValue jval = jarr.first();
|
||||||
if (jval.isObject()) {
|
if (jval.isObject()) {
|
||||||
QJsonObject jobj = jval.toObject();
|
QJsonObject jobj = jval.toObject();
|
||||||
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
||||||
Note note;
|
Note note = Note::fromjson(jobj);
|
||||||
note.fromjson(jobj);
|
int position = indexOf(note.id);
|
||||||
int index = m_notes.indexOf(note);
|
if (position >= 0) {
|
||||||
if (index >= 0) {
|
m_notes[position].note = note;
|
||||||
m_notes.replace(index, note);
|
emit dataChanged(index(position), index(position));
|
||||||
|
notesToRemove.removeAt(position);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO
|
position = insertPosition(note);
|
||||||
|
//beginInsertRows(QModelIndex(), position, position);
|
||||||
|
ModelNote<Note, int> noteToAdd;
|
||||||
|
noteToAdd.note = note; noteToAdd.param = position;
|
||||||
|
notesToAdd << noteToAdd;
|
||||||
|
//m_notes[position].note = note;
|
||||||
|
//endInsertRows();
|
||||||
}
|
}
|
||||||
|
notesModified++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jarr.pop_front();
|
jarr.pop_front();
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < notesToRemove.size(); i++) {
|
||||||
|
beginRemoveRows(QModelIndex(), notesToRemove[i], notesToRemove[i]);
|
||||||
|
m_notes.removeAt(notesToRemove[i]);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < notesToAdd.size(); i++) {
|
||||||
|
beginInsertRows(QModelIndex(), notesToAdd[i].param, notesToAdd[i].param);
|
||||||
|
ModelNote<Note, bool> note;
|
||||||
|
note.note = notesToAdd[i].note;
|
||||||
|
m_notes.insert(notesToAdd[i].param, note);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (jdoc.isObject()) {
|
else if (jdoc.isObject()) {
|
||||||
QJsonObject jobj = jdoc.object();
|
QJsonObject jobj = jdoc.object();
|
||||||
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
if (!jobj.isEmpty() && !jobj.value(noteRoles[errorRole]).toBool(true)) {
|
||||||
Note note;
|
Note note;
|
||||||
note.fromjson(jobj);
|
note.fromjson(jobj);
|
||||||
int index = m_notes.indexOf(note);
|
int position = indexOf(note.id);
|
||||||
if (index >= 0) {
|
if (position >= 0) {
|
||||||
m_notes.replace(index, note);
|
m_notes[position].note = note;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO
|
position = insertPosition(note);
|
||||||
|
beginInsertRows(index(position), position, position);
|
||||||
|
m_notes[position].note = note;
|
||||||
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
notesModified++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort();
|
if (notesModified > 0) {
|
||||||
|
sort(); // TODO react to signal connect()
|
||||||
|
search(m_searchQuery);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -115,12 +173,20 @@ bool NotesModel::removeNote(int id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesModel::search(QString query) const {
|
void NotesModel::search(QString query) {
|
||||||
// TODO
|
m_searchQuery = query;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesModel::clearSearch() const {
|
void NotesModel::clearSearch() {
|
||||||
// TODO
|
search("");
|
||||||
|
}
|
||||||
|
|
||||||
|
int NotesModel::indexOf(int id) const {
|
||||||
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
|
if (m_notes[i].note.id == id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -138,16 +204,6 @@ bool NotesModel::addNotes(QList<Note> ¬es) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QHash<int, QByteArray> NotesModel::roleNames() const {
|
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;
|
return noteRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +216,7 @@ QHash<int, QByteArray> NotesModel::sortingNames() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags NotesModel::flags(const QModelIndex &index) const {
|
Qt::ItemFlags NotesModel::flags(const QModelIndex &index) const {
|
||||||
return Qt::ItemIsEnabled; //| Qt::ItemIsEditable | Qt::ItemIsSelectable
|
return Qt::ItemIsEnabled | Qt::ItemIsEditable; // | Qt::ItemIsSelectable
|
||||||
}
|
}
|
||||||
|
|
||||||
int NotesModel::rowCount(const QModelIndex &parent) const {
|
int NotesModel::rowCount(const QModelIndex &parent) const {
|
||||||
|
@ -169,67 +225,137 @@ int NotesModel::rowCount(const QModelIndex &parent) const {
|
||||||
|
|
||||||
QVariant NotesModel::data(const QModelIndex &index, int role) const {
|
QVariant NotesModel::data(const QModelIndex &index, int role) const {
|
||||||
if (!index.isValid()) return QVariant();
|
if (!index.isValid()) return QVariant();
|
||||||
else if (role == idRole) return m_notes[index.row()].id;
|
else if (role == visible) return m_notes[index.row()].param;
|
||||||
else if (role == modifiedRole) return m_notes[index.row()].modified;
|
else if (role == idRole) return m_notes[index.row()].note.id;
|
||||||
else if (role == titleRole) return m_notes[index.row()].title;
|
else if (role == modifiedRole) return m_notes[index.row()].note.modified;
|
||||||
else if (role == categoryRole) return m_notes[index.row()].category;
|
else if (role == titleRole) return m_notes[index.row()].note.title;
|
||||||
else if (role == contentRole) return m_notes[index.row()].content;
|
else if (role == categoryRole) return m_notes[index.row()].note.category;
|
||||||
else if (role == favoriteRole) return m_notes[index.row()].favorite;
|
else if (role == contentRole) return m_notes[index.row()].note.content;
|
||||||
else if (role == etagRole) return m_notes[index.row()].etag;
|
else if (role == favoriteRole) return m_notes[index.row()].note.favorite;
|
||||||
else if (role == errorRole) return m_notes[index.row()].error;
|
else if (role == etagRole) return m_notes[index.row()].note.etag;
|
||||||
else if (role == errorMessageRole) return m_notes[index.row()].errorMessage;
|
else if (role == errorRole) return m_notes[index.row()].note.error;
|
||||||
|
else if (role == errorMessageRole) return m_notes[index.row()].note.errorMessage;
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NotesModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
||||||
|
if (!index.isValid()) return false;
|
||||||
|
else if (role == modifiedRole) {
|
||||||
|
m_notes[index.row()].note.modified = value.toInt();
|
||||||
|
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } );
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == categoryRole) {
|
||||||
|
m_notes[index.row()].note.category = value.toString();
|
||||||
|
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } );
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == contentRole) {
|
||||||
|
m_notes[index.row()].note.content = value.toString();
|
||||||
|
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } );
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (role == favoriteRole) {
|
||||||
|
m_notes[index.row()].note.favorite = value.toBool();
|
||||||
|
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } );
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NotesModel::sort() {
|
void NotesModel::sort() {
|
||||||
QList<Note> notes;
|
QList<ModelNote<Note, bool> > notes;
|
||||||
QMap<QString, Note> map;
|
QMap<QString, ModelNote<Note, bool> > map;
|
||||||
QMap<QString, Note> favorites;
|
QMap<QString, ModelNote<Note, bool> > favorites;
|
||||||
switch (m_sortBy) {
|
switch (m_sortBy) {
|
||||||
case sortByDate:
|
case sortByDate:
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
foreach (const Note ¬e, m_notes) {
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
if (m_favoritesOnTop && note.favorite)
|
if (m_favoritesOnTop && m_notes[i].note.favorite)
|
||||||
favorites.insert(QString::number(note.modified), note);
|
favorites.insert(QString::number(m_notes[i].note.modified), m_notes[i]);
|
||||||
else
|
else
|
||||||
map.insert(QString::number(note.modified), note);
|
map.insert(QString::number(m_notes[i].note.modified), m_notes[i]);
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
notes = favorites.values();
|
||||||
notes.append(map.values());
|
notes.append(map.values());
|
||||||
m_notes = notes;
|
m_notes = notes;
|
||||||
emit layoutChanged();
|
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
break;
|
break;
|
||||||
case sortByCategory:
|
case sortByCategory:
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
foreach (const Note ¬e, m_notes) {
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
if (m_favoritesOnTop && note.favorite)
|
if (m_favoritesOnTop && m_notes[i].note.favorite)
|
||||||
favorites.insert(note.category, note);
|
favorites.insert(m_notes[i].note.category, m_notes[i]);
|
||||||
else
|
else
|
||||||
map.insert(note.category, note);
|
map.insert(m_notes[i].note.category, m_notes[i]);
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
notes = favorites.values();
|
||||||
notes.append(map.values());
|
notes.append(map.values());
|
||||||
m_notes = notes;
|
m_notes = notes;
|
||||||
emit layoutChanged();
|
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
break;
|
break;
|
||||||
case sortByTitle:
|
case sortByTitle:
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
foreach (const Note ¬e, m_notes) {
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
if (m_favoritesOnTop && note.favorite)
|
if (m_favoritesOnTop && m_notes[i].note.favorite)
|
||||||
favorites.insert(note.title, note);
|
favorites.insert(m_notes[i].note.title, m_notes[i]);
|
||||||
else
|
else
|
||||||
map.insert(note.title, note);
|
map.insert(m_notes[i].note.title, m_notes[i]);
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
notes = favorites.values();
|
||||||
notes.append(map.values());
|
notes.append(map.values());
|
||||||
m_notes = notes;
|
m_notes = notes;
|
||||||
emit layoutChanged();
|
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NotesModel::insertPosition(const Note &n) const {
|
||||||
|
int lower = 0;
|
||||||
|
int upper = m_notes.size();
|
||||||
|
while (lower < upper) {
|
||||||
|
int middle = qFloor(lower + (upper-lower) / 2);
|
||||||
|
bool result = noteLessThan(n, m_notes[middle].note);
|
||||||
|
if (result)
|
||||||
|
upper = middle;
|
||||||
|
else
|
||||||
|
lower = middle + 1;
|
||||||
|
}
|
||||||
|
return lower;
|
||||||
|
}
|
||||||
|
|
||||||
/*bool NotesModel::noteLessThanByDate(const Note &n1, const Note &n2) {
|
/*bool NotesModel::noteLessThanByDate(const Note &n1, const Note &n2) {
|
||||||
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
if (m_favoritesOnTop && n1.favorite != n2.favorite)
|
||||||
return n1.favorite;
|
return n1.favorite;
|
||||||
|
@ -251,53 +377,7 @@ bool NotesModel::noteLessThanByTitle(const Note &n1, const Note &n2) {
|
||||||
return n1.title < n2.title;
|
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) {
|
bool NotesModel::insertRow(int row, const QModelIndex &parent) {
|
||||||
beginInsertRows(parent, row, row);
|
beginInsertRows(parent, row, row);
|
||||||
m_notes.insert(row, Note());
|
m_notes.insert(row, Note());
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
|
|
||||||
struct Note;
|
struct Note;
|
||||||
|
|
||||||
|
template <typename N, typename P>
|
||||||
|
struct ModelNote {
|
||||||
|
N note;
|
||||||
|
P param;
|
||||||
|
};
|
||||||
|
|
||||||
class NotesModel : public QAbstractListModel {
|
class NotesModel : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -14,20 +20,23 @@ public:
|
||||||
virtual ~NotesModel();
|
virtual ~NotesModel();
|
||||||
|
|
||||||
Q_PROPERTY(int sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
|
Q_PROPERTY(int sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
|
||||||
int sortBy() { return m_sortBy; }
|
int sortBy() const { return m_sortBy; }
|
||||||
void setSortBy(int sortBy);
|
void setSortBy(int sortBy);
|
||||||
|
|
||||||
Q_PROPERTY(bool favoritesOnTop READ favoritesOnTop WRITE setFavoritesOnTop NOTIFY favoritesOnTopChanged)
|
Q_PROPERTY(bool favoritesOnTop READ favoritesOnTop WRITE setFavoritesOnTop NOTIFY favoritesOnTopChanged)
|
||||||
bool favoritesOnTop() { return m_favoritesOnTop; }
|
bool favoritesOnTop() const { return m_favoritesOnTop; }
|
||||||
void setFavoritesOnTop(bool favoritesOnTop);
|
void setFavoritesOnTop(bool favoritesOnTop);
|
||||||
|
|
||||||
Q_INVOKABLE bool applyJSON(QString json, bool replaceIfArray = true);
|
Q_INVOKABLE bool applyJSON(QString json, bool replaceIfArray = true);
|
||||||
Q_INVOKABLE bool removeNote(int id);
|
Q_INVOKABLE bool removeNote(int id);
|
||||||
|
|
||||||
Q_INVOKABLE void search(QString query) const;
|
Q_INVOKABLE void search(QString query);
|
||||||
Q_INVOKABLE void clearSearch() const;
|
Q_INVOKABLE void clearSearch();
|
||||||
|
|
||||||
|
Q_INVOKABLE int indexOf(int id) const;
|
||||||
|
|
||||||
enum NoteRoles {
|
enum NoteRoles {
|
||||||
|
visible = Qt::UserRole,
|
||||||
idRole = Qt::UserRole + 1,
|
idRole = Qt::UserRole + 1,
|
||||||
modifiedRole = Qt::UserRole + 2,
|
modifiedRole = Qt::UserRole + 2,
|
||||||
titleRole = Qt::UserRole + 3,
|
titleRole = Qt::UserRole + 3,
|
||||||
|
@ -51,7 +60,7 @@ public:
|
||||||
virtual int rowCount(const QModelIndex &parent) const;
|
virtual int rowCount(const QModelIndex &parent) const;
|
||||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||||
//virtual QVariant headerData(int section, Qt::Orientation orientation, 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);
|
virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
|
|
||||||
//bool insertRow(int row, const QModelIndex &parent);
|
//bool insertRow(int row, const QModelIndex &parent);
|
||||||
//bool insertRows(int row, int count, const QModelIndex &parent);
|
//bool insertRows(int row, int count, const QModelIndex &parent);
|
||||||
|
@ -59,20 +68,25 @@ public:
|
||||||
//bool removeRows(int row, int count, const QModelIndex &parent);
|
//bool removeRows(int row, int count, const QModelIndex &parent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bool noteLessThanByDate(const Note &n1, const Note &n2);
|
bool noteLessThan(const Note &n1, const Note &n2) const;
|
||||||
|
/*static bool noteLessThanByDate(const Note &n1, const Note &n2);
|
||||||
static bool noteLessThanByCategory(const Note &n1, const Note &n2);
|
static bool noteLessThanByCategory(const Note &n1, const Note &n2);
|
||||||
static bool noteLessThanByTitle(const Note &n1, const Note &n2);
|
static bool noteLessThanByTitle(const Note &n1, const Note &n2);*/
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ());
|
||||||
void sortByChanged(int sortBy);
|
void sortByChanged(int sortBy);
|
||||||
void favoritesOnTopChanged(bool favoritesOnTop);
|
void favoritesOnTopChanged(bool favoritesOnTop);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<Note> m_notes;
|
QList<ModelNote<Note, bool> > m_notes;
|
||||||
int m_sortBy;
|
int m_sortBy;
|
||||||
bool m_favoritesOnTop;
|
bool m_favoritesOnTop;
|
||||||
|
QString m_searchQuery;
|
||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
|
void update();
|
||||||
|
int insertPosition(const Note &n) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NOTESMODEL_H
|
#endif // NOTESMODEL_H
|
||||||
|
|
Loading…
Reference in a new issue