diff --git a/harbour-nextcloud-notes.desktop b/harbour-nextcloud-notes.desktop new file mode 100644 index 0000000..223b3ec --- /dev/null +++ b/harbour-nextcloud-notes.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +X-Nemo-Application-Type=silica-qt5 +Icon=harbour-nextcloud-notes +Exec=harbour-nextcloud-notes +Name=harbour-nextcloud-notes +# translation example: +# your app name in German locale (de) +# +# Remember to comment out the following line, if you do not want to use +# a different app name in German locale (de). +Name[de]=harbour-nextcloud-notes diff --git a/harbour-nextcloud-notes.pro b/harbour-nextcloud-notes.pro new file mode 100644 index 0000000..5a12bff --- /dev/null +++ b/harbour-nextcloud-notes.pro @@ -0,0 +1,42 @@ +# NOTICE: +# +# Application name defined in TARGET has a corresponding QML filename. +# If name defined in TARGET is changed, the following needs to be done +# to match new name: +# - corresponding QML filename must be changed +# - desktop icon filename must be changed +# - desktop filename must be changed +# - icon definition filename in desktop file must be changed +# - translation filenames have to be changed + +# The name of your application +TARGET = harbour-nextcloud-notes + +CONFIG += sailfishapp + +SOURCES += src/harbour-nextcloud-notes.cpp + +DISTFILES += qml/harbour-nextcloud-notes.qml \ + qml/cover/CoverPage.qml \ + qml/pages/FirstPage.qml \ + rpm/harbour-nextcloud-notes.changes.in \ + rpm/harbour-nextcloud-notes.changes.run.in \ + rpm/harbour-nextcloud-notes.spec \ + rpm/harbour-nextcloud-notes.yaml \ + translations/*.ts \ + harbour-nextcloud-notes.desktop \ + qml/pages/NotePage.qml + +SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172 + +# to disable building translations every time, comment out the +# following CONFIG line +CONFIG += sailfishapp_i18n + +# German translation is enabled as an example. If you aren't +# planning to localize your app, remember to comment out the +# following TRANSLATIONS line. And also do not forget to +# modify the localized app name in the the .desktop file. +TRANSLATIONS += translations/harbour-nextcloud-notes-de.ts + +HEADERS += diff --git a/icons/108x108/harbour-nextcloud-notes.png b/icons/108x108/harbour-nextcloud-notes.png new file mode 100644 index 0000000..ab10628 Binary files /dev/null and b/icons/108x108/harbour-nextcloud-notes.png differ diff --git a/icons/128x128/harbour-nextcloud-notes.png b/icons/128x128/harbour-nextcloud-notes.png new file mode 100644 index 0000000..54375c5 Binary files /dev/null and b/icons/128x128/harbour-nextcloud-notes.png differ diff --git a/icons/172x172/harbour-nextcloud-notes.png b/icons/172x172/harbour-nextcloud-notes.png new file mode 100644 index 0000000..36eee58 Binary files /dev/null and b/icons/172x172/harbour-nextcloud-notes.png differ diff --git a/icons/86x86/harbour-nextcloud-notes.png b/icons/86x86/harbour-nextcloud-notes.png new file mode 100644 index 0000000..ad316d6 Binary files /dev/null and b/icons/86x86/harbour-nextcloud-notes.png differ diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml new file mode 100644 index 0000000..fc562d5 --- /dev/null +++ b/qml/cover/CoverPage.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +CoverBackground { + Label { + id: label + anchors.centerIn: parent + text: qsTr("My Cover") + } + + CoverActionList { + id: coverAction + + CoverAction { + iconSource: "image://theme/icon-cover-next" + } + + CoverAction { + iconSource: "image://theme/icon-cover-pause" + } + } +} diff --git a/qml/harbour-nextcloud-notes.qml b/qml/harbour-nextcloud-notes.qml new file mode 100644 index 0000000..16d4d39 --- /dev/null +++ b/qml/harbour-nextcloud-notes.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import Nemo.Configuration 1.0 +import "pages" + +ApplicationWindow +{ + id: appWindow + + ConfigurationGroup { + id: appSettings + path: "/apps/harbour-nextcloud-notes/settings" + property string lastUpdate: qsTr("never") + property url nextcloudServer: "https://cloud.scharel.name" + property string username: "scharel" + property string password: "" + } + + property var notesModel: JSONListModel { + url: appSettings.nextcloudServer + "/index.php/apps/notes/api/v0.2/notes" + name: "notes" + saveFile: false + } + Connections { + target: notesModel + onLastUpdateChanged: appSettings.lastUpdate = notesModel.lastUpdate + } + + initialPage: Component { FirstPage { } } + cover: Qt.resolvedUrl("cover/CoverPage.qml") + allowedOrientations: defaultAllowedOrientations +} diff --git a/qml/pages/FirstPage.qml b/qml/pages/FirstPage.qml new file mode 100644 index 0000000..ab94ffa --- /dev/null +++ b/qml/pages/FirstPage.qml @@ -0,0 +1,130 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 +//import harbour.nextcloudnotes 0.1 + +Page { + id: page + + SilicaListView { + id: notesList + anchors.fill: parent + + PullDownMenu { + busy: notesModel.busy + MenuItem { + text: qsTr("Settings") + onClicked: pageStack.push(Qt.resolvedUrl("Settings.qml")) + } + MenuItem { + text: qsTr("Add note") + onClicked: console.log("Add note") + } + MenuLabel { + text: qsTr("Last update") + ": " + appSettings.lastUpdate + } + } + + header: SearchField { + width: parent.width + placeholderText: qsTr("Nextcloud Notes") + onTextChanged: notesModel.search(text.toLowerCase()) + + EnterKey.iconSource: "image://theme/icon-m-enter-close" + EnterKey.onClicked: focus = false + enabled: notesModel.json.length > 0 + } + + currentIndex: -1 + Component.onCompleted: notesModel.update() + + model: notesModel + + delegate: ListItem { + id: note + contentHeight: Theme.itemSizeMedium + + onClicked: { + pageStack.push(Qt.resolvedUrl("NotePage.qml"), + {id: id, + etag: etag, + modified: modified, + title: title, + category: category, + favorite: favorite, + content: content, + error: error, + errorMessage: errorMessage}) + } + + IconButton { + id: isFavoriteIcon + x: Theme.horizontalPageMargin + anchors.verticalCenter: parent.verticalCenter + width: Theme.iconSizeMedium + icon.source: (favorite ? "image://theme/icon-m-favorite-selected?" : "image://theme/icon-m-favorite?") + + (note.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor) + onClicked: { + console.log("Toggle favorite") + favorite = !favorite + } + } + + Label { + id: titleLabel + anchors.left: isFavoriteIcon.right + anchors.leftMargin: Theme.paddingSmall + anchors.right: parent.right + anchors.bottom: parent.verticalCenter + text: title + truncationMode: TruncationMode.Fade + color: note.highlighted ? Theme.highlightColor : Theme.primaryColor + } + + Label { + id: modifiedLabel + anchors.left: isFavoriteIcon.right + anchors.leftMargin: Theme.paddingSmall + anchors.right: parent.right + anchors.top: parent.verticalCenter + text: new Date(modified * 1000).toLocaleDateString() + font.pixelSize: Theme.fontSizeExtraSmall + color: note.highlighted ? Theme.highlightColor : Theme.primaryColor + } + + menu: ContextMenu { + Text { + id: descriptionText + width: parent.width - 2*Theme.horizontalPageMargin + height: contentHeight + Theme.paddingMedium + x: Theme.horizontalPageMargin + wrapMode: Text.Wrap + color: Theme.highlightColor + font.pixelSize: Theme.fontSizeSmall + maximumLineCount: 5 + text: content + } + MenuItem { + text: qsTr("Delete") + onClicked: console.log("Delete note") + } + } + } + + section.property: "category" + section.criteria: ViewSection.FullString + section.labelPositioning: ViewSection.InlineLabels + section.delegate: SectionHeader { + text: section.empty ? qsTr("No category") : section + } + + BusyIndicator { + id: busyIndicator + anchors.centerIn: parent + size: BusyIndicatorSize.Large + visible: notesList.count === 0 + running: visible + } + + VerticalScrollDecorator { flickable: notesList } + } +} diff --git a/qml/pages/JSONListModel.qml b/qml/pages/JSONListModel.qml new file mode 100644 index 0000000..b7efa4e --- /dev/null +++ b/qml/pages/JSONListModel.qml @@ -0,0 +1,117 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import Nemo.Configuration 1.0 + +ListModel { + property url url + property string json + property string name + property string file: StandardPaths.data + "/" + name + ".json" + property bool saveFile: false + property bool busy: false + property int status: 200 + property date lastUpdate: new Date(0) + + onJsonChanged: refresh() + + function flush() { + json = "" + var filePut = new XMLHttpRequest + filePut.open("PUT", file) + filePut.send(json) + clear() + lastUpdate = new Date(0) + status = 200 + } + + function refresh() { + search("") + } + + function search(query) { + clear() + var elements = parseJson() + for (var element in elements) { + elements[element].section = "" + var match = false + for (var child in elements[element]) { + if (elements[element][child]) { + match = (elements[element][child].toString().toLowerCase().indexOf(query) >= 0) || match + } + } + if (query === "" || match) + append(elements[element]) + } + } + + function parseJson() { + var elements = JSON.parse(json) + if (elements === null) { + console.log("Error parsing " + name + "-JSON") + elements = "" + json = "" + return null + } + else { + clear() + return elements + } + } + + function update() { + busy = true + var apiReq = new XMLHttpRequest + apiReq.open("GET", url, true)//, appSettings.username, appSettings.password) + apiReq.setRequestHeader('User-Agent', 'SailfishOS/harbour-lidderbuch') + apiReq.setRequestHeader('OCS-APIRequest', 'true') + apiReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(appSettings.username + ":" + appSettings.password)) + apiReq.onreadystatechange = function() { + if (apiReq.readyState === XMLHttpRequest.DONE) { + if (apiReq.status === 200) { + console.log("Successfully loaded " + url) + json = apiReq.responseText + //console.log(json) + if (saveFile) { + var filePut = new XMLHttpRequest + filePut.open("PUT", file) + filePut.send(json) + } + lastUpdate = new Date() + } + else { + console.log("Error loading " + url + " - " + apiReq.status) + //lastUpdate = new Date(0) + } + status = apiReq.status + busy = false + } + } + apiReq.send() + } + + Component.onCompleted: { + if (saveFile) { + if (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 " + name + " from local JSON file") + json = fileReq.responseText + busy = false + } + } + } + fileReq.send() + } + } + } +} diff --git a/qml/pages/NotePage.qml b/qml/pages/NotePage.qml new file mode 100644 index 0000000..9fdb72d --- /dev/null +++ b/qml/pages/NotePage.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +Page { + id: page + + property int id + property string etag + property date modified + property string title + property string category + property bool favorite + property string content + property bool error + property string errorMessage + + + // The effective value will be restricted by ApplicationWindow.allowedOrientations + allowedOrientations: Orientation.All + + SilicaFlickable { + id: flickable + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + //x: Theme.horizontalPageMargin + width: parent.width// - 2*x + + PageHeader { + title: page.title + } + + TextArea { + id: note + width: parent.width + readOnly: true + text: page.content + } + } + VerticalScrollDecorator {} + } +} diff --git a/rpm/harbour-nextcloud-notes.changes.in b/rpm/harbour-nextcloud-notes.changes.in new file mode 100644 index 0000000..8bf39db --- /dev/null +++ b/rpm/harbour-nextcloud-notes.changes.in @@ -0,0 +1,18 @@ +# Rename this file as harbour-nextcloud-notes.changes to include changelog +# entries in your RPM file. +# +# Add new changelog entries following the format below. +# Add newest entries to the top of the list. +# Separate entries from eachother with a blank line. +# +# Alternatively, if your changelog is automatically generated (e.g. with +# the git-change-log command provided with Sailfish OS SDK), create a +# harbour-nextcloud-notes.changes.run script to let mb2 run the required commands for you. + +# * date Author's Name version-release +# - Summary of changes + +* Sun Apr 13 2014 Jack Tar 0.0.1-1 +- Scrubbed the deck +- Hoisted the sails + diff --git a/rpm/harbour-nextcloud-notes.changes.run.in b/rpm/harbour-nextcloud-notes.changes.run.in new file mode 100644 index 0000000..25b26aa --- /dev/null +++ b/rpm/harbour-nextcloud-notes.changes.run.in @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Rename this file as harbour-nextcloud-notes.changes.run to let mb2 automatically +# generate changelog from well formatted Git commit messages and tag +# annotations. + +git-change-log + +# Here are some basic examples how to change from the default behavior. Run +# git-change-log --help inside the Sailfish OS SDK chroot or build engine to +# learn all the options git-change-log accepts. + +# Use a subset of tags +#git-change-log --tags refs/tags/my-prefix/* + +# Group entries by minor revision, suppress headlines for patch-level revisions +#git-change-log --dense '/[0-9]\+\.[0-9\+$' + +# Trim very old changes +#git-change-log --since 2014-04-01 +#echo '[ Some changelog entries trimmed for brevity ]' + +# Use the subjects (first lines) of tag annotations when no entry would be +# included for a revision otherwise +#git-change-log --auto-add-annotations diff --git a/rpm/harbour-nextcloud-notes.spec b/rpm/harbour-nextcloud-notes.spec new file mode 100644 index 0000000..04edb7c --- /dev/null +++ b/rpm/harbour-nextcloud-notes.spec @@ -0,0 +1,71 @@ +# +# Do NOT Edit the Auto-generated Part! +# Generated by: spectacle version 0.27 +# + +Name: harbour-nextcloud-notes + +# >> 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.1 +Release: 1 +Group: Qt/Qt +License: LICENSE +URL: http://example.org/ +Source0: %{name}-%{version}.tar.bz2 +Source100: harbour-nextcloud-notes.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 +Short description of my Sailfish OS Application + + +%prep +%setup -q -n %{name}-%{version} + +# >> setup +# << setup + +%build +# >> build pre +# << build pre + +%qtc_qmake5 + +%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 diff --git a/rpm/harbour-nextcloud-notes.yaml b/rpm/harbour-nextcloud-notes.yaml new file mode 100644 index 0000000..1d63232 --- /dev/null +++ b/rpm/harbour-nextcloud-notes.yaml @@ -0,0 +1,45 @@ +Name: harbour-nextcloud-notes +Summary: Nextcloud Notes +Version: 0.1 +Release: 1 +# The contents of the Group field should be one of the groups listed here: +# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS +Group: Qt/Qt +URL: http://example.org/ +License: LICENSE +# This must be generated before uploading a package to a remote build service. +# Usually this line does not need to be modified. +Sources: +- '%{name}-%{version}.tar.bz2' +Description: | + Short description of my Sailfish OS Application +Configure: none +# The qtc5 builder inserts macros to allow QtCreator to have fine +# control over qmake/make execution +Builder: qtc5 + +# This section specifies build dependencies that are resolved using pkgconfig. +# This is the preferred way of specifying build dependencies for your package. +PkgConfigBR: + - sailfishapp >= 1.0.2 + - Qt5Core + - Qt5Qml + - Qt5Quick + +# Build dependencies without a pkgconfig setup can be listed here +# PkgBR: +# - package-needed-to-build + +# Runtime dependencies which are not automatically detected +Requires: + - sailfishsilica-qt5 >= 0.10.9 + +# All installed files +Files: + - '%{_bindir}' + - '%{_datadir}/%{name}' + - '%{_datadir}/applications/%{name}.desktop' + - '%{_datadir}/icons/hicolor/*/apps/%{name}.png' + +# For more information about yaml and what's supported in Sailfish OS +# build system, please see https://wiki.merproject.org/wiki/Spectacle diff --git a/src/harbour-nextcloud-notes.cpp b/src/harbour-nextcloud-notes.cpp new file mode 100644 index 0000000..a97eb14 --- /dev/null +++ b/src/harbour-nextcloud-notes.cpp @@ -0,0 +1,24 @@ +#ifdef QT_QML_DEBUG +#include +#endif + +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication* app = SailfishApp::application(argc, argv); + app->setApplicationDisplayName("Nextcloud Notes"); + app->setApplicationName("harbour-nextcloud-notes"); + app->setApplicationVersion("0.1"); + app->setOrganizationDomain("https://github.com/scharel"); + app->setOrganizationName("harbour-nextcloud-notes"); + + qDebug() << app->applicationDisplayName() << app->applicationVersion(); + + QQuickView* view = SailfishApp::createView(); + + view->setSource(SailfishApp::pathTo("qml/harbour-nextcloud-notes.qml")); + view->show(); + + return app->exec(); +} diff --git a/translations/harbour-nextcloud-notes-de.ts b/translations/harbour-nextcloud-notes-de.ts new file mode 100644 index 0000000..b29fbb1 --- /dev/null +++ b/translations/harbour-nextcloud-notes-de.ts @@ -0,0 +1,45 @@ + + + + + CoverPage + + My Cover + Mein Cover + + + + FirstPage + + Settings + Einstellungen + + + Add note + Neue Notiz + + + Nextcloud Notes + Nextcloud Notizen + + + Delete + Löschen + + + No category + Ohne Kategorie + + + Last update + Zuletzt aktualisiert + + + + harbour-nextcloud-notes + + never + noch nie + + + diff --git a/translations/harbour-nextcloud-notes.ts b/translations/harbour-nextcloud-notes.ts new file mode 100644 index 0000000..63f653e --- /dev/null +++ b/translations/harbour-nextcloud-notes.ts @@ -0,0 +1,45 @@ + + + + + CoverPage + + My Cover + + + + + FirstPage + + Settings + + + + Add note + + + + Nextcloud Notes + + + + Delete + + + + No category + + + + Last update + + + + + harbour-nextcloud-notes + + never + + + +