Implemented API in C++. Next: I discovered QSortFilterProxyModel :)
This commit is contained in:
parent
a026c2ee8d
commit
3f128bcd63
16 changed files with 334 additions and 660 deletions
|
@ -18,13 +18,11 @@ DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/notesapi.h \
|
src/notesapi.h \
|
||||||
src/sslconfiguration.h \
|
|
||||||
src/notesmodel.h \
|
src/notesmodel.h \
|
||||||
src/note.h
|
src/note.h
|
||||||
|
|
||||||
SOURCES += src/harbour-nextcloudnotes.cpp \
|
SOURCES += src/harbour-nextcloudnotes.cpp \
|
||||||
src/notesapi.cpp \
|
src/notesapi.cpp \
|
||||||
src/sslconfiguration.cpp \
|
|
||||||
src/notesmodel.cpp \
|
src/notesmodel.cpp \
|
||||||
src/note.cpp
|
src/note.cpp
|
||||||
|
|
||||||
|
@ -46,8 +44,7 @@ DISTFILES += qml/harbour-nextcloudnotes.qml \
|
||||||
qml/pages/NotesApi.qml \
|
qml/pages/NotesApi.qml \
|
||||||
qml/pages/MITLicense.qml \
|
qml/pages/MITLicense.qml \
|
||||||
qml/pages/GPLLicense.qml \
|
qml/pages/GPLLicense.qml \
|
||||||
qml/pages/SyntaxPage.qml \
|
qml/pages/SyntaxPage.qml
|
||||||
qml/components/NotesApi.qml
|
|
||||||
|
|
||||||
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||||
|
|
||||||
|
|
|
@ -1,175 +0,0 @@
|
||||||
import QtQuick 2.5
|
|
||||||
import Sailfish.Silica 1.0
|
|
||||||
import Nemo.Configuration 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
property string response
|
|
||||||
property var categories: [ ]
|
|
||||||
property string file: StandardPaths.data + "/" + appSettings.currentAccount + ".json"
|
|
||||||
property bool saveFile: false
|
|
||||||
property bool busy: jobsRunning > 0
|
|
||||||
property int jobsRunning: 0
|
|
||||||
property int status: 0 //204
|
|
||||||
property string statusText: "No Content"
|
|
||||||
|
|
||||||
onStatusChanged: {
|
|
||||||
//console.log("Network response: " + statusText + " (" + status + ")")
|
|
||||||
}
|
|
||||||
|
|
||||||
/*function getNote(id) {
|
|
||||||
var dict
|
|
||||||
if (id) {
|
|
||||||
for (var i = 0; i < model.count; i++) {
|
|
||||||
dict = model.get(i)
|
|
||||||
if (dict.id === id) {
|
|
||||||
return dict
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
function apiCall(method, data) {
|
|
||||||
jobsRunning++
|
|
||||||
|
|
||||||
var endpoint = account.server + "/index.php/apps/notes/api/" + account.version + "/notes"
|
|
||||||
if (data) {
|
|
||||||
if (method === "POST" || method === "PUT") {
|
|
||||||
console.log("Adding note...")
|
|
||||||
}
|
|
||||||
else if (data.id && method === "DELETE") {
|
|
||||||
console.log("Deleting note...")
|
|
||||||
}
|
|
||||||
if (method === "GET" || method === "PUT" || method === "DELETE") {
|
|
||||||
if (data.id) {
|
|
||||||
endpoint = endpoint + "/" + data.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Calling " + endpoint)
|
|
||||||
var apiReq = new XMLHttpRequest
|
|
||||||
apiReq.open(method, endpoint, true)
|
|
||||||
apiReq.setRequestHeader('User-Agent', 'SailfishOS/harbour-nextcloudnotes')
|
|
||||||
apiReq.setRequestHeader('OCS-APIRequest', 'true')
|
|
||||||
apiReq.setRequestHeader("Content-Type", "application/json")
|
|
||||||
apiReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(account.username + ":" + account.password))
|
|
||||||
apiReq.withCredentials = true
|
|
||||||
//apiReq.timeout = 5000
|
|
||||||
apiReq.onreadystatechange = function() {
|
|
||||||
if (apiReq.readyState === XMLHttpRequest.DONE) {
|
|
||||||
statusText = apiReq.statusText
|
|
||||||
status = apiReq.status
|
|
||||||
if (apiReq.status === 200) {
|
|
||||||
response = apiReq.responseText
|
|
||||||
//console.log(response)
|
|
||||||
console.log("Network response: " + statusText + " (" + status + ")")
|
|
||||||
}
|
|
||||||
else if(apiReq.status === 0) {
|
|
||||||
statusText = qsTr("Unable to connect")
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else if (apiReq.status === 304) {
|
|
||||||
console.log("ETag does not differ!")
|
|
||||||
}
|
|
||||||
else if (apiReq.status === 401) {
|
|
||||||
console.log("Unauthorized!")
|
|
||||||
}
|
|
||||||
else if (apiReq.status === 404) {
|
|
||||||
console.log("Note does not exist!")
|
|
||||||
}*/
|
|
||||||
else {
|
|
||||||
//console.log("Network error: " + apiReq.statusText + " (" + apiReq.status + ")")
|
|
||||||
}
|
|
||||||
jobsRunning--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (method === "GET") {
|
|
||||||
apiReq.send()
|
|
||||||
}
|
|
||||||
else if (method === "POST" || method === "PUT" || method === "DELETE") {
|
|
||||||
apiReq.send(JSON.stringify(data))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("Unsupported method: " + method)
|
|
||||||
apiReq.abort()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNotesFromApi() {
|
|
||||||
apiCall("GET")
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoteFromApi(id) {
|
|
||||||
if (id) {
|
|
||||||
apiCall("GET", { 'id': id } )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNote(data) {
|
|
||||||
if (data)
|
|
||||||
apiCall("POST", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateNote(id, data) {
|
|
||||||
if (id && data) {
|
|
||||||
data.id = id
|
|
||||||
apiCall("PUT", data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteNote(id) {
|
|
||||||
if (id)
|
|
||||||
apiCall("DELETE", { 'id': id } )
|
|
||||||
}
|
|
||||||
|
|
||||||
// source: https://stackoverflow.com/a/14339782
|
|
||||||
/*function getPrettyDate(date) {
|
|
||||||
var today = new Date()
|
|
||||||
today.setHours(0)
|
|
||||||
today.setMinutes(0)
|
|
||||||
today.setSeconds(0)
|
|
||||||
today.setMilliseconds(0)
|
|
||||||
var compDate = new Date(date*1000)
|
|
||||||
compDate.setHours(0)
|
|
||||||
compDate.setMinutes(0)
|
|
||||||
compDate.setSeconds(0)
|
|
||||||
compDate.setMilliseconds(0)
|
|
||||||
if (compDate.getTime() === today.getTime()) {
|
|
||||||
return qsTr("Today")
|
|
||||||
} else if ((today.getTime() - compDate.getTime()) === (24 * 60 * 60 * 1000)) {
|
|
||||||
return qsTr("Yesterday")
|
|
||||||
} else if ((today.getTime() - compDate.getTime()) <= (7 * 24 * 60 * 60 * 1000)) {
|
|
||||||
return compDate.toLocaleDateString(Qt.locale(), "dddd")
|
|
||||||
} else if (today.getFullYear() === compDate.getFullYear()) {
|
|
||||||
return compDate.toLocaleDateString(Qt.locale(), "MMMM")
|
|
||||||
} else {
|
|
||||||
return compDate.toLocaleDateString(Qt.locale(), "MMMM yyyy")
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*Component.onCompleted: {
|
|
||||||
if (saveFile) {
|
|
||||||
if (account.name === "") {
|
|
||||||
saveFile = false
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
busy = true
|
|
||||||
var fileReq = new XMLHttpRequest
|
|
||||||
fileReq.open("GET", file)
|
|
||||||
fileReq.onreadystatechange = function() {
|
|
||||||
if (fileReq.readyState === XMLHttpRequest.DONE) {
|
|
||||||
if (fileReq.responseText === "") {
|
|
||||||
update()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("Loaded " + account.name + " from local JSON file")
|
|
||||||
json = fileReq.responseText
|
|
||||||
busy = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileReq.send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
|
@ -2,10 +2,7 @@ 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 harbour.nextcloudnotes.notesapi 1.0
|
import harbour.nextcloudnotes.notesapi 1.0
|
||||||
import harbour.nextcloudnotes.notesmodel 1.0
|
|
||||||
import harbour.nextcloudnotes.sslconfiguration 1.0
|
|
||||||
import "pages"
|
import "pages"
|
||||||
//import "components"
|
|
||||||
|
|
||||||
ApplicationWindow
|
ApplicationWindow
|
||||||
{
|
{
|
||||||
|
@ -26,8 +23,8 @@ ApplicationWindow
|
||||||
property string version: value("version", "v0.2", String)
|
property string version: value("version", "v0.2", String)
|
||||||
property string username: value("username", "", String)
|
property string username: value("username", "", String)
|
||||||
property string password: account.value("password", "", String)
|
property string password: account.value("password", "", String)
|
||||||
property bool unsecureConnection: account.value("unsecureConnection", false, Boolean)
|
property bool doNotVerifySsl: account.value("doNotVerifySsl", false, Boolean)
|
||||||
property bool unencryptedConnection: account.value("unencryptedConnection", false, Boolean)
|
property bool allowUnecrypted: account.value("allowUnecrypted", 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")
|
||||||
onNameChanged: console.log("Account: " + name)
|
onNameChanged: console.log("Account: " + name)
|
||||||
|
@ -37,6 +34,7 @@ ApplicationWindow
|
||||||
id: appSettings
|
id: appSettings
|
||||||
path: "/apps/harbour-nextcloudnotes/settings"
|
path: "/apps/harbour-nextcloudnotes/settings"
|
||||||
|
|
||||||
|
property bool initialized: false
|
||||||
property string currentAccount: value("currentAccount", "", String)
|
property string currentAccount: value("currentAccount", "", String)
|
||||||
property var accountIDs: value("accountIDs", [ ], Array)
|
property var accountIDs: value("accountIDs", [ ], Array)
|
||||||
property int autoSyncInterval: value("autoSyncInterval", 0, Number)
|
property int autoSyncInterval: value("autoSyncInterval", 0, Number)
|
||||||
|
@ -48,10 +46,12 @@ ApplicationWindow
|
||||||
property bool useCapitalX: value("useCapitalX", false, Boolean)
|
property bool useCapitalX: value("useCapitalX", false, Boolean)
|
||||||
onCurrentAccountChanged: {
|
onCurrentAccountChanged: {
|
||||||
account.path = "/apps/harbour-nextcloudnotes/accounts/" + currentAccount
|
account.path = "/apps/harbour-nextcloudnotes/accounts/" + currentAccount
|
||||||
//noteListModel.clear()
|
account.sync()
|
||||||
//api.getNotesFromApi()
|
if (initialized)
|
||||||
api.getAllNotes();
|
notesApi.getAllNotes();
|
||||||
|
autoSyncTimer.restart()
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: initialized = true
|
||||||
|
|
||||||
function addAccount() {
|
function addAccount() {
|
||||||
var uuid = uuidv4()
|
var uuid = uuidv4()
|
||||||
|
@ -88,26 +88,18 @@ ApplicationWindow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*SslConfiguration {
|
|
||||||
id: ssl
|
|
||||||
checkCert: !account.unsecureConnection
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: autoSyncTimer
|
id: autoSyncTimer
|
||||||
interval: appSettings.autoSyncInterval * 1000
|
interval: appSettings.autoSyncInterval * 1000
|
||||||
repeat: true
|
repeat: true
|
||||||
running: interval > 0 && appWindow.visible
|
running: interval > 0 && appWindow.visible
|
||||||
triggeredOnStart: true
|
triggeredOnStart: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (!api.busy) {
|
if (!notesApi.busy) {
|
||||||
//api.getNotesFromApi()
|
notesApi.getAllNotes();
|
||||||
api.getAllNotes();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
triggeredOnStart = false
|
|
||||||
restart()
|
restart()
|
||||||
triggeredOnStart = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onIntervalChanged: {
|
onIntervalChanged: {
|
||||||
|
@ -118,33 +110,16 @@ ApplicationWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
NotesApi {
|
NotesApi {
|
||||||
id: api
|
id: notesApi
|
||||||
/*scheme: "https"
|
scheme: account.allowUnecrypted ? "http" : "https"
|
||||||
host: account.server
|
host: account.server
|
||||||
path: "/index.php/apps/notes/api/" + account.version
|
path: "/index.php/apps/notes/api/" + account.version
|
||||||
username: account.username
|
username: account.username
|
||||||
password: account.password*/
|
password: account.password
|
||||||
|
sslVerify: !account.doNotVerifySsl
|
||||||
|
Component.onCompleted: getAllNotes()
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
api.scheme = "https"
|
|
||||||
api.host = account.server
|
|
||||||
api.path = "/index.php/apps/notes/api/" + account.version
|
|
||||||
api.username = account.username
|
|
||||||
api.password = account.password
|
|
||||||
}
|
|
||||||
|
|
||||||
/*NotesApi {
|
|
||||||
id: api
|
|
||||||
onResponseChanged: noteListModel.applyJSON(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*NotesModel {
|
|
||||||
id: noteListModel
|
|
||||||
sortBy: appSettisignangs.sortBy
|
|
||||||
favoritesOnTop: appSettings.favoritesOnTop
|
|
||||||
}*/
|
|
||||||
|
|
||||||
initialPage: Component { NotesPage { } }
|
initialPage: Component { NotesPage { } }
|
||||||
cover: Qt.resolvedUrl("cover/CoverPage.qml")
|
cover: Qt.resolvedUrl("cover/CoverPage.qml")
|
||||||
allowedOrientations: defaultAllowedOrientations
|
allowedOrientations: defaultAllowedOrientations
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import harbour.nextcloudnotes.note 1.0
|
import harbour.nextcloudnotes.note 1.0
|
||||||
import "../components"
|
import harbour.nextcloudnotes.notesmodel 1.0
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
id: page
|
id: page
|
||||||
|
|
||||||
property string searchText: ""
|
property NotesModel notesModel: notesApi.model()
|
||||||
|
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status === PageStatus.Active) {
|
if (status === PageStatus.Active) {
|
||||||
|
@ -25,7 +25,7 @@ Page {
|
||||||
spacing: Theme.paddingLarge
|
spacing: Theme.paddingLarge
|
||||||
|
|
||||||
PullDownMenu {
|
PullDownMenu {
|
||||||
busy: api.busy
|
busy: notesApi.busy
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Settings")
|
text: qsTr("Settings")
|
||||||
|
@ -34,12 +34,12 @@ Page {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Add note")
|
text: qsTr("Add note")
|
||||||
enabled: appSettings.currentAccount.length > 0
|
enabled: appSettings.currentAccount.length > 0
|
||||||
onClicked: api.createNote( { 'content': "" } )
|
onClicked: notesApi.createNote( { 'content': "" } )
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: enabled ? qsTr("Reload") : qsTr("Updating...")
|
text: enabled ? qsTr("Reload") : qsTr("Updating...")
|
||||||
enabled: appSettings.currentAccount.length > 0 && !api.busy
|
enabled: appSettings.currentAccount.length > 0 && !notesApi.busy
|
||||||
onClicked: api.getNotesFromApi()
|
onClicked: notesApi.getAllNotes()
|
||||||
}
|
}
|
||||||
MenuLabel {
|
MenuLabel {
|
||||||
visible: appSettings.currentAccount.length > 0
|
visible: appSettings.currentAccount.length > 0
|
||||||
|
@ -59,7 +59,7 @@ Page {
|
||||||
placeholderText: account.name.length > 0 ? account.name : qsTr("Nextcloud Notes")
|
placeholderText: account.name.length > 0 ? account.name : qsTr("Nextcloud Notes")
|
||||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||||
EnterKey.onClicked: focus = false
|
EnterKey.onClicked: focus = false
|
||||||
onTextChanged: noteListModel.searchText = text
|
onTextChanged: notesModel.searchText = text
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
id: description
|
id: description
|
||||||
|
@ -70,24 +70,25 @@ Page {
|
||||||
anchors.bottomMargin: Theme.paddingMedium
|
anchors.bottomMargin: Theme.paddingMedium
|
||||||
color: Theme.secondaryHighlightColor
|
color: Theme.secondaryHighlightColor
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
text: account.username + "@" + account.server.toString().split("://")[1]
|
text: account.username + "@" + account.server
|
||||||
}
|
}
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
anchors.verticalCenter: searchField.verticalCenter
|
anchors.verticalCenter: searchField.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Theme.horizontalPageMargin
|
anchors.rightMargin: Theme.horizontalPageMargin
|
||||||
size: BusyIndicatorSize.Medium
|
size: BusyIndicatorSize.Medium
|
||||||
running: api.busy && !busyIndicator.running
|
running: notesApi.busy && !busyIndicator.running
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIndex: -1
|
currentIndex: -1
|
||||||
|
|
||||||
model: api.model()
|
model: notesModel
|
||||||
|
|
||||||
delegate: BackgroundItem {
|
delegate: BackgroundItem {
|
||||||
id: note
|
id: note
|
||||||
|
|
||||||
|
visible: inSearch
|
||||||
contentHeight: titleLabel.height + previewLabel.height + 2*Theme.paddingSmall
|
contentHeight: titleLabel.height + previewLabel.height + 2*Theme.paddingSmall
|
||||||
height: contentHeight + menu.height
|
height: contentHeight + menu.height
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -103,7 +104,7 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NotePage.qml"),
|
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NotePage.qml"),
|
||||||
{ note: noteListModel.get(index),
|
{ //note: noteListModel.get(index),
|
||||||
id: id,
|
id: id,
|
||||||
modified: modified,
|
modified: modified,
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -112,8 +113,8 @@ Page {
|
||||||
favorite: favorite,
|
favorite: favorite,
|
||||||
etag: etag,
|
etag: etag,
|
||||||
error: error,
|
error: error,
|
||||||
errorMessage: errorMessage,
|
errorMessage: errorMessage
|
||||||
date: date
|
//date: date
|
||||||
})
|
})
|
||||||
onPressAndHold: menu.open(note)
|
onPressAndHold: menu.open(note)
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ Page {
|
||||||
icon.source: (favorite ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") +
|
icon.source: (favorite ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") +
|
||||||
(note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
|
(note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
api.updateNote(id, {'favorite': !favorite} )
|
notesApi.updateNote(id, {'favorite': !favorite} )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +202,7 @@ Page {
|
||||||
text: qsTr("Delete")
|
text: qsTr("Delete")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
remorse.execute(note, qsTr("Deleting note"), function() {
|
remorse.execute(note, qsTr("Deleting note"), function() {
|
||||||
api.deleteNote(id)
|
notesApi.deleteNote(id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +220,7 @@ Page {
|
||||||
id: busyIndicator
|
id: busyIndicator
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
size: BusyIndicatorSize.Large
|
size: BusyIndicatorSize.Large
|
||||||
running: notesList.count === 0 && api.busy
|
running: notesList.count === 0 && notesApi.busy
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
id: busyLabel
|
id: busyLabel
|
||||||
|
@ -232,7 +233,7 @@ Page {
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
text: qsTr("Loading notes...")
|
text: qsTr("Loading notes...")
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
ViewPlaceholder {
|
ViewPlaceholder {
|
||||||
id: noLoginPlaceholder
|
id: noLoginPlaceholder
|
||||||
enabled: appSettings.accountIDs.length <= 0
|
enabled: appSettings.accountIDs.length <= 0
|
||||||
|
@ -242,14 +243,14 @@ Page {
|
||||||
|
|
||||||
ViewPlaceholder {
|
ViewPlaceholder {
|
||||||
id: noNotesPlaceholder
|
id: noNotesPlaceholder
|
||||||
enabled: api.status === 204 && !busyIndicator.running && !noLoginPlaceholder.enabled
|
enabled: notesApi.status === 204 && !busyIndicator.running && !noLoginPlaceholder.enabled
|
||||||
text: qsTr("No notes yet")
|
text: qsTr("No notes yet")
|
||||||
hintText: qsTr("Pull down to add a note")
|
hintText: qsTr("Pull down to add a note")
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPlaceholder {
|
ViewPlaceholder {
|
||||||
id: noSearchPlaceholder
|
id: noSearchPlaceholder
|
||||||
enabled: notesList.count === 0 && noteListModel.searchText !== ""
|
enabled: notesList.count === 0 && notesModel.searchText !== ""
|
||||||
text: qsTr("No result")
|
text: qsTr("No result")
|
||||||
hintText: qsTr("Try another query")
|
hintText: qsTr("Try another query")
|
||||||
}
|
}
|
||||||
|
@ -258,9 +259,9 @@ Page {
|
||||||
id: errorPlaceholder
|
id: errorPlaceholder
|
||||||
enabled: notesList.count === 0 && !busyIndicator.running && !noSearchPlaceholder.enabled && !noNotesPlaceholder.enabled && !noLoginPlaceholder.enabled
|
enabled: notesList.count === 0 && !busyIndicator.running && !noSearchPlaceholder.enabled && !noNotesPlaceholder.enabled && !noLoginPlaceholder.enabled
|
||||||
text: qsTr("An error occurred")
|
text: qsTr("An error occurred")
|
||||||
hintText: api.statusText
|
hintText: notesApi.statusText
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
TouchInteractionHint {
|
TouchInteractionHint {
|
||||||
id: addAccountHint
|
id: addAccountHint
|
||||||
interactionMode: TouchInteraction.Pull
|
interactionMode: TouchInteraction.Pull
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "notesapi.h"
|
#include "notesapi.h"
|
||||||
#include "note.h"
|
#include "note.h"
|
||||||
#include "notesmodel.h"
|
#include "notesmodel.h"
|
||||||
#include "sslconfiguration.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -20,7 +19,6 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterType<NotesApi>("harbour.nextcloudnotes.notesapi", 1, 0, "NotesApi");
|
qmlRegisterType<NotesApi>("harbour.nextcloudnotes.notesapi", 1, 0, "NotesApi");
|
||||||
qmlRegisterType<Note>("harbour.nextcloudnotes.note", 1, 0, "Note");
|
qmlRegisterType<Note>("harbour.nextcloudnotes.note", 1, 0, "Note");
|
||||||
qmlRegisterType<NotesModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel");
|
qmlRegisterType<NotesModel>("harbour.nextcloudnotes.notesmodel", 1, 0, "NotesModel");
|
||||||
qmlRegisterType<SslConfiguration>("harbour.nextcloudnotes.sslconfiguration", 1, 0, "SslConfiguration");
|
|
||||||
|
|
||||||
QQuickView* view = SailfishApp::createView();
|
QQuickView* view = SailfishApp::createView();
|
||||||
|
|
||||||
|
|
36
src/note.cpp
36
src/note.cpp
|
@ -42,7 +42,7 @@ Note& Note::operator=(const Note& note) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Note::operator==(const Note& note) const {
|
bool Note::operator==(const Note& note) const {
|
||||||
return same(note);
|
return equal(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Note::same(const Note& note) const {
|
bool Note::same(const Note& note) const {
|
||||||
|
@ -118,3 +118,37 @@ bool Note::searchInNote(const QString &query, const Note ¬e, SearchAttributes
|
||||||
}
|
}
|
||||||
return queryFound;
|
return queryFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByDate(const Note &n1, const Note &n2) {
|
||||||
|
return n1.modified() > n2.modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByCategory(const Note &n1, const Note &n2) {
|
||||||
|
return n1.category() > n2.category();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByTitle(const Note &n1, const Note &n2) {
|
||||||
|
return n1.title() > n2.title();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByDateFavOnTop(const Note &n1, const Note &n2) {
|
||||||
|
if (n1.favorite() != n2.favorite())
|
||||||
|
return n1.favorite();
|
||||||
|
else
|
||||||
|
return n1.modified() > n2.modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByCategoryFavOnTop(const Note &n1, const Note &n2) {
|
||||||
|
if (n1.favorite() != n2.favorite())
|
||||||
|
return n1.favorite();
|
||||||
|
else
|
||||||
|
return n1.category() > n2.category();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Note::lessThanByTitleFavOnTop(const Note &n1, const Note &n2) {
|
||||||
|
if (n1.favorite() != n2.favorite())
|
||||||
|
return n1.favorite();
|
||||||
|
else
|
||||||
|
return n1.title() > n2.title();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,12 @@ public:
|
||||||
|
|
||||||
static Note fromjson(const QJsonObject& jobj);
|
static Note fromjson(const QJsonObject& jobj);
|
||||||
static bool searchInNote(const QString &query, const Note ¬e, SearchAttributes criteria = QFlag(SearchAll), Qt::CaseSensitivity cs = Qt::CaseInsensitive);
|
static bool searchInNote(const QString &query, const Note ¬e, SearchAttributes criteria = QFlag(SearchAll), Qt::CaseSensitivity cs = Qt::CaseInsensitive);
|
||||||
|
static bool lessThanByDate(const Note &n1, const Note &n2);
|
||||||
|
static bool lessThanByCategory(const Note &n1, const Note &n2);
|
||||||
|
static bool lessThanByTitle(const Note &n1, const Note &n2);
|
||||||
|
static bool lessThanByDateFavOnTop(const Note &n1, const Note &n2);
|
||||||
|
static bool lessThanByCategoryFavOnTop(const Note &n1, const Note &n2);
|
||||||
|
static bool lessThanByTitleFavOnTop(const Note &n1, const Note &n2);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void idChanged(int id);
|
void idChanged(int id);
|
||||||
|
|
|
@ -147,24 +147,24 @@ void NotesApi::getNote(int noteId, QStringList excludeFields) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesApi::createNote(QVariantHash fields) {
|
void NotesApi::createNote(QVariantMap fields) {
|
||||||
QUrl url = m_url;
|
QUrl url = m_url;
|
||||||
url.setPath(url.path() + "/notes");
|
url.setPath(url.path() + "/notes");
|
||||||
if (url.isValid()) {
|
if (url.isValid()) {
|
||||||
qDebug() << "POST" << url.toDisplayString();
|
qDebug() << "POST" << url.toDisplayString();
|
||||||
m_request.setUrl(url);
|
m_request.setUrl(url);
|
||||||
m_replies << m_manager.post(m_request, QJsonDocument(QJsonObject::fromVariantHash(fields)).toJson());
|
m_replies << m_manager.post(m_request, QJsonDocument(QJsonObject::fromVariantMap(fields)).toJson());
|
||||||
emit busyChanged(busy());
|
emit busyChanged(busy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesApi::updateNote(int noteId, QVariantHash fields) {
|
void NotesApi::updateNote(int noteId, QVariantMap fields) {
|
||||||
QUrl url = m_url;
|
QUrl url = m_url;
|
||||||
url.setPath(url.path() + QString("/notes/%1").arg(noteId));
|
url.setPath(url.path() + QString("/notes/%1").arg(noteId));
|
||||||
if (url.isValid()) {
|
if (url.isValid()) {
|
||||||
qDebug() << "PUT" << url.toDisplayString();
|
qDebug() << "PUT" << url.toDisplayString();
|
||||||
m_request.setUrl(url);
|
m_request.setUrl(url);
|
||||||
m_replies << m_manager.put(m_request, QJsonDocument(QJsonObject::fromVariantHash(fields)).toJson());
|
m_replies << m_manager.put(m_request, QJsonDocument(QJsonObject::fromVariantMap(fields)).toJson());
|
||||||
emit busyChanged(busy());
|
emit busyChanged(busy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ void NotesApi::replyFinished(QNetworkReply *reply) {
|
||||||
//qDebug() << json;
|
//qDebug() << json;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << reply->errorString();
|
qDebug() << reply->error() << reply->errorString();
|
||||||
}
|
}
|
||||||
m_replies.removeAll(reply);
|
m_replies.removeAll(reply);
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "notesmodel.h"
|
#include "notesmodel.h"
|
||||||
|
|
||||||
|
@ -58,10 +59,10 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList());
|
Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList());
|
||||||
Q_INVOKABLE void getNote(int noteId, QStringList excludeFields = QStringList());
|
Q_INVOKABLE void getNote(int noteId, QStringList excludeFields = QStringList());
|
||||||
Q_INVOKABLE void createNote(QVariantHash fields = QVariantHash());
|
Q_INVOKABLE void createNote(QVariantMap fields = QVariantMap());
|
||||||
Q_INVOKABLE void updateNote(int noteId, QVariantHash fields = QVariantHash());
|
Q_INVOKABLE void updateNote(int noteId, QVariantMap fields = QVariantMap());
|
||||||
Q_INVOKABLE void deleteNote(int noteId);
|
Q_INVOKABLE void deleteNote(int noteId);
|
||||||
Q_INVOKABLE NotesModel& model() const { return *mp_model; }
|
Q_INVOKABLE NotesModel* model() const { return mp_model; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sslVerifyChanged(bool verify);
|
void sslVerifyChanged(bool verify);
|
||||||
|
@ -91,6 +92,7 @@ private:
|
||||||
QNetworkRequest m_request;
|
QNetworkRequest m_request;
|
||||||
QVector<QNetworkReply*> m_replies;
|
QVector<QNetworkReply*> m_replies;
|
||||||
NotesModel* mp_model;
|
NotesModel* mp_model;
|
||||||
|
QSortFilterProxyModel* mp_modelProxy; // TODO: use!
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NOTESAPI_H
|
#endif // NOTESAPI_H
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "notesmodel.h"
|
#include "notesmodel.h"
|
||||||
|
#include <algorithm> // std::sort
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
@ -8,11 +9,11 @@
|
||||||
NotesModel::NotesModel(QObject *parent) : QAbstractListModel(parent)
|
NotesModel::NotesModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
m_sortBy = noSorting;
|
m_sortBy = noSorting;
|
||||||
m_favoritesOnTop = false;
|
m_favoritesOnTop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotesModel::~NotesModel() {
|
NotesModel::~NotesModel() {
|
||||||
clear();
|
//clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesModel::setSortBy(QString sortBy) {
|
void NotesModel::setSortBy(QString sortBy) {
|
||||||
|
@ -37,15 +38,24 @@ void NotesModel::setSearchText(QString searchText) {
|
||||||
qDebug() << "Searching by:" << searchText;
|
qDebug() << "Searching by:" << searchText;
|
||||||
if (searchText != m_searchText) {
|
if (searchText != m_searchText) {
|
||||||
m_searchText = searchText;
|
m_searchText = searchText;
|
||||||
for (int i = 0; i < m_notes.size(); i++) {
|
emit searchTextChanged(m_searchText);
|
||||||
if (m_searchText.isEmpty()) {
|
if (m_searchText.isEmpty()) {
|
||||||
m_notes[i].param = true;
|
m_invisibleIds.clear();
|
||||||
}
|
emit dataChanged(this->index(0), this->index(m_notes.size()));
|
||||||
else {
|
}
|
||||||
m_notes[i].param = Note::searchInNote(m_searchText, m_notes[i].note);
|
else {
|
||||||
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
|
if (Note::searchInNote(m_searchText, m_notes[i])) {
|
||||||
|
//qDebug() << "Note" << m_notes[i].title() << "in search";
|
||||||
|
m_invisibleIds.removeAll(m_notes[i].id());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//qDebug() << "Note" << m_notes[i].title() << "not in search";
|
||||||
|
m_invisibleIds.append(m_notes[i].id());
|
||||||
|
}
|
||||||
|
emit dataChanged(this->index(i), this->index(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit searchTextChanged(m_searchText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,54 +67,46 @@ void NotesModel::clearSearch() {
|
||||||
search();
|
search();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotesModel::applyJSONobject(const QJsonObject &jobj) {
|
|
||||||
if (!jobj.isEmpty()) {
|
|
||||||
Note note = Note::fromjson(jobj); // TODO connect signals
|
|
||||||
if (!note.error()) {
|
|
||||||
int position = indexOf(note.id());
|
|
||||||
Note oldNote = get(position);
|
|
||||||
if (position >= 0 && note.etag() != oldNote.etag()) {
|
|
||||||
qDebug() << "-- Existing note " << note.title() << "changed, updating the model.";
|
|
||||||
replaceNote(note);
|
|
||||||
}
|
|
||||||
else if (position < 0) {
|
|
||||||
qDebug() << "-- New note" << note.title() << ", adding it to the model.";
|
|
||||||
insertNote(note);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "-- Existing note " << note.title() << "unchanged, nothing to do.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "Note contains an error:" << note.errorMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "Unknown JSON object. This message should never occure!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NotesModel::applyJSON(const QJsonDocument &jdoc) {
|
bool NotesModel::applyJSON(const QJsonDocument &jdoc) {
|
||||||
qDebug() << "Applying new JSON input";// << json;
|
qDebug() << "Applying new JSON input";// << json;
|
||||||
if (!jdoc.isNull()) {
|
if (!jdoc.isNull()) {
|
||||||
if (jdoc.isArray()) {
|
if (jdoc.isArray()) {
|
||||||
qDebug() << "- It's an array...";
|
qDebug() << "- It's an array...";
|
||||||
|
QVector<Note> newNotes;
|
||||||
QJsonArray jarr = jdoc.array();
|
QJsonArray jarr = jdoc.array();
|
||||||
while (!jarr.empty()) {
|
while (!jarr.empty()) {
|
||||||
//qDebug() << jarr.count() << "JSON Objects to handle...";
|
//qDebug() << jarr.count() << "JSON Objects to handle...";
|
||||||
QJsonValue jval = jarr.first();
|
QJsonValue jval = jarr.first();
|
||||||
if (jval.isObject()) {
|
if (jval.isObject()) {
|
||||||
//qDebug() << "It's an object, all fine...";
|
//qDebug() << "It's an object, all fine...";
|
||||||
applyJSONobject(jval.toObject());
|
QJsonObject jobj = jval.toObject();
|
||||||
|
if (!jobj.isEmpty()) {
|
||||||
|
newNotes.append(Note::fromjson(jobj));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
jarr.pop_front();
|
jarr.pop_front();
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < m_notes.size(); ++i) {
|
||||||
|
bool noteToBeRemoved = true;
|
||||||
|
for (int j = 0; j < newNotes.size(); ++j) {
|
||||||
|
if (m_notes[i].id() == newNotes[j].id())
|
||||||
|
noteToBeRemoved = false;
|
||||||
|
}
|
||||||
|
if (noteToBeRemoved) {
|
||||||
|
qDebug() << "-- Removing note " << m_notes[i].title();
|
||||||
|
removeNote(m_notes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!newNotes.empty()) {
|
||||||
|
insertNote(newNotes.first());
|
||||||
|
newNotes.pop_front();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (jdoc.isObject()) {
|
else if (jdoc.isObject()) {
|
||||||
qDebug() << "- It's a single object...";
|
qDebug() << "- It's a single object...";
|
||||||
return applyJSONobject(jdoc.object());
|
insertNote(Note::fromjson(jdoc.object()));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << "Unknown JSON document. This message should never occure!";
|
qDebug() << "Unknown JSON document. This message should never occure!";
|
||||||
|
@ -127,22 +129,29 @@ bool NotesModel::applyJSON(const QString &json) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int NotesModel::insertNote(const Note ¬e) {
|
int NotesModel::insertNote(const Note ¬e) {
|
||||||
int position = insertPosition(note);
|
int position = indexOf(note.id());
|
||||||
ModelNote<Note, bool> modelNote;
|
if (position >= 0) {
|
||||||
modelNote.note = note;
|
if (note.etag() != m_notes[position].etag()) {
|
||||||
modelNote.param = true;
|
qDebug() << "-- Existing note " << note.title() << "changed, updating the model.";
|
||||||
beginInsertRows(QModelIndex(), position, position);
|
m_notes.replace(position, note);
|
||||||
m_notes.insert(position, modelNote);
|
emit dataChanged(this->index(position), this->index(position));
|
||||||
endInsertRows();
|
}
|
||||||
|
else {
|
||||||
|
qDebug() << "-- Existing note " << note.title() << "unchanged, nothing to do.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug() << "-- New note" << note.title() << ", adding it to the model.";
|
||||||
|
position = insertPosition(note);
|
||||||
|
beginInsertRows(QModelIndex(), position, position);
|
||||||
|
m_notes.insert(position, note);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotesModel::removeNote(const Note ¬e) {
|
bool NotesModel::removeNote(const Note ¬e) {
|
||||||
return removeNote(note.id());
|
int position = m_notes.indexOf(note);
|
||||||
}
|
|
||||||
|
|
||||||
bool NotesModel::removeNote(int id) {
|
|
||||||
int position = indexOf(id);
|
|
||||||
if (position >= 0 && position < m_notes.size()) {
|
if (position >= 0 && position < m_notes.size()) {
|
||||||
beginRemoveRows(QModelIndex(), position, position);
|
beginRemoveRows(QModelIndex(), position, position);
|
||||||
m_notes.removeAt(position);
|
m_notes.removeAt(position);
|
||||||
|
@ -152,61 +161,19 @@ bool NotesModel::removeNote(int id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotesModel::replaceNote(const Note ¬e) {
|
bool NotesModel::removeNote(int id) {
|
||||||
int position = indexOf(note.id());
|
bool retval = false;
|
||||||
if (position >= 0 && position < m_notes.size()) {
|
for (int i = 0; i < m_notes.size(); ++i) {
|
||||||
ModelNote<Note, bool> modelNote;
|
if (m_notes[i].id() == id) {
|
||||||
modelNote.note = note;
|
retval |= removeNote(m_notes[i]);
|
||||||
modelNote.param = m_notes[position].param;
|
if (i > 0) i--;
|
||||||
m_notes.replace(position, modelNote);
|
}
|
||||||
QVector<int> roles;
|
|
||||||
roles << ModifiedRole << TitleRole << CategoryRole << ContentRole << FavoriteRole << EtagRole;
|
|
||||||
emit dataChanged(this->index(position), this->index(position), roles);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotesModel::clear() {
|
|
||||||
m_searchText.clear();
|
|
||||||
beginRemoveRows(QModelIndex(), 0, rowCount());
|
|
||||||
m_notes.clear();
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Note NotesModel::get(int index) const {
|
|
||||||
Note note;
|
|
||||||
if (index >= 0 && index < m_notes.size()) {
|
|
||||||
note = m_notes[index].note;
|
|
||||||
}
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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> NotesModel::roleNames() const {
|
||||||
return QHash<int, QByteArray> {
|
return QHash<int, QByteArray> {
|
||||||
{NotesModel::VisibleRole, "visible"},
|
|
||||||
{NotesModel::IdRole, "id"},
|
{NotesModel::IdRole, "id"},
|
||||||
{NotesModel::ModifiedRole, "modified"},
|
{NotesModel::ModifiedRole, "modified"},
|
||||||
{NotesModel::TitleRole, "title"},
|
{NotesModel::TitleRole, "title"},
|
||||||
|
@ -216,17 +183,17 @@ QHash<int, QByteArray> NotesModel::roleNames() const {
|
||||||
{NotesModel::EtagRole, "etag"},
|
{NotesModel::EtagRole, "etag"},
|
||||||
{NotesModel::ErrorRole, "error"},
|
{NotesModel::ErrorRole, "error"},
|
||||||
{NotesModel::ErrorMessageRole, "errorMessage"},
|
{NotesModel::ErrorMessageRole, "errorMessage"},
|
||||||
{NotesModel::DateStringRole, "date"}
|
{NotesModel::InSearchRole, "inSearch"}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> NotesModel::sortingNames() const {
|
QHash<int, QByteArray> NotesModel::sortingNames() const {
|
||||||
QHash<int, QByteArray> criteria;
|
return QHash<int, QByteArray> {
|
||||||
criteria[sortByDate] = "date";
|
{NotesModel::sortByDate, "date"},
|
||||||
criteria[sortByCategory] = "category";
|
{NotesModel::sortByCategory, "category"},
|
||||||
criteria[sortByTitle] = "title";
|
{NotesModel::sortByTitle, "title"},
|
||||||
criteria[noSorting] = "none";
|
{NotesModel::noSorting, "none"}
|
||||||
return criteria;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList NotesModel::sortingCriteria() const {
|
QStringList NotesModel::sortingCriteria() const {
|
||||||
|
@ -257,17 +224,19 @@ 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 == VisibleRole) return m_notes[index.row()].param;
|
else if (role == IdRole) return m_notes[index.row()].id();
|
||||||
else if (role == IdRole) return m_notes[index.row()].note.id();
|
else if (role == ModifiedRole) return m_notes[index.row()].modified();
|
||||||
else if (role == ModifiedRole) return m_notes[index.row()].note.modified();
|
else if (role == TitleRole) return m_notes[index.row()].title();
|
||||||
else if (role == TitleRole) return m_notes[index.row()].note.title();
|
else if (role == CategoryRole) return m_notes[index.row()].category();
|
||||||
else if (role == CategoryRole) return m_notes[index.row()].note.category();
|
else if (role == ContentRole) return m_notes[index.row()].content();
|
||||||
else if (role == ContentRole) return m_notes[index.row()].note.content();
|
else if (role == FavoriteRole) return m_notes[index.row()].favorite();
|
||||||
else if (role == FavoriteRole) return m_notes[index.row()].note.favorite();
|
else if (role == EtagRole) return m_notes[index.row()].etag();
|
||||||
else if (role == EtagRole) return m_notes[index.row()].note.etag();
|
else if (role == ErrorRole) return m_notes[index.row()].error();
|
||||||
else if (role == ErrorRole) return m_notes[index.row()].note.error();
|
else if (role == ErrorMessageRole) return m_notes[index.row()].errorMessage();
|
||||||
else if (role == ErrorMessageRole) return m_notes[index.row()].note.errorMessage();
|
else if (role == InSearchRole) {
|
||||||
else if (role == DateStringRole) return m_notes[index.row()].note.dateString();
|
qDebug() << "Invisible:" << m_invisibleIds.contains(m_notes[index.row()].id());
|
||||||
|
return !m_invisibleIds.contains(m_notes[index.row()].id());
|
||||||
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,99 +244,47 @@ QMap<int, QVariant> NotesModel::itemData(const QModelIndex &index) const {
|
||||||
QMap<int, QVariant> map;
|
QMap<int, QVariant> map;
|
||||||
if (!index.isValid()) return map;
|
if (!index.isValid()) return map;
|
||||||
else {
|
else {
|
||||||
for (int role = VisibleRole; role <= ErrorMessageRole; role++) {
|
for (int role = Qt::UserRole; role < Qt::UserRole + 10; ++role) {
|
||||||
map.insert(role, data(index, role));
|
map.insert(role, data(index, role));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
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.toUInt()) {
|
|
||||||
m_notes[index.row()].note.setModified(value.toInt());
|
|
||||||
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } ); // TODO remove when signals from Note are connected
|
|
||||||
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, DateStringRole} ); // TODO remove when signals from Note are connected
|
|
||||||
sort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (role == CategoryRole && m_notes[index.row()].note.category() != value.toString()) {
|
|
||||||
m_notes[index.row()].note.setCategory(value.toString());
|
|
||||||
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } ); // TODO remove when signals from Note are connected
|
|
||||||
sort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (role == ContentRole && m_notes[index.row()].note.content() != value.toString()) {
|
|
||||||
m_notes[index.row()].note.setContent(value.toString());
|
|
||||||
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } ); // TODO remove when signals from Note are connected
|
|
||||||
sort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (role == FavoriteRole && m_notes[index.row()].note.favorite() != value.toBool()) {
|
|
||||||
m_notes[index.row()].note.setFavorite(value.toBool());
|
|
||||||
emit dataChanged(this->index(index.row()), this->index(index.row()), QVector<int> { 1, role } ); // TODO remove when signals from Note are connected
|
|
||||||
sort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NotesModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) {
|
|
||||||
if (!index.isValid()) return false;
|
|
||||||
else if (roles.contains(ModifiedRole) || roles.contains(CategoryRole) || roles.contains(ContentRole) || roles.contains(FavoriteRole)) {
|
|
||||||
QMap<int, QVariant>::const_iterator i = roles.constBegin();
|
|
||||||
while (i != roles.constEnd()) {
|
|
||||||
setData(index, i.value(), i.key());
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotesModel::sort() {
|
void NotesModel::sort() {
|
||||||
qDebug() << "Sorting notes in the model";
|
qDebug() << "Sorting notes in the model";
|
||||||
QList<ModelNote<Note, bool> > notes;
|
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
QMap<QString, ModelNote<Note, bool> > map;
|
if (m_favoritesOnTop) {
|
||||||
QMap<QString, ModelNote<Note, bool> > favorites;
|
if (m_sortBy == sortingNames()[sortByDate]) {
|
||||||
if (m_sortBy == sortingNames()[sortByDate]) {
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByDateFavOnTop);
|
||||||
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
for (int i = 0; i < m_notes.size(); i++) {
|
|
||||||
if (m_favoritesOnTop && m_notes[i].note.favorite())
|
|
||||||
favorites.insert(QString::number(std::numeric_limits<uint>::max() - m_notes[i].note.modified()), m_notes[i]);
|
|
||||||
else
|
|
||||||
map.insert(QString::number(std::numeric_limits<uint>::max() - m_notes[i].note.modified()), m_notes[i]);
|
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
else if (m_sortBy == sortingNames()[sortByCategory]) {
|
||||||
notes.append(map.values());
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByCategoryFavOnTop);
|
||||||
m_notes = notes;
|
|
||||||
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
}
|
|
||||||
else if (m_sortBy == sortingNames()[sortByCategory]) {
|
|
||||||
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
for (int i = 0; i < m_notes.size(); i++) {
|
|
||||||
if (m_favoritesOnTop && m_notes[i].note.favorite())
|
|
||||||
favorites.insert(m_notes[i].note.category(), m_notes[i]);
|
|
||||||
else
|
|
||||||
map.insert(m_notes[i].note.category(), m_notes[i]);
|
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
else if (m_sortBy == sortingNames()[sortByTitle]) {
|
||||||
notes.append(map.values());
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByTitleFavOnTop);
|
||||||
m_notes = notes;
|
|
||||||
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
}
|
|
||||||
else if (m_sortBy == sortingNames()[sortByTitle]) {
|
|
||||||
emit layoutAboutToBeChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
for (int i = 0; i < m_notes.size(); i++) {
|
|
||||||
if (m_favoritesOnTop && m_notes[i].note.favorite())
|
|
||||||
favorites.insert(m_notes[i].note.title(), m_notes[i]);
|
|
||||||
else
|
|
||||||
map.insert(m_notes[i].note.title(), m_notes[i]);
|
|
||||||
}
|
}
|
||||||
notes = favorites.values();
|
|
||||||
notes.append(map.values());
|
|
||||||
m_notes = notes;
|
|
||||||
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (m_sortBy == sortingNames()[sortByDate]) {
|
||||||
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByDate);
|
||||||
|
}
|
||||||
|
else if (m_sortBy == sortingNames()[sortByCategory]) {
|
||||||
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByCategory);
|
||||||
|
}
|
||||||
|
else if (m_sortBy == sortingNames()[sortByTitle]) {
|
||||||
|
std::sort(m_notes.begin(), m_notes.end(), Note::lessThanByTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit layoutChanged(QList<QPersistentModelIndex> (), VerticalSortHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
int NotesModel::indexOf(int id) const {
|
||||||
|
for (int i = 0; i < m_notes.size(); i++) {
|
||||||
|
if (m_notes[i].id() == id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NotesModel::insertPosition(const Note &n) const {
|
int NotesModel::insertPosition(const Note &n) const {
|
||||||
|
@ -375,7 +292,7 @@ int NotesModel::insertPosition(const Note &n) const {
|
||||||
int upper = m_notes.size();
|
int upper = m_notes.size();
|
||||||
while (lower < upper) {
|
while (lower < upper) {
|
||||||
int middle = qFloor(lower + (upper-lower) / 2);
|
int middle = qFloor(lower + (upper-lower) / 2);
|
||||||
bool result = noteLessThan(n, m_notes[middle].note);
|
bool result = noteLessThan(n, m_notes[middle]);
|
||||||
if (result)
|
if (result)
|
||||||
upper = middle;
|
upper = middle;
|
||||||
else
|
else
|
||||||
|
@ -386,22 +303,13 @@ int NotesModel::insertPosition(const Note &n) const {
|
||||||
|
|
||||||
bool NotesModel::noteLessThan(const Note &n1, const Note &n2) const {
|
bool NotesModel::noteLessThan(const Note &n1, const Note &n2) const {
|
||||||
if (m_sortBy == sortingNames()[sortByDate]) {
|
if (m_sortBy == sortingNames()[sortByDate]) {
|
||||||
if (m_favoritesOnTop && n1.favorite() != n2.favorite())
|
return m_favoritesOnTop ? Note::lessThanByDateFavOnTop(n1, n2) : Note::lessThanByDate(n1, n2);
|
||||||
return n1.favorite();
|
|
||||||
else
|
|
||||||
return n1.modified() > n2.modified();
|
|
||||||
}
|
}
|
||||||
else if (m_sortBy == sortingNames()[sortByCategory]) {
|
else if (m_sortBy == sortingNames()[sortByCategory]) {
|
||||||
if (m_favoritesOnTop && n1.favorite() != n2.favorite())
|
return m_favoritesOnTop ? Note::lessThanByCategoryFavOnTop(n1, n2) : Note::lessThanByCategory(n1, n2);
|
||||||
return n1.favorite();
|
|
||||||
else
|
|
||||||
return n1.category() < n2.category();
|
|
||||||
}
|
}
|
||||||
else if (m_sortBy == sortingNames()[sortByTitle]) {
|
else if (m_sortBy == sortingNames()[sortByTitle]) {
|
||||||
if (m_favoritesOnTop && n1.favorite() != n2.favorite())
|
return m_favoritesOnTop ? Note::lessThanByTitleFavOnTop(n1, n2) : Note::lessThanByTitle(n1, n2);
|
||||||
return n1.favorite();
|
|
||||||
else
|
|
||||||
return n1.title() < n2.title();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_favoritesOnTop && n1.favorite() != n2.favorite())
|
if (m_favoritesOnTop && n1.favorite() != n2.favorite())
|
||||||
|
@ -409,73 +317,3 @@ bool NotesModel::noteLessThan(const Note &n1, const Note &n2) const {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*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::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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -5,12 +5,6 @@
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include "note.h"
|
#include "note.h"
|
||||||
|
|
||||||
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:
|
||||||
|
@ -32,29 +26,20 @@ public:
|
||||||
Q_INVOKABLE void search(QString searchText = QString());
|
Q_INVOKABLE void search(QString searchText = QString());
|
||||||
Q_INVOKABLE void clearSearch();
|
Q_INVOKABLE void clearSearch();
|
||||||
|
|
||||||
Q_INVOKABLE bool applyJSON(const QJsonDocument &jdoc);
|
bool applyJSON(const QJsonDocument &jdoc);
|
||||||
Q_INVOKABLE bool applyJSON(const QString &json);
|
bool applyJSON(const QString &json);
|
||||||
Q_INVOKABLE int insertNote(const Note ¬e);
|
|
||||||
Q_INVOKABLE bool removeNote(const Note ¬e);
|
|
||||||
Q_INVOKABLE bool removeNote(int position);
|
|
||||||
Q_INVOKABLE bool replaceNote(const Note ¬e);
|
|
||||||
Q_INVOKABLE void clear();
|
|
||||||
|
|
||||||
Q_INVOKABLE int indexOf(int id) const;
|
|
||||||
Q_INVOKABLE Note get(int index) const;
|
|
||||||
|
|
||||||
enum NoteRoles {
|
enum NoteRoles {
|
||||||
VisibleRole = Qt::UserRole,
|
IdRole = Qt::UserRole,
|
||||||
IdRole = Qt::UserRole + 1,
|
ModifiedRole = Qt::UserRole + 1,
|
||||||
ModifiedRole = Qt::UserRole + 2,
|
TitleRole = Qt::UserRole + 2,
|
||||||
TitleRole = Qt::UserRole + 3,
|
CategoryRole = Qt::UserRole + 3,
|
||||||
CategoryRole = Qt::UserRole + 4,
|
ContentRole = Qt::UserRole + 4,
|
||||||
ContentRole = Qt::UserRole + 5,
|
FavoriteRole = Qt::UserRole + 5,
|
||||||
FavoriteRole = Qt::UserRole + 6,
|
EtagRole = Qt::UserRole + 6,
|
||||||
EtagRole = Qt::UserRole + 7,
|
ErrorRole = Qt::UserRole + 7,
|
||||||
ErrorRole = Qt::UserRole + 8,
|
ErrorMessageRole = Qt::UserRole + 8,
|
||||||
ErrorMessageRole = Qt::UserRole + 9,
|
InSearchRole = Qt::UserRole + 9
|
||||||
DateStringRole = Qt::UserRole + 10
|
|
||||||
};
|
};
|
||||||
QHash<int, QByteArray> roleNames() const;
|
QHash<int, QByteArray> roleNames() const;
|
||||||
|
|
||||||
|
@ -71,14 +56,6 @@ public:
|
||||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||||
QMap<int, QVariant> itemData(const QModelIndex &index) const;
|
QMap<int, QVariant> itemData(const QModelIndex &index) 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 setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
|
|
||||||
|
|
||||||
//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:
|
protected:
|
||||||
|
|
||||||
|
@ -89,19 +66,21 @@ signals:
|
||||||
void searchTextChanged(QString searchText);
|
void searchTextChanged(QString searchText);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<ModelNote<Note, bool> > m_notes;
|
QVector<Note> m_notes;
|
||||||
|
QVector<int> m_invisibleIds;
|
||||||
QString m_sortBy;
|
QString m_sortBy;
|
||||||
bool m_favoritesOnTop;
|
bool m_favoritesOnTop;
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
//void update();
|
//void update();
|
||||||
bool applyJSONobject(const QJsonObject &jobj);
|
int insertNote(const Note ¬e);
|
||||||
|
bool replaceNote(const Note ¬e);
|
||||||
|
bool removeNote(const Note ¬e);
|
||||||
|
bool removeNote(int id);
|
||||||
|
int indexOf(int id) const;
|
||||||
int insertPosition(const Note &n) const;
|
int insertPosition(const Note &n) const;
|
||||||
bool noteLessThan(const Note &n1, const Note &n2) const;
|
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 noteLessThanByTitle(const Note &n1, const Note &n2);*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NOTESMODEL_H
|
#endif // NOTESMODEL_H
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
#include "sslconfiguration.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
SslConfiguration::SslConfiguration(QObject *parent) : QObject(parent), _checkCert(true) {
|
|
||||||
checkCertConfig = noCheckConfig = QSslConfiguration::defaultConfiguration();
|
|
||||||
noCheckConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
|
|
||||||
QSslConfiguration::setDefaultConfiguration(checkCertConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SslConfiguration::checkCert() {
|
|
||||||
return _checkCert;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SslConfiguration::setCheckCert(bool check) {
|
|
||||||
if (_checkCert != check) {
|
|
||||||
qDebug() << "Changing SSL Cert check to" << check;
|
|
||||||
_checkCert = check;
|
|
||||||
QSslConfiguration::setDefaultConfiguration(_checkCert ? checkCertConfig : noCheckConfig);
|
|
||||||
emit checkCertChanged(_checkCert);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef SSLCONFIGURATION_H
|
|
||||||
#define SSLCONFIGURATION_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QSslConfiguration>
|
|
||||||
#include <QSslSocket>
|
|
||||||
|
|
||||||
class SslConfiguration : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(bool checkCert READ checkCert WRITE setCheckCert NOTIFY checkCertChanged)
|
|
||||||
public:
|
|
||||||
explicit SslConfiguration(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
bool checkCert();
|
|
||||||
void setCheckCert(bool check);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void checkCertChanged(bool check);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _checkCert;
|
|
||||||
QSslConfiguration checkCertConfig;
|
|
||||||
QSslConfiguration noCheckConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SSLCONFIGURATION_H
|
|
|
@ -213,13 +213,6 @@
|
||||||
<translation>Geändert</translation>
|
<translation>Geändert</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>NotesApi</name>
|
|
||||||
<message>
|
|
||||||
<source>Unable to connect</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>NotesPage</name>
|
<name>NotesPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -270,6 +263,34 @@
|
||||||
<source>Open the settings to configure your Nextcloud accounts</source>
|
<source>Open the settings to configure your Nextcloud accounts</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No account yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Got to the settings to add an account</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No notes yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pull down to add a note</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No result</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Try another query</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>An error occurred</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -213,13 +213,6 @@
|
||||||
<translation>Ingen kategori</translation>
|
<translation>Ingen kategori</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>NotesApi</name>
|
|
||||||
<message>
|
|
||||||
<source>Unable to connect</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>NotesPage</name>
|
<name>NotesPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -270,6 +263,34 @@
|
||||||
<source>Open the settings to configure your Nextcloud accounts</source>
|
<source>Open the settings to configure your Nextcloud accounts</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No account yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Got to the settings to add an account</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No notes yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pull down to add a note</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No result</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Try another query</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>An error occurred</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
|
|
@ -259,73 +259,100 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>NotesApi</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../qml/components/NotesApi.qml" line="68"/>
|
|
||||||
<source>Unable to connect</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>NotesPage</name>
|
<name>NotesPage</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="31"/>
|
<location filename="../qml/pages/NotesPage.qml" line="38"/>
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="35"/>
|
<location filename="../qml/pages/NotesPage.qml" line="42"/>
|
||||||
<source>Add note</source>
|
<source>Add note</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="40"/>
|
<location filename="../qml/pages/NotesPage.qml" line="47"/>
|
||||||
<source>Reload</source>
|
<source>Reload</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="40"/>
|
<location filename="../qml/pages/NotesPage.qml" line="47"/>
|
||||||
<source>Updating...</source>
|
<source>Updating...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="46"/>
|
<location filename="../qml/pages/NotesPage.qml" line="53"/>
|
||||||
<source>Last update</source>
|
<source>Last update</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="49"/>
|
<location filename="../qml/pages/NotesPage.qml" line="56"/>
|
||||||
<source>never</source>
|
<source>never</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="59"/>
|
<location filename="../qml/pages/NotesPage.qml" line="66"/>
|
||||||
<source>Nextcloud Notes</source>
|
<source>Nextcloud Notes</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="198"/>
|
<location filename="../qml/pages/NotesPage.qml" line="206"/>
|
||||||
<source>Modified</source>
|
<source>Modified</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="201"/>
|
<location filename="../qml/pages/NotesPage.qml" line="209"/>
|
||||||
<source>Delete</source>
|
<source>Delete</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="203"/>
|
<location filename="../qml/pages/NotesPage.qml" line="211"/>
|
||||||
<source>Deleting note</source>
|
<source>Deleting note</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="233"/>
|
<location filename="../qml/pages/NotesPage.qml" line="241"/>
|
||||||
<source>Loading notes...</source>
|
<source>Loading notes...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../qml/pages/NotesPage.qml" line="271"/>
|
<location filename="../qml/pages/NotesPage.qml" line="247"/>
|
||||||
|
<source>No account yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="248"/>
|
||||||
|
<source>Got to the settings to add an account</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="254"/>
|
||||||
|
<source>No notes yet</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="255"/>
|
||||||
|
<source>Pull down to add a note</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="261"/>
|
||||||
|
<source>No result</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="262"/>
|
||||||
|
<source>Try another query</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="268"/>
|
||||||
|
<source>An error occurred</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../qml/pages/NotesPage.qml" line="279"/>
|
||||||
<source>Open the settings to configure your Nextcloud accounts</source>
|
<source>Open the settings to configure your Nextcloud accounts</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
Loading…
Reference in a new issue