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()
}
}