diff --git a/main.qml b/main.qml index bedb0ed..c70c1cf 100644 --- a/main.qml +++ b/main.qml @@ -1,197 +1,185 @@ 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" import "src/views/books" Maui.ApplicationWindow { id: root title: qsTr("Buho") /***** PROPS *****/ floatingBar: true - property string accentColor : highlightColor + accentColor : "#8981d8" property int currentView : views.notes property var views : ({ notes: 0, links: 1, books: 2, tags: 3, search: 4 }) headBar.middleContent: [ + Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly onClicked: currentView = views.notes - iconColor: currentView === views.notes? accentColor : textColor + iconColor: currentView === views.notes? highlightColor : 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 + iconColor: currentView === views.links? highlightColor : textColor iconName: "link" text: qsTr("Links") }, Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - iconColor: currentView === views.books? accentColor : textColor + iconColor: currentView === views.books? highlightColor : textColor iconName: "document-new" text: qsTr("Books") }, Maui.ToolButton { display: root.isWide ? ToolButton.TextBesideIcon : ToolButton.IconOnly - iconColor: currentView === views.tags? accentColor : textColor + iconColor: currentView === views.tags? highlightColor : textColor iconName: "tag" text: qsTr("Tags") } ] + footBarAligment: Qt.AlignRight footBar.middleContent: [ - Maui.ToolButton - { - 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 - } - - } - }, - Maui.PieButton { id: addButton iconName: "list-add" + iconColor: "white" model: ListModel { 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() - } + newNote() else if(item.mid === "link") - { - currentView = views.links - newLinkDialog.open() - } + newLink() } } ] /***** COMPONENTS *****/ Connections { target: owl onNoteInserted: notesView.append(note) onLinkInserted: linksView.append(link) } NewNoteDialog { id: newNoteDialog - onNoteSaved: owl.insertNote(note.title.trim(), note.body, note.color, note.tags) + onNoteSaved: owl.insertNote(note) } NewNoteDialog { id: editNote onNoteSaved: { - if(owl.updateNote(notesView.currentNote.id, note.title.trim(), note.body, note.color, note.tags)) + if(owl.updateNote(note)) 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: currentView onCurrentIndexChanged: currentView = currentIndex NotesView { id: notesView onNoteClicked: setNote(note) } LinksView { id: linksView onLinkClicked: previewLink(link) } BooksView { id: booksView - } } Component.onCompleted: { notesView.populate() linksView.populate() } + + function newNote() + { + currentView = views.notes + newNoteDialog.open() + } + + function newLink() + { + currentView = views.links + newLinkDialog.open() + } + function setNote(note) { var tags = owl.getNoteTags(note.id) note.tags = tags notesView.currentNote = note editNote.fill(note) } function previewLink(link) { var tags = owl.getLinkTags(link.link) link.tags = tags linksView.previewer.show(link) } } diff --git a/qml.qrc b/qml.qrc index 6c1325d..8fffc77 100644 --- a/qml.qrc +++ b/qml.qrc @@ -1,17 +1,19 @@ main.qml src/db/script.sql src/widgets/NewNoteDialog.qml src/widgets/CardsView.qml src/views/notes/NotesView.qml src/widgets/CardDelegate.qml src/widgets/NewLinkDialog.qml src/views/links/LinksView.qml utils.js src/views/links/WebViewAndroid.qml src/views/links/WebViewLinux.qml src/views/links/Previewer.qml src/views/books/BooksView.qml + src/widgets/ColorsBar.qml + src/widgets/CardsList.qml diff --git a/src/db/db.cpp b/src/db/db.cpp index 56fe22e..308947a 100644 --- a/src/db/db.cpp +++ b/src/db/db.cpp @@ -1,233 +1,240 @@ /*** Pix 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 "db.h" #include #include #include #include DB::DB(QObject *parent) : QObject(parent) { QDir collectionDBPath_dir(OWL::CollectionDBPath); if (!collectionDBPath_dir.exists()) collectionDBPath_dir.mkpath("."); this->name = QUuid::createUuid().toString(); if(!OWL::fileExists(OWL::CollectionDBPath + OWL::DBName)) { this->openDB(this->name); qDebug()<<"Collection doesn't exists, trying to create it" << OWL::CollectionDBPath + OWL::DBName; this->prepareCollectionDB(); }else this->openDB(this->name); } DB::~DB() { this->m_db.close(); } void DB::openDB(const QString &name) { if(!QSqlDatabase::contains(name)) { this->m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), name); this->m_db.setDatabaseName(OWL::CollectionDBPath + OWL::DBName); } if (!this->m_db.isOpen()) { if(!this->m_db.open()) qDebug()<<"ERROR OPENING DB"<m_db.lastError().text()<getQuery("PRAGMA synchronous=OFF"); query.exec(); } void DB::prepareCollectionDB() const { QSqlQuery query(this->m_db); QFile file(":/src/db/script.sql"); if (!file.exists()) { QString log = QStringLiteral("Fatal error on build database. The file '"); log.append(file.fileName() + QStringLiteral("' for database and tables creation query cannot be not found!")); qDebug()<getQuery(queryStr); if (query.exec()) { if (query.next()) return true; }else qDebug()<m_db); return query; } bool DB::insert(const QString &tableName, const QVariantMap &insertData) { if (tableName.isEmpty()) { qDebug()<m_db); query.prepare(sqlQueryString); int k = 0; foreach (const QVariant &value, values) query.bindValue(k++, value); return query.exec(); } -bool DB::update(const QString &tableName, const OWL::DB &updateData, const QVariantMap &where) +bool DB::update(const QString &tableName, const QVariantMap &updateData, const QVariantMap &where) { if (tableName.isEmpty()) { qDebug()<getQuery(sqlQueryString); - qDebug()<getQuery(queryStr); return query.exec(); } bool DB::remove(const QString &tableName, const OWL::DB &removeData) { if (tableName.isEmpty()) { qDebug()< 1 && igetQuery(sqlQueryString).exec(); } diff --git a/src/db/db.h b/src/db/db.h index 194ff34..e2d51a9 100644 --- a/src/db/db.h +++ b/src/db/db.h @@ -1,73 +1,73 @@ /*** Pix 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 DB_H #define DB_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../utils/owl.h" class DB : public QObject { Q_OBJECT private: QString name; QSqlDatabase m_db; public: explicit DB(QObject *parent = nullptr); ~ DB(); void openDB(const QString &name); /*basic public actions*/ void prepareCollectionDB() const; /* utils*/ Q_INVOKABLE bool checkExistance(const QString &tableName, const QString &searchId, const QString &search); protected: QSqlQuery getQuery(const QString &queryTxt); bool insert(const QString &tableName, const QVariantMap &insertData); - bool update(const QString &tableName, const OWL::DB &updateData, const QVariantMap &where); + bool update(const QString &tableName, const QVariantMap &updateData, const QVariantMap &where); bool update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id); bool remove(const QString &tableName, const OWL::DB &removeData); signals: public slots: }; #endif // DB_H diff --git a/src/db/dbactions.cpp b/src/db/dbactions.cpp index 5061fdb..2aaa018 100644 --- a/src/db/dbactions.cpp +++ b/src/db/dbactions.cpp @@ -1,179 +1,198 @@ /*** 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 #include "linker.h" DBActions::DBActions(QObject *parent) : DB(parent) { qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath; qDebug()<< "Starting DBActions"; this->tag = Tagging::getInstance(OWL::App, OWL::version, "org.kde.buho", OWL::comment); } 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 QStringList &tags) +bool DBActions::insertNote(const QVariantMap ¬e) { - qDebug()<<"TAGS"<< tags; + qDebug()<<"TAGS"<< note[OWL::KEYMAP[OWL::KEY::TAG]].toStringList(); + + auto title = note[OWL::KEYMAP[OWL::KEY::TITLE]].toString(); + auto body = note[OWL::KEYMAP[OWL::KEY::BODY]].toString(); + auto color = note[OWL::KEYMAP[OWL::KEY::COLOR]].toString(); + auto pin = note[OWL::KEYMAP[OWL::KEY::PIN]].toInt(); + auto fav = note[OWL::KEYMAP[OWL::KEY::FAV]].toInt(); + auto tags = note[OWL::KEYMAP[OWL::KEY::TAG]].toStringList(); 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::PIN], pin}, + {OWL::KEYMAP[OWL::KEY::FAV], fav}, {OWL::KEYMAP[OWL::KEY::UPDATED], QDateTime::currentDateTime()}, {OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime()} }; if(this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map)) { for(auto tg : tags) this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::NOTES], id, color); this->noteInserted(note_map); return true; } return false; } -bool DBActions::updateNote(const QString &id, const QString &title, const QString &body, const QString &color, const QStringList &tags) +bool DBActions::updateNote(const QVariantMap ¬e) { - OWL::DB note = + auto id = note[OWL::KEYMAP[OWL::KEY::ID]].toString(); + auto title = note[OWL::KEYMAP[OWL::KEY::TITLE]].toString(); + auto body = note[OWL::KEYMAP[OWL::KEY::BODY]].toString(); + auto color = note[OWL::KEYMAP[OWL::KEY::COLOR]].toString(); + auto pin = note[OWL::KEYMAP[OWL::KEY::PIN]].toInt(); + auto fav = note[OWL::KEYMAP[OWL::KEY::FAV]].toInt(); + auto tags = note[OWL::KEYMAP[OWL::KEY::TAG]].toStringList(); + + QVariantMap note_map = { - {OWL::KEY::TITLE, title}, - {OWL::KEY::BODY, body}, - {OWL::KEY::COLOR, color}, - {OWL::KEY::UPDATED, QDateTime::currentDateTime().toString()} + {OWL::KEYMAP[OWL::KEY::TITLE], title}, + {OWL::KEYMAP[OWL::KEY::BODY], body}, + {OWL::KEYMAP[OWL::KEY::COLOR], color}, + {OWL::KEYMAP[OWL::KEY::PIN], pin}, + {OWL::KEYMAP[OWL::KEY::FAV], fav}, + {OWL::KEYMAP[OWL::KEY::UPDATED], QDateTime::currentDateTime().toString()} }; for(auto tg : tags) this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::NOTES], id, color); - return this->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note, {{OWL::KEYMAP[OWL::KEY::ID], id}} ); + return this->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map, {{OWL::KEYMAP[OWL::KEY::ID], id}} ); } QVariantList DBActions::getNotes() { return this->get("select * from notes"); } QVariantList DBActions::getNoteTags(const QString &id) { return this->tag->getAbstractTags(OWL::TABLEMAP[OWL::TABLE::NOTES], id); } bool DBActions::insertLink(const QString &link, const QString &title, const QString &preview, const QString &color, const QStringList &tags) { auto image_path = OWL::saveImage(Linker::getUrl(preview), OWL::LinksPath+QUuid::createUuid().toString()); QVariantMap link_map = { {OWL::KEYMAP[OWL::KEY::LINK], link}, {OWL::KEYMAP[OWL::KEY::TITLE], title}, {OWL::KEYMAP[OWL::KEY::PREVIEW], image_path}, {OWL::KEYMAP[OWL::KEY::COLOR], color}, {OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime()} }; if(this->insert(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map)) { for(auto tg : tags) this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], link, color); this->linkInserted(link_map); return true; } return false; } QVariantList DBActions::getLinks() { return this->get("select * from links"); } QVariantList DBActions::getLinkTags(const QString &link) { return this->tag->getAbstractTags(OWL::TABLEMAP[OWL::TABLE::LINKS], link); } 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 6eb82ca..9eea1e5 100644 --- a/src/db/dbactions.h +++ b/src/db/dbactions.h @@ -1,57 +1,57 @@ /*** 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" #include "tagging.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 QStringList &tags = QStringList()); - Q_INVOKABLE bool updateNote(const QString &id, const QString &title, const QString &body, const QString &color = QString(), const QStringList &tags = QStringList()); + Q_INVOKABLE bool insertNote(const QVariantMap ¬e); + Q_INVOKABLE bool updateNote(const QVariantMap ¬e); Q_INVOKABLE QVariantList getNotes(); Q_INVOKABLE QVariantList getNoteTags(const QString &id); Q_INVOKABLE bool insertLink(const QString &link, const QString &title, const QString &preview, const QString &color = QString(), const QStringList &tags = QStringList()); Q_INVOKABLE QVariantList getLinks(); Q_INVOKABLE QVariantList getLinkTags(const QString &link); protected: OWL::DB_LIST getDBData(const QString &queryTxt); bool execQuery(const QString &queryTxt); Tagging *tag; 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 4cae607..9e63ab3 100644 --- a/src/db/script.sql +++ b/src/db/script.sql @@ -1,25 +1,27 @@ CREATE TABLE IF NOT EXISTS NOTES ( id TEXT PRIMARY KEY, title TEXT, body TEXT, color TEXT, +fav INT, +pin INT, 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, preview TEXT, color TEXT, addDate DATE ); diff --git a/src/linker.cpp b/src/linker.cpp index 69e7415..d1f728c 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -1,95 +1,97 @@ #include "linker.h" #include "owl.h" #include #include #include #include Linker::Linker(QObject *parent) : QObject(parent) { } QByteArray Linker::getUrl(const QString &url) { QUrl mURL(url); QNetworkAccessManager manager; QNetworkRequest request (mURL); QNetworkReply *reply = manager.get(request); QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit())); loop.exec(); if(reply->error()) { qDebug() << reply->error(); return QByteArray(); } if(reply->bytesAvailable()) { auto data = reply->readAll(); reply->deleteLater(); return data; } return QByteArray(); } /* extract needs to extract from a url the title, the body and a preview image*/ void Linker::extract(const QString &url) { auto data = getUrl(url); auto titles = query(data, HtmlTag::TITLE); QStringList imgs ; +// auto tags = query(data, HtmlTag::META); + for(auto img : query(data, HtmlTag::IMG, "src")) { if(imgs.contains(img) || img.isEmpty()) continue; if(url.at(url.length()-1) == "/") { if(img.startsWith("http")) imgs << img; else imgs << url+img; }else { if(img.startsWith("http")) imgs << img; else imgs << url+"/"+img; } } LINK link_data {{OWL::KEYMAP[OWL::KEY::TITLE], titles}, {OWL::KEYMAP[OWL::KEY::BODY], data}, {OWL::KEYMAP[OWL::KEY::IMAGE], imgs}}; emit previewReady(link_data); } QStringList Linker::query(const QByteArray &array, const HtmlTag &tag, const QString &attribute) { QStringList res; auto doc = QGumboDocument::parse(array); auto root = doc.rootNode(); auto node = root.getElementsByTagName(tag); for(const auto &i : node) { if(attribute.isEmpty()) res << i.innerText(); else res << i.getAttribute(attribute); } return res; } diff --git a/src/utils/owl.h b/src/utils/owl.h index 866a478..9842dbc 100644 --- a/src/utils/owl.h +++ b/src/utils/owl.h @@ -1,179 +1,181 @@ #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, + PIN, 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::PIN, "pin"}, {KEY::COLOR, "color"}, {KEY::ADD_DATE, "addDate"}, {KEY::TAG, "tag"}, {KEY::PREVIEW, "preview"}, {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 comment = "Notes taking and link collector manager"; 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(); } inline QString saveImage(QByteArray array, const QString &path) { if(!array.isNull()&&!array.isEmpty()) { QImage img; img.loadFromData(array); QString name = path; name.replace("/", "-"); name.replace("&", "-"); QString format = "JPEG"; if (img.save(path+".jpg", format.toLatin1(), 100)) return path+".jpg"; else qDebug() << "couldn't save artwork"; }else qDebug()<<"array is empty"; return QString(); } } #endif // OWL_H diff --git a/src/views/links/LinksView.qml b/src/views/links/LinksView.qml index 339b06a..bf67d3c 100644 --- a/src/views/links/LinksView.qml +++ b/src/views/links/LinksView.qml @@ -1,46 +1,89 @@ import QtQuick 2.9 import "../../widgets" import org.kde.maui 1.0 as Maui Maui.Page { id: control property alias cardsView : cardsView property alias previewer : previewer property var currentLink : ({}) signal linkClicked(var link) - headBarVisible: false margins: isMobile ? space.big : space.enormus + headBarExit: false + headBar.leftContent: [ + Maui.ToolButton + { + iconName: cardsView.gridView ? "view-list-icons" : "view-list-details" + onClicked: + { + cardsView.gridView = !cardsView.gridView + cardsView.refresh() + } + }, + Maui.ToolButton + { + iconName: "view-sort-ascending" + + }, + + Maui.ToolButton + { + iconName: "view-sort-descending" + + } + ] + + headBar.rightContent: [ + Maui.ToolButton + { + iconName: "tag-recents" + + }, + + Maui.ToolButton + { + iconName: "window-pin" + + }, + + Maui.ToolButton + { + iconName: "view-calendar-day" + + } + ] + Previewer { id: previewer } 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 abefc5f..db76405 100644 --- a/src/views/notes/NotesView.qml +++ b/src/views/notes/NotesView.qml @@ -1,32 +1,116 @@ import QtQuick 2.9 +import QtQuick.Layouts 1.3 import "../../widgets" import org.kde.maui 1.0 as Maui +import org.kde.kirigami 2.2 as Kirigami + Maui.Page { property alias cardsView : cardsView property var currentNote : ({}) signal noteClicked(var note) - margins: isMobile ? space.big : space.enormus + margins: 0 + + headBarExit : false + + headBar.leftContent: [ + Maui.ToolButton + { + iconName: cardsView.gridView ? "view-list-icons" : "view-list-details" + onClicked: + { + cardsView.gridView = !cardsView.gridView + cardsView.refresh() + } + }, + Maui.ToolButton + { + iconName: "view-sort-ascending" + + }, + + Maui.ToolButton + { + iconName: "view-sort-descending" + + } + ] + + headBar.rightContent: [ + Maui.ToolButton + { + iconName: "tag-recents" + + }, + Maui.ToolButton + { + id: pinButton + iconName: "window-pin" + checkable: true + iconColor: checked ? highlightColor : textColor - headBarVisible: false - CardsView + }, + + Maui.ToolButton + { + iconName: "view-calendar-day" + + } + ] + + ColumnLayout { - id: cardsView anchors.fill: parent - onItemClicked: noteClicked(cardsView.model.get(index)) + spacing: 0 + CardsList + { + id: pinnedList + visible: pinButton.checked + Layout.margins: isMobile ? space.big : space.enormus + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + height: cardsView.itemHeight + itemHeight: cardsView.itemHeight * 0.9 + itemWidth: itemHeight + onItemClicked: noteClicked(cardsView.model.get(index)) + + } + + Kirigami.Separator + { + visible: pinnedList.visible + Layout.fillWidth: true + height: unit + } + + CardsView + { + id: cardsView + Layout.fillHeight: true + Layout.fillWidth: true + Layout.margins: isMobile ? space.big : space.enormus + onItemClicked: noteClicked(cardsView.model.get(index)) + holder.message : "

No notes!

Click here to create a new note

" + + Connections + { + target: cardsView.holder + onActionTriggered: newNote() + } + } } function populate() { var data = owl.getNotes() - for(var i in data) + 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 8186118..affea08 100644 --- a/src/widgets/CardDelegate.qml +++ b/src/widgets/CardDelegate.qml @@ -1,156 +1,171 @@ 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 + property string noteColor : color ? color : viewBackgroundColor + property int cardWidth: visible ? unit * 200 : 0 + property int cardHeight: visible ? unit * 120 : 0 + property int cardRadius: unit * 4 + + property bool condition : true + width: cardWidth height: cardHeight hoverEnabled: !isMobile background: Rectangle { color: "transparent" } + visible: condition + DropShadow { anchors.fill: card visible: card.visible horizontalOffset: 0 verticalOffset: 3 radius: 8.0 samples: 17 - color: "#80000000" + color: Qt.darker(noteColor, 1.5) source: card } Rectangle { id: card z: -999 anchors.centerIn: control anchors.fill: control border.color: Qt.darker(noteColor, 1.2) color: noteColor radius: cardRadius } Rectangle { anchors.fill: parent color: hovered? "#333" : "transparent" z: 999 opacity: 0.3 + radius: cardRadius } ColumnLayout { - anchors.fill: parent + height: parent.height * 0.9 + width: parent.width * 0.9 + anchors.centerIn: 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.alignment: Qt.AlignLeft + 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 + padding: 0 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.alignment: Qt.AlignLeft 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.margins: unit clip: true Layout.topMargin: space.medium visible: img.status === Image.Ready Image { id: img 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: "file://"+encodeURIComponent( 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 + console.log("UPDATE NOTES", note.pin) + model.title = note.title + model.body = note.body + model.color = note.color + model.pin = note.pin ? 1 : 0 + model.fav = note.fav ? 1 : 0 } } diff --git a/src/widgets/CardsList.qml b/src/widgets/CardsList.qml new file mode 100644 index 0000000..254f340 --- /dev/null +++ b/src/widgets/CardsList.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 +import org.kde.maui 1.0 as Maui + +ListView +{ + id: control + clip: true + + property int itemWidth: unit * 200 + property int itemHeight: unit * 200 + signal itemClicked(int index) + boundsBehavior: !isMobile? Flickable.StopAtBounds : Flickable.DragAndOvershootBounds + orientation: ListView.Horizontal + spacing: space.large + Maui.Holder + { + id: holder + visible: count < 1 + message: "

No pinned notes!

You can pin your notes to see them here

" + } + + model: notesView.cardsView.model + delegate: CardDelegate + { + cardWidth: model.pin == 1 ? itemWidth : 0 + cardHeight: model.pin == 1 ? itemHeight : 0 + condition: model.pin == 1 + + onClicked: + { + currentIndex = index + itemClicked(index) + } + } + +} diff --git a/src/widgets/CardsView.qml b/src/widgets/CardsView.qml index 2f56e3b..63486b9 100644 --- a/src/widgets/CardsView.qml +++ b/src/widgets/CardsView.qml @@ -1,64 +1,64 @@ 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 : unit * 200 - property int itemWidth : !gridView ? parent.width : + property int itemWidth : !gridView ? parent.width * 0.9 : isMobile? (width-itemSpacing) * 0.42 : unit * 200 property int itemHeight: unit * 120 property int itemSpacing: space.huge signal itemClicked(int index) boundsBehavior: !isMobile? Flickable.StopAtBounds : Flickable.DragAndOvershootBounds cellWidth: itemWidth + itemSpacing cellHeight: itemHeight + itemSpacing - + clip : true Maui.Holder { id: holder visible: count < 1 - message: "

No notes!

You can create new notes
links and books

" + message: "

Nohing here!

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/ColorsBar.qml b/src/widgets/ColorsBar.qml new file mode 100644 index 0000000..f168760 --- /dev/null +++ b/src/widgets/ColorsBar.qml @@ -0,0 +1,105 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.2 + +Row +{ + signal colorPicked(color color) + anchors.verticalCenter: parent.verticalCenter + 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: colorPicked(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: colorPicked(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: colorPicked(parent.color) + } + } + + Rectangle + { + color:"#dbd8ff" + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: colorPicked(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: colorPicked(parent.color) + } + } + + Rectangle + { + color: viewBackgroundColor + anchors.verticalCenter: parent.verticalCenter + height: iconSizes.medium + width: height + radius: Math.max(height, width) + border.color: borderColor + + MouseArea + { + anchors.fill: parent + onClicked: colorPicked(parent.color) + } + } +} diff --git a/src/widgets/NewLinkDialog.qml b/src/widgets/NewLinkDialog.qml index 24e2b7b..bb826ed 100644 --- a/src/widgets/NewLinkDialog.qml +++ b/src/widgets/NewLinkDialog.qml @@ -1,298 +1,219 @@ 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) : contentLayout.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: isAndroid ? 1 : "undefined" Connections { target: linker onPreviewReady: { previewReady = true fill(link) } } Maui.Page { id: content margins: 0 anchors.fill: parent Rectangle { id: bg color: selectedColor z: -1 anchors.fill: parent } onExit: clear() headBarVisible: previewReady footBarVisible: previewReady - headBar.rightContent: Row + headBar.rightContent: ColorsBar { - 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 - } - } + onColorPicked: selectedColor = color } ColumnLayout { id: contentLayout anchors.fill: parent TextField { id: link Layout.fillWidth: true Layout.margins: space.medium height: rowHeight verticalAlignment: Qt.AlignVCenter placeholderText: qsTr("URL") font.weight: Font.Bold font.bold: true font.pointSize: fontSizes.large color: fgColor Layout.alignment: Qt.AlignCenter 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 } } } } Maui.TagsBar { id: tagBar visible: previewReady Layout.fillWidth: true allowEditMode: true onTagsEdited: { for(var i in tags) append({tag : tags[i]}) } } } footBar.rightContent: [ Button { id: save text: qsTr("Save") onClicked: { var data = ({ link : link.text, title: title.text, preview: previewList.model.get(previewList.currentIndex).url, color: selectedColor, tags: tagBar.getTags() }) linkSaved(data) clear() } }, Button { id: discard text: qsTr("Discard") onClicked: clear() } ] } function clear() { title.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) previewList.model.append({url : imgs[i]}) } } diff --git a/src/widgets/NewNoteDialog.qml b/src/widgets/NewNoteDialog.qml index 012e548..c46ec2d 100644 --- a/src/widgets/NewNoteDialog.qml +++ b/src/widgets/NewNoteDialog.qml @@ -1,323 +1,265 @@ 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) property bool showEditActions : false signal noteSaved(var note) x: (parent.width / 2) - (width / 2) y: (parent.height /2 ) - (height / 2) modal: true padding: isAndroid ? 1 : "undefined" Maui.Page { id: content anchors.fill: parent margins: 0 onExit: clear() + + Rectangle { id: bg color: selectedColor z: -1 anchors.fill: parent } headBar.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" }, Maui.ToolButton { iconName: "image" } ] headBar.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 + ColorsBar { - 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 - } + onColorPicked: selectedColor = color } Maui.ToolButton - { - iconName: "overflow-menu" + id: pinButton + iconName: "window-pin" + checkable: true + iconColor: checked ? highlightColor : textColor +// onClicked: checked = !checked } } ColumnLayout { anchors.fill: parent TextField { id: title 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" } } 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 width: parent.width height: parent.height placeholderText: qsTr("Body") selectByKeyboard :!isMobile selectByMouse : !isMobile textFormat : TextEdit.AutoText color: fgColor font.pointSize: fontSizes.large wrapMode: TextEdit.WrapAnywhere background: Rectangle { color: "transparent" } } } Maui.TagsBar { id: tagBar Layout.fillWidth: true allowEditMode: true onTagsEdited: { for(var i in tags) append({tag : tags[i]}) } } } footBar.leftContent: [ Maui.ToolButton { + id: favButton iconName: "love" + checkable: true + iconColor: checked ? "#ff007f" : textColor }, Maui.ToolButton { iconName: "document-share" onClicked: isAndroid ? Maui.Android.shareText(body.text) : shareDialog.show(body.text) }, Maui.ToolButton { iconName: "document-export" }, Maui.ToolButton { iconName: "entry-delete" } ] footBar.rightContent: [ Button { id: save text: qsTr("Save") onClicked: { if(body.text.length > 0) - noteSaved({ - title: title.text, - body: body.text, - color: selectedColor, - tags: tagBar.getTags() - }) + packNote() clear() } }, Button { id: discard text: qsTr("Discard") onClicked: clear() } ] } onOpened: body.forceActiveFocus() function clear() { title.clear() body.clear() close() } function fill(note) { - document.load("qrc:/texteditor.html") title.text = note.title body.text = note.body selectedColor = note.color + pinButton.checked = note.pin == 1 + favButton.checked = note.fav == 1 tagBar.populate(note.tags) open() } + + function packNote() + { + noteSaved({ + id: notesView.currentNote.id, + title: title.text.trim(), + body: body.text, + color: selectedColor, + tag: tagBar.getTags(), + pin: pinButton.checked, + fav: favButton.checked + }) + } }