diff --git a/android/gradle.properties b/android/gradle.properties index e2fc078..41fdacc 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,9 +1,9 @@ ## This file is automatically generated by QtCreator. # # This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. androidBuildToolsVersion=26.0.2 -androidCompileSdkVersion=27 +androidCompileSdkVersion=26 buildDir=.build -qt5AndroidDir=/home/camilo/Qt/5.11.1/android_armv7/src/android/java +qt5AndroidDir=/home/camilo/Qt/5.10.1/android_armv7/src/android/java diff --git a/android/gradle.properties~ b/android/gradle.properties~ index e2fc078..41fdacc 100644 --- a/android/gradle.properties~ +++ b/android/gradle.properties~ @@ -1,9 +1,9 @@ ## This file is automatically generated by QtCreator. # # This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. androidBuildToolsVersion=26.0.2 -androidCompileSdkVersion=27 +androidCompileSdkVersion=26 buildDir=.build -qt5AndroidDir=/home/camilo/Qt/5.11.1/android_armv7/src/android/java +qt5AndroidDir=/home/camilo/Qt/5.10.1/android_armv7/src/android/java diff --git a/android/local.properties b/android/local.properties index 24e25cc..f73784e 100644 --- a/android/local.properties +++ b/android/local.properties @@ -1,6 +1,6 @@ ## This file is automatically generated by QtCreator. # # This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. -sdk.dir=/home/camilo/Android/Sdk +sdk.dir=/opt/android-sdk diff --git a/android/local.properties~ b/android/local.properties~ index 24e25cc..f73784e 100644 --- a/android/local.properties~ +++ b/android/local.properties~ @@ -1,6 +1,6 @@ ## This file is automatically generated by QtCreator. # # This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. -sdk.dir=/home/camilo/Android/Sdk +sdk.dir=/opt/android-sdk diff --git a/main.qml b/main.qml index 2af6395..1827573 100644 --- a/main.qml +++ b/main.qml @@ -1,154 +1,174 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import org.kde.kirigami 2.0 as Kirigami import org.kde.maui 1.0 as Maui import "src/widgets" import "src/views/notes" import "src/views/links" Maui.ApplicationWindow { id: root title: qsTr("Buho") /***** PROPS *****/ + floatingBar: true + property string accentColor : highlightColor + property int currentView : views.notes property var views : ({ notes: 0, links: 1, books: 2 }) headBar.middleContent: Row { spacing: space.medium Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - + onClicked: currentView = views.notes + iconColor: currentView === views.notes? accentColor : textColor iconName: "draw-text" text: qsTr("Notes") } Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - + onClicked: currentView = views.links + iconColor: currentView === views.links? accentColor : textColor iconName: "link" text: qsTr("Links") } Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - + iconColor: currentView === views.books? accentColor : textColor iconName: "document-new" text: qsTr("Books") } } - footBar.middleContent: Maui.PieButton - { - id: addButton - iconName: "list-add" + footBar.middleContent: [ - model: ListModel + Maui.ToolButton { - ListElement {iconName: "document-new"; mid: "page"} - ListElement {iconName: "link"; mid: "link"} - ListElement {iconName: "draw-text"; mid: "note"} - } + iconName: swipeView.currentItem.cardsView.gridView ? "view-list-icons" : "view-list-details" + onClicked: + { + switch(currentView) + { + case views.notes: + notesView.cardsView.gridView = !notesView.cardsView.gridView + notesView.cardsView.refresh() + break + + case views.links: + linksView.cardsView.gridView = !linksView.cardsView.gridView + linksView.cardsView.refresh() + break + } - onItemClicked: - { - if(item.mid === "note") - newNoteDialog.open() - else if(item.mid === "link") - newLinkDialog.open() - } - } + } + }, - footBar.leftContent: Maui.ToolButton - { - iconName: swipeView.currentItem.cardsView.gridView ? "view-list-icons" : "view-list-details" - onClicked: + Maui.PieButton { - switch(swipeView.currentIndex) + id: addButton + iconName: "list-add" + + model: ListModel { - case views.notes: - notesView.cardsView.gridView = !notesView.cardsView.gridView - notesView.cardsView.refresh() - break + ListElement {iconName: "document-new"; mid: "page"} + ListElement {iconName: "link"; mid: "link"} + ListElement {iconName: "draw-text"; mid: "note"} } + onItemClicked: + { + if(item.mid === "note") + { + currentView = views.notes + newNoteDialog.open() + } + else if(item.mid === "link") + { + currentView = views.links + newLinkDialog.open() + } + } } - } - footBar.rightContent: Maui.ToolButton - { - iconName: "archive-remove" - } + ] /***** COMPONENTS *****/ Connections { target: owl onNoteInserted: notesView.append(note) + onLinkInserted: linksView.append(link) } NewNoteDialog { id: newNoteDialog - onNoteSaved: owl.insertNote(note.title, note.body, note.color, note.tags) + onNoteSaved: owl.insertNote(note.title.trim(), note.body, note.color, note.tags) } NewNoteDialog { id: editNote onNoteSaved: { - if(owl.updateNote(notesView.currentNote.id, note.title, note.body, note.color, note.tags)) + if(owl.updateNote(notesView.currentNote.id, note.title.trim(), note.body, note.color, note.tags)) notesView.cardsView.currentItem.update(note) } } NewLinkDialog { id: newLinkDialog + onLinkSaved: owl.insertLink(note.link, note.title.trim(), note.preview, note.color, note.tags) } /***** VIEWS *****/ SwipeView { id: swipeView anchors.fill: parent - currentIndex: views.notes + currentIndex: currentView + onCurrentIndexChanged: currentView = currentIndex + NotesView { id: notesView onNoteClicked: setNote(note) } LinksView { id: linksView } } Component.onCompleted: { notesView.populate() + linksView.populate() } function setNote(note) { notesView.currentNote = note editNote.fill(note) } } diff --git a/src/db/dbactions.cpp b/src/db/dbactions.cpp index 49054cd..204e6ae 100644 --- a/src/db/dbactions.cpp +++ b/src/db/dbactions.cpp @@ -1,142 +1,168 @@ /*** Buho Copyright (C) 2018 Camilo Higuita This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "dbactions.h" #include #include #include #include DBActions::DBActions(QObject *parent) : DB(parent) { qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath; qDebug()<< "Starting DBActions"; } DBActions::~DBActions() {} OWL::DB_LIST DBActions::getDBData(const QString &queryTxt) { OWL::DB_LIST mapList; auto query = this->getQuery(queryTxt); if(query.exec()) { while(query.next()) { OWL::DB data; for(auto key : OWL::KEYMAP.keys()) if(query.record().indexOf(OWL::KEYMAP[key])>-1) data.insert(key, query.value(OWL::KEYMAP[key]).toString()); mapList<< data; } }else qDebug()<< query.lastError()<< query.lastQuery(); return mapList; } QVariantList DBActions::get(const QString &queryTxt) { QVariantList mapList; auto query = this->getQuery(queryTxt); if(query.exec()) { while(query.next()) { QVariantMap data; for(auto key : OWL::KEYMAP.keys()) if(query.record().indexOf(OWL::KEYMAP[key])>-1) data[OWL::KEYMAP[key]] = query.value(OWL::KEYMAP[key]).toString(); mapList<< data; } }else qDebug()<< query.lastError()<< query.lastQuery(); return mapList; } bool DBActions::insertNote(const QString &title, const QString &body, const QString &color, const QString &tags) { auto id = QUuid::createUuid().toString(); QVariantMap note_map = { {OWL::KEYMAP[OWL::KEY::ID], id}, {OWL::KEYMAP[OWL::KEY::TITLE], title}, {OWL::KEYMAP[OWL::KEY::BODY], body}, {OWL::KEYMAP[OWL::KEY::COLOR], color}, {OWL::KEYMAP[OWL::KEY::UPDATED], QDateTime::currentDateTime()}, {OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime()} }; // if(!tags.isEmpty()) // { // for(auto tag : tags.split(",")) // { // this->insert(OWL::TABLEMAP[OWL::TABLE::TAGS], {{OWL::KEYMAP[OWL::KEY::TAG], tag}}); // this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES_TAGS], // { // {OWL::KEYMAP[OWL::KEY::TAG], tag}, // {OWL::KEYMAP[OWL::KEY::URL], note_url} // }); // } // } if(this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map)) { this->noteInserted(note_map); return true; } return false; } bool DBActions::updateNote(const QString &id, const QString &title, const QString &body, const QString &color, const QString &tags) { OWL::DB note = { {OWL::KEY::TITLE, title}, {OWL::KEY::BODY, body}, {OWL::KEY::COLOR, color}, {OWL::KEY::UPDATED, QDateTime::currentDateTime().toString()} }; return this->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note, {{OWL::KEYMAP[OWL::KEY::ID], id}} ); } QVariantList DBActions::getNotes() { return this->get("select * from notes"); } +bool DBActions::insertLink(const QString &link, const QString &title, const QString &preview, const QString &color, const QString &tags) +{ + QVariantMap link_map = + { + {OWL::KEYMAP[OWL::KEY::LINK], link}, + {OWL::KEYMAP[OWL::KEY::TITLE], title}, + {OWL::KEYMAP[OWL::KEY::PREVIEW], preview}, + {OWL::KEYMAP[OWL::KEY::COLOR], color}, + {OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime()} + }; + + qDebug()<< link_map; + if(this->insert(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map)) + { + this->linkInserted(link_map); + return true; + } + + return false; +} + +QVariantList DBActions::getLinks() +{ + return this->get("select * from links"); +} + bool DBActions::execQuery(const QString &queryTxt) { auto query = this->getQuery(queryTxt); return query.exec(); } diff --git a/src/db/dbactions.h b/src/db/dbactions.h index e56a960..46cf69d 100644 --- a/src/db/dbactions.h +++ b/src/db/dbactions.h @@ -1,53 +1,54 @@ /*** Buho Copyright (C) 2018 Camilo Higuita This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #ifndef DBACTIONS_H #define DBACTIONS_H #include #include "db.h" class DBActions : public DB { Q_OBJECT public: explicit DBActions(QObject *parent = nullptr); ~DBActions(); Q_INVOKABLE QVariantList get(const QString &queryTxt); /*main actions*/ Q_INVOKABLE bool insertNote(const QString &title, const QString &body, const QString &color = QString(), const QString &tags = QString()); Q_INVOKABLE bool updateNote(const QString &id, const QString &title, const QString &body, const QString &color = QString(), const QString &tags = QString()); Q_INVOKABLE QVariantList getNotes(); Q_INVOKABLE bool insertLink(const QString &link, const QString &title, const QString &preview, const QString &color = QString(), const QString &tags = QString()); + Q_INVOKABLE QVariantList getLinks(); protected: OWL::DB_LIST getDBData(const QString &queryTxt); bool execQuery(const QString &queryTxt); signals: void noteInserted(QVariantMap note); - + void linkInserted(QVariantMap link); }; #endif // DBACTIONS_H diff --git a/src/db/script.sql b/src/db/script.sql index 3a521f4..4cae607 100644 --- a/src/db/script.sql +++ b/src/db/script.sql @@ -1,25 +1,25 @@ CREATE TABLE IF NOT EXISTS NOTES ( id TEXT PRIMARY KEY, title TEXT, body TEXT, color TEXT, addDate DATE, updated DATE ); CREATE TABLE IF NOT EXISTS BOOKS ( url TEXT PRIMARY KEY, title TEXT NOT NULL, fav INTEGER NOT NULL, addDate DATE ); CREATE TABLE IF NOT EXISTS LINKS ( link TEXT PRIMARY KEY, url TEXT, title TEXT, -body TEXT, preview TEXT, +color TEXT, addDate DATE ); diff --git a/src/utils/owl.h b/src/utils/owl.h index b2cba96..41169d8 100644 --- a/src/utils/owl.h +++ b/src/utils/owl.h @@ -1,153 +1,156 @@ #ifndef OWL_H #define OWL_H #include #include #include #include #include #include #include #include #include #include #include namespace OWL { Q_NAMESPACE enum class W : uint8_t { TITLE, BODY, IMAGE, VIDEO, LINK, TAG, AUTHOR, DATE, NOTE, TAGS, ADD_DATE, COLOR }; static const QMap SLANG = { {W::TITLE, "title"}, {W::BODY, "body"}, {W::IMAGE, "image"}, {W::VIDEO, "video"}, {W::LINK, "link"}, {W::TAG, "tag"}, {W::AUTHOR, "author"}, {W::DATE, "date"}, {W::NOTE, "note"}, {W::TAGS, "tags"}, {W::ADD_DATE, "addDate"}, {W::COLOR, "color"} }; enum class TABLE : uint8_t { NOTES, NOTES_TAGS, TAGS, BOOKS, PAGES, BOOKS_PAGES, LINKS, LINKS_TAGS, PAGES_TAGS, NONE }; static const QMap TABLEMAP = { {TABLE::NOTES,"notes"}, {TABLE::NOTES_TAGS,"notes_tags"}, {TABLE::TAGS,"tags"}, {TABLE::BOOKS,"books"}, {TABLE::PAGES,"pages"}, {TABLE::BOOKS_PAGES,"books_pages"}, {TABLE::LINKS,"links"}, {TABLE::LINKS_TAGS,"links_tags"}, {TABLE::PAGES_TAGS,"pages_tags"}, {TABLE::LINKS_TAGS,"links_tags"} }; enum class KEY :uint8_t { URL, UPDATED, ID, TITLE, BODY, FAV, COLOR, ADD_DATE, TAG, PREVIEW, IMAGE, + LINK, NONE }; typedef QMap DB; typedef QList DB_LIST; static const DB KEYMAP = { {KEY::ID, "id"}, {KEY::BODY, "body"}, {KEY::UPDATED, "updated"}, {KEY::TITLE, "title"}, {KEY::URL, "url"}, {KEY::FAV, "fav"}, {KEY::COLOR, "color"}, {KEY::ADD_DATE, "addDate"}, {KEY::TAG, "tag"}, {KEY::PREVIEW, "preview"}, - {KEY::IMAGE, "image"} + {KEY::IMAGE, "image"}, + {KEY::LINK, "link"} + }; const QString CollectionDBPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/buho/"; const QString NotesPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/buho/notes/"; const QString BooksPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/buho/books/"; const QString LinksPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+"/buho/links/"; const QString App = "Buho"; const QString version = "1.0"; const QString DBName = "collection.db"; inline bool fileExists(const QString &url) { QFileInfo path(url); if (path.exists()) return true; else return false; } inline void saveJson(QJsonDocument document, QString fileName) { QFile jsonFile(fileName); jsonFile.open(QFile::WriteOnly); jsonFile.write(document.toJson()); } inline QVariantMap openJson(const QString &url) { QString val; QFile file; file.setFileName(url); file.open(QIODevice::ReadOnly | QIODevice::Text); val = file.readAll(); file.close(); QJsonDocument d = QJsonDocument::fromJson(val.toUtf8()); QJsonObject obj = d.object(); return obj.toVariantMap(); } } #endif // OWL_H diff --git a/src/views/links/LinksView.qml b/src/views/links/LinksView.qml index 3dcf8ba..768db3b 100644 --- a/src/views/links/LinksView.qml +++ b/src/views/links/LinksView.qml @@ -1,8 +1,40 @@ import QtQuick 2.9 import "../../widgets" import org.kde.maui 1.0 as Maui Maui.Page { id: control + + property alias cardsView : cardsView + property var currentLink : ({}) + signal linkClicked(var note) + + headBarVisible: false + margins: isMobile ? space.big : space.enormus + + CardsView + { + id: cardsView + anchors.fill: parent + onItemClicked: linkClicked(cardsView.model.get(index)) + holder.message: "

No Links!

You can create new notes
links and books

" + + } + + function populate() + { + var data = owl.getLinks() + for(var i in data) + { + console.log("PREVIEW", data[i].preview) + append(data[i]) + } + + } + + function append(link) + { + cardsView.model.append(link) + } } diff --git a/src/views/notes/NotesView.qml b/src/views/notes/NotesView.qml index ef48839..abefc5f 100644 --- a/src/views/notes/NotesView.qml +++ b/src/views/notes/NotesView.qml @@ -1,32 +1,32 @@ import QtQuick 2.9 import "../../widgets" import org.kde.maui 1.0 as Maui Maui.Page { property alias cardsView : cardsView property var currentNote : ({}) signal noteClicked(var note) - + margins: isMobile ? space.big : space.enormus headBarVisible: false CardsView { id: cardsView anchors.fill: parent onItemClicked: noteClicked(cardsView.model.get(index)) } function populate() { var data = owl.getNotes() for(var i in data) append(data[i]) } function append(note) { cardsView.model.append(note) } } diff --git a/src/widgets/CardDelegate.qml b/src/widgets/CardDelegate.qml index 833479b..d260224 100644 --- a/src/widgets/CardDelegate.qml +++ b/src/widgets/CardDelegate.qml @@ -1,120 +1,154 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.2 as Kirigami ItemDelegate { id: control property string noteColor : color ? color : "pink" property int cardWidth: Kirigami.Units.devicePixelRatio*200 property int cardHeight: Kirigami.Units.devicePixelRatio*120 + property int cardRadius: Kirigami.Units.devicePixelRatio*4 width: cardWidth height: cardHeight - + hoverEnabled: !isMobile background: Rectangle { color: "transparent" } DropShadow { anchors.fill: card visible: card.visible horizontalOffset: 0 verticalOffset: 3 radius: 8.0 samples: 17 color: "#80000000" source: card } Rectangle { id: card z: -999 anchors.centerIn: control anchors.fill: control border.color: Qt.darker(noteColor, 1.2) color: noteColor - radius: Kirigami.Units.devicePixelRatio*3 + radius: cardRadius + } + + Rectangle + { + anchors.fill: parent + color: hovered? "#333" : "transparent" + z: 999 + opacity: 0.3 } ColumnLayout { anchors.fill: parent spacing: 0 clip: true Label { id: title visible: title.text.length > 0 Layout.leftMargin: space.medium Layout.topMargin: space.medium Layout.rightMargin: space.medium Layout.fillWidth: true text: model.title color: Qt.darker(model.color, 3) + elide: Qt.ElideRight font.weight: Font.Bold font.bold: true font.pointSize: fontSizes.large } TextArea { id: body - - Layout.leftMargin: space.medium - Layout.bottomMargin: space.medium - Layout.rightMargin: space.medium + visible: typeof model.body !== 'undefined' + Layout.leftMargin: visible ? space.medium : 0 + Layout.bottomMargin: visible ? space.medium : 0 + Layout.rightMargin: visible ? space.medium : 0 Layout.topMargin: title.visible ? 0 : space.medium - Layout.fillHeight: true - Layout.fillWidth: true + Layout.fillHeight: visible + Layout.fillWidth: visible enabled: false text: model.body color: Qt.darker(model.color, 3) textFormat: TextEdit.RichText font.pointSize: fontSizes.big background: Rectangle { color: "transparent" } } Item { id: preview Layout.fillHeight: true Layout.fillWidth: true - Layout.maximumHeight: control.height * 0.3 + clip: true + Layout.topMargin: space.medium + Image { id: img - visible: model.preview + visible: status === Image.Ready asynchronous: true + anchors.centerIn: parent + + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter height: parent.height width: parent.width sourceSize.height: height sourceSize.width: width fillMode: Image.PreserveAspectCrop source: model.preview || "" + + layer.enabled: img.visible + layer.effect: OpacityMask + { + maskSource: Item + { + width: img.width + height: img.height + Rectangle + { + anchors.centerIn: parent + width: img.width + height: img.height + radius: cardRadius + // radius: Math.min(width, height) + } + } + } } } } function update(note) { title.text = note.title body.text = note.body noteColor = note.color } } diff --git a/src/widgets/CardsView.qml b/src/widgets/CardsView.qml index 9729af2..19d504c 100644 --- a/src/widgets/CardsView.qml +++ b/src/widgets/CardsView.qml @@ -1,61 +1,62 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import org.kde.kirigami 2.2 as Kirigami import org.kde.maui 1.0 as Maui GridView { property bool gridView : true property alias holder : holder readonly property int defaultSize : Kirigami.Units.devicePixelRatio * 200 - property int itemWidth : !gridView ? parent.width : Kirigami.Units.devicePixelRatio * 200 + property int itemWidth : !gridView ? parent.width : + isMobile? (width-itemSpacing) * 0.42 : Kirigami.Units.devicePixelRatio * 200 property int itemHeight: Kirigami.Units.devicePixelRatio * 120 - property int itemSpacing: space.huge + property int itemSpacing: space.huge signal itemClicked(int index) cellWidth: itemWidth + itemSpacing cellHeight: itemHeight + itemSpacing Maui.Holder { id: holder visible: count < 1 message: "

No notes!

You can create new notes
links and books

" } model: ListModel { id: cardsModel} delegate: CardDelegate { id: delegate cardWidth: itemWidth cardHeight: itemHeight onClicked: { currentIndex = index itemClicked(index) } } // onWidthChanged: if(!isMobile && gridView) adaptGrid() function adaptGrid() { var amount = parseInt(width/(itemWidth + itemSpacing),10) var leftSpace = parseInt(width-(amount*(itemWidth + itemSpacing)), 10) var size = parseInt((itemWidth + itemSpacing)+(parseInt(leftSpace/amount, 10)), 10) size = size > itemWidth + itemSpacing ? size : itemWidth + itemSpacing cellWidth = size } function refresh() { model = cardsModel } } diff --git a/src/widgets/NewLinkDialog.qml b/src/widgets/NewLinkDialog.qml index 91d643b..02a5a68 100644 --- a/src/widgets/NewLinkDialog.qml +++ b/src/widgets/NewLinkDialog.qml @@ -1,177 +1,284 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.0 import org.kde.maui 1.0 as Maui import org.buho.editor 1.0 import org.kde.kirigami 2.2 as Kirigami Popup { parent: ApplicationWindow.overlay height: previewReady ? parent.height * (isMobile ? 0.8 : 0.7) : - toolBarHeight + content.implicitHeight width: parent.width * (isMobile ? 0.9 : 0.7) signal linkSaved(var note) + property string selectedColor : "#ffffe6" + property string fgColor: Qt.darker(selectedColor, 2.5) property bool previewReady : false x: (parent.width / 2) - (width / 2) y: (parent.height /2 ) - (height / 2) - + modal: true padding: 1 Connections { target: linker onPreviewReady: { previewReady = true fill(link) } } + Rectangle { id: bg - color: "transparent" + color: selectedColor z: -1 anchors.fill: parent } ColumnLayout { id: content anchors.fill: parent + Maui.ToolBar + { + position: ToolBar.Header + Layout.fillWidth: true + visible: previewReady + middleContent: Row + { + spacing: space.medium + Rectangle + { + color:"#ffded4" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: selectedColor = parent.color + } + } + + Rectangle + { + color:"#d3ffda" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: selectedColor = parent.color + } + } + + Rectangle + { + color:"#caf3ff" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: selectedColor = parent.color + } + } + + Rectangle + { + color:"#ccc1ff" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: selectedColor = parent.color + } + } + + Rectangle + { + color:"#ffcdf4" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: selectedColor = parent.color + } + } + } + } + TextField { id: link Layout.fillWidth: true Layout.margins: space.medium height: 24 placeholderText: qsTr("URL") font.weight: Font.Bold font.bold: true font.pointSize: fontSizes.large + color: fgColor + background: Rectangle { color: "transparent" } onAccepted: linker.extract(link.text) } TextField { id: title visible: previewReady Layout.fillWidth: true Layout.margins: space.medium height: 24 placeholderText: qsTr("Title") font.weight: Font.Bold font.bold: true font.pointSize: fontSizes.large + color: fgColor background: Rectangle { color: "transparent" } } Item { Layout.fillWidth: true Layout.fillHeight: true visible: previewReady ListView { id: previewList anchors.fill: parent anchors.centerIn: parent clip: true snapMode: ListView.SnapOneItem orientation: ListView.Horizontal interactive: count > 1 + highlightFollowsCurrentItem: true model: ListModel{} + onMovementEnded: + { + var index = indexAt(contentX, contentY) + currentIndex = index + } delegate: ItemDelegate { height: previewList.height width: previewList.width background: Rectangle { color: "transparent" } Image { id: img source: model.url fillMode: Image.PreserveAspectFit asynchronous: true width: parent.width height: parent.height sourceSize.height: height horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter } } } } Row { Layout.fillWidth: true width: parent.width Layout.margins: space.medium Layout.alignment: Qt.AlignRight spacing: space.medium visible: previewReady layoutDirection: Qt.RightToLeft Button { id: save text: qsTr("Save") onClicked: { - linker.extract(link.text) + var data = ({ + link : link.text, + title: title.text, + preview: previewList.model.get(previewList.currentIndex).url, + color: selectedColor + }) + linkSaved(data) clear() } - } Button { id: discard text: qsTr("Discard") onClicked: clear() } } } function clear() { title.clear() - body.clear() + link.clear() + previewList.model.clear() + previewReady = false close() } function fill(note) { title.text = note.title[0] populatePreviews(note.image) open() } function populatePreviews(imgs) { for(var i in imgs) - { - console.log("IMAGE:", imgs[i]) - previewList.model.append({url : imgs[i]})} + previewList.model.append({url : imgs[i]}) } } diff --git a/src/widgets/NewNoteDialog.qml b/src/widgets/NewNoteDialog.qml index 03f8cbd..1cbb11b 100644 --- a/src/widgets/NewNoteDialog.qml +++ b/src/widgets/NewNoteDialog.qml @@ -1,278 +1,288 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.0 import org.kde.maui 1.0 as Maui import org.buho.editor 1.0 Popup { parent: ApplicationWindow.overlay height: parent.height * (isMobile ? 0.8 : 0.7) width: parent.width * (isMobile ? 0.9 : 0.7) property string selectedColor : "#ffffe6" + property string fgColor: Qt.darker(selectedColor, 2.5) + signal noteSaved(var note) x: (parent.width / 2) - (width / 2) y: (parent.height /2 ) - (height / 2) padding: 1 + modal: true Rectangle { id: bg color: selectedColor z: -1 anchors.fill: parent } ColumnLayout { id: content anchors.fill: parent Maui.ToolBar { position: ToolBar.Header z: 999 Layout.fillWidth: true leftContent: [ Maui.ToolButton { iconName: "format-text-bold" focusPolicy: Qt.TabFocus iconColor: checked ? highlightColor : textColor checkable: true checked: document.bold onClicked: document.bold = !document.bold }, Maui.ToolButton { iconName: "format-text-italic-symbolic" iconColor: checked ? highlightColor : textColor focusPolicy: Qt.TabFocus checkable: true checked: document.italic onClicked: document.italic = !document.italic }, Maui.ToolButton { iconName: "format-text-underline-symbolic" }, Maui.ToolButton { iconName: "format-text-uppercase" } ] rightContent: Row { spacing: space.medium Rectangle { color:"#ffded4" anchors.verticalCenter: parent.verticalCenter height: iconSizes.medium width: height radius: Math.max(height, width) border.color: borderColor MouseArea { anchors.fill: parent onClicked: selectedColor = parent.color } } Rectangle { color:"#d3ffda" anchors.verticalCenter: parent.verticalCenter height: iconSizes.medium width: height radius: Math.max(height, width) border.color: borderColor MouseArea { anchors.fill: parent onClicked: selectedColor = parent.color } } Rectangle { color:"#caf3ff" anchors.verticalCenter: parent.verticalCenter height: iconSizes.medium width: height radius: Math.max(height, width) border.color: borderColor MouseArea { anchors.fill: parent onClicked: selectedColor = parent.color } } Rectangle { color:"#ccc1ff" anchors.verticalCenter: parent.verticalCenter height: iconSizes.medium width: height radius: Math.max(height, width) border.color: borderColor MouseArea { anchors.fill: parent onClicked: selectedColor = parent.color } } Rectangle { color:"#ffcdf4" anchors.verticalCenter: parent.verticalCenter height: iconSizes.medium width: height radius: Math.max(height, width) border.color: borderColor MouseArea { anchors.fill: parent onClicked: selectedColor = parent.color } } Maui.ToolButton { iconName: "overflow-menu" } } } TextField { id: title Layout.fillWidth: true Layout.margins: space.medium height: 24 placeholderText: qsTr("Title") font.weight: Font.Bold font.bold: true - color: Qt.darker(selectedColor, 2.5) + font.pointSize: fontSizes.large + + color: fgColor background: Rectangle { color: "transparent" } } DocumentHandler { id: document document: body.textDocument cursorPosition: body.cursorPosition selectionStart: body.selectionStart selectionEnd: body.selectionEnd // textColor: TODO // onLoaded: { // body.text = text // } - onError: { + onError: + { body.text = message body.visible = true } } ScrollView { Layout.fillHeight: true Layout.fillWidth: true Layout.margins: space.medium TextArea { id: body - + width: parent.width + height: parent.height placeholderText: qsTr("Body") selectByKeyboard :!isMobile selectByMouse : !isMobile textFormat : TextEdit.AutoText - color: Qt.darker(selectedColor, 2.5) + color: fgColor + font.pointSize: fontSizes.large + wrapMode: TextEdit.WrapAnywhere + background: Rectangle { color: "transparent" } } } Row { Layout.fillWidth: true width: parent.width Layout.margins: space.medium Layout.alignment: Qt.AlignRight spacing: space.medium layoutDirection: Qt.RightToLeft Button { id: save text: qsTr("Save") onClicked: { if(body.text.length > 0) noteSaved({ title: title.text, body: body.text, color: selectedColor, tags: "" }) clearNote() close() } } Button { id: discard text: qsTr("Discard") onClicked: { close() clearNote() } } } } onOpened: body.forceActiveFocus() function clearNote() { title.clear() body.clear() } function fill(note) { document.load("qrc:/texteditor.html") title.text = note.title body.text = note.body selectedColor = note.color open() } }