diff --git a/main.qml b/main.qml index ef522f4..cb67dda 100644 --- a/main.qml +++ b/main.qml @@ -1,125 +1,130 @@ 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" Maui.ApplicationWindow { id: root title: qsTr("Buho") /***** PROPS *****/ property var views : ({ notes: 0, links: 1, books: 2 }) headBar.middleContent: Row { spacing: space.medium Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly iconName: "draw-text" text: qsTr("Notes") } + Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly iconName: "link" text: qsTr("Links") } + Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly iconName: "document-new" text: qsTr("Books") } } footBar.middleContent: Maui.PieButton { id: addButton iconName: "list-add" model: ListModel { ListElement {iconName: "document-new"; mid: "page"} ListElement {iconName: "link"; mid: "link"} ListElement {iconName: "draw-text"; mid: "note"} } onItemClicked: { if(item.mid === "note") newNoteDialog.open() } } footBar.leftContent: Maui.ToolButton { iconName: "document-share" } footBar.rightContent: Maui.ToolButton { iconName: "archive-remove" } /***** COMPONENTS *****/ + Connections + { + target: owl + onNoteInserted: notesView.append(note) + } + NewNoteDialog { id: newNoteDialog - onNoteSaved: - { - if(owl.insertNote(note.title, note.body, note.color, note.tags)) - notesView.append(note) - } + onNoteSaved: owl.insertNote(note.title, note.body, note.color, note.tags) } NewNoteDialog { id: editNote onNoteSaved: { - owl.updateNote(notesView.currentNote.id, note.title, note.body, note.color, note.tags) + if(owl.updateNote(notesView.currentNote.id, note.title, note.body, note.color, note.tags)) + notesView.cardsView.currentItem.update(note) } } /***** VIEWS *****/ SwipeView { anchors.fill: parent currentIndex: views.notes NotesView { id: notesView onNoteClicked: setNote(note) } } Component.onCompleted: { notesView.populate() } function setNote(note) { notesView.currentNote = note editNote.fill(note) } } diff --git a/src/db/dbactions.cpp b/src/db/dbactions.cpp index 78c73b8..49054cd 100644 --- a/src/db/dbactions.cpp +++ b/src/db/dbactions.cpp @@ -1,136 +1,142 @@ /*** 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} // }); // } // } - return this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map); + 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::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 ee5e6c7..f7bb913 100644 --- a/src/db/dbactions.h +++ b/src/db/dbactions.h @@ -1,50 +1,51 @@ /*** 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(); protected: OWL::DB_LIST getDBData(const QString &queryTxt); bool execQuery(const QString &queryTxt); signals: - void tagAdded(QString tag); + void noteInserted(QVariantMap note); + }; #endif // DBACTIONS_H diff --git a/src/views/notes/NotesView.qml b/src/views/notes/NotesView.qml index 2d554b2..a91f5fb 100644 --- a/src/views/notes/NotesView.qml +++ b/src/views/notes/NotesView.qml @@ -1,32 +1,33 @@ 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) 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) { console.log("OCLOR", data[i].color) append(data[i]) } } function append(note) { cardsView.model.append(note) } } diff --git a/src/widgets/CardDelegate.qml b/src/widgets/CardDelegate.qml index 196a5bf..850544d 100644 --- a/src/widgets/CardDelegate.qml +++ b/src/widgets/CardDelegate.qml @@ -1,82 +1,106 @@ 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 width: cardWidth height: cardHeight 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 } ColumnLayout { anchors.fill: parent spacing: 0 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 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 + Layout.topMargin: title.visible ? 0 : space.medium Layout.fillHeight: true Layout.fillWidth: true enabled: false text: model.body textFormat: TextEdit.RichText + font.pointSize: fontSizes.big background: Rectangle { color: "transparent" } } - } + Item + { + id: preview + Image + { + id: img + } + } + } + + 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 6923276..39caabf 100644 --- a/src/widgets/CardsView.qml +++ b/src/widgets/CardsView.qml @@ -1,48 +1,53 @@ 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 alias holder : holder property int itemWidth : Kirigami.Units.devicePixelRatio * 200 property int itemHeight: Kirigami.Units.devicePixelRatio * 120 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 from the add button

" + message: "

No notes!

You can create new notes
links and books

" } model: ListModel { } delegate: CardDelegate { id: delegate cardWidth: itemWidth cardHeight: itemHeight - onClicked: itemClicked(index) + onClicked: + { + currentIndex = index + itemClicked(index) + + } } onWidthChanged: 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 } } diff --git a/src/widgets/NewNoteDialog.qml b/src/widgets/NewNoteDialog.qml index c222379..f2338c7 100644 --- a/src/widgets/NewNoteDialog.qml +++ b/src/widgets/NewNoteDialog.qml @@ -1,269 +1,275 @@ 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" signal noteSaved(var note) x: (parent.width / 2) - (width / 2) y: (parent.height /2 ) - (height / 2) padding: 1 Rectangle { id: bg color: selectedColor z: -1 anchors.fill: parent } ColumnLayout { anchors.fill: parent Maui.ToolBar { 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 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: { body.text = message body.visible = true } } ScrollView { Layout.fillHeight: true Layout.fillWidth: true Layout.margins: space.medium TextArea { id: body placeholderText: qsTr("Body") selectByKeyboard :!isMobile selectByMouse : !isMobile - textFormat : TextEdit.RichText + textFormat : TextEdit.AutoText background: Rectangle { color: "transparent" } } } Row { Layout.fillWidth: true width: parent.width Layout.margins: space.medium Layout.alignment: Qt.AlignRight spacing: space.medium Button { id: save text: qsTr("Save") onClicked: { close() noteSaved({ title: title.text, body: body.text, color: selectedColor, tags: "" }) clearNote() } } Button { id: discard text: qsTr("Discard") onClicked: { close() clearNote() } } } } 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() } function bold() { // body.sele } }