diff --git a/src/GroupRenderer.qml b/src/GroupRenderer.qml index 548f0ee..ff23b0a 100644 --- a/src/GroupRenderer.qml +++ b/src/GroupRenderer.qml @@ -1,73 +1,74 @@ /* * SPDX-FileCopyrightText: (C) 2020 by Ismael Asensio * SPDX-License-Identifier: GPL-2.0-or-later */ import QtQuick 2.14 import QtQuick.Layouts 1.14 import QtQuick.Controls 2.14 as QQC2 import org.kde.kirigami 2.12 as Kirigami ListView { id: root Layout.fillWidth: true Layout.fillHeight: true delegate: Kirigami.AbstractListItem { RowLayout { Kirigami.Icon { source: model.decoration Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium } Loader { id: contentLoader Layout.fillWidth: true + Layout.alignment: Qt.AlignTop sourceComponent: { switch (model.type) { case 255: return groupRenderer; case 3: return imageRenderer; default: return textRenderer; } } Component { id: groupRenderer // ERROR: GroupRenderer is instantiated recursively // GroupRenderer { // model: root.model.childrenObjects // } QQC2.Label { text: model.display } } Component { id: textRenderer TextEdit { text: model.display textFormat: TextEdit.RichText wrapMode: TextEdit.WordWrap } } Component { id: imageRenderer Image { source: model.display fillMode: Image.PreserveAspectFit - //Layout.maximumHeight: paintedHeight + Layout.alignment: Qt.AlignTop } } } QQC2.ToolTip { visible: hovered text: model.toolTip } } } } diff --git a/src/noteitem.cpp b/src/noteitem.cpp index a7142b4..206b3ec 100644 --- a/src/noteitem.cpp +++ b/src/noteitem.cpp @@ -1,246 +1,251 @@ /* * SPDX-FileCopyrightText: (C) 2003 by Sébastien Laoût * SPDX-FileCopyrightText: (C) 2020 by Ismael Asensio * SPDX-License-Identifier: GPL-2.0-or-later */ #include "noteitem.h" #include #include "basketscene.h" // TEMP: to get basket->fullPath() #include "xmlwork.h" namespace { QString iconNameForType(NoteType::Id type) { switch (type) { case NoteType::Group: return "package"; case NoteType::Text: return "text-x-plain"; case NoteType::Html: return "text-html"; case NoteType::Image: return "folder-pictures-symbolic"; case NoteType::Animation: return "folder-video-symbolic"; case NoteType::Sound: return "folder-music-symbolic"; case NoteType::File: return "application-x-zerosize"; case NoteType::Link: return "edit-link"; case NoteType::CrossReference: return "basket"; case NoteType::Launcher: return "run-build"; case NoteType::Color: return "color-profile"; case NoteType::Unknown: return "application-octet-stream"; } return QString(); } } QString NoteItem::s_basketPath; NoteItem::NoteItem() : m_parent(nullptr) , m_content(nullptr) { } NoteItem::~NoteItem() { delete m_content; qDeleteAll(m_children); } int NoteItem::row() const { if (!m_parent) { return 0; } return m_parent->m_children.indexOf(const_cast(this)); } NoteItem *NoteItem::parent() const { return m_parent; } void NoteItem::setParent(NoteItem *parent) { m_parent = parent; } QVector NoteItem::children() const { return m_children; } int NoteItem::childrenCount() const { return m_children.count(); } void NoteItem::insertAt(int row, NoteItem *item) { if (!item) return; item->setParent(this); if (row >= 0 && row < m_children.count() ) { m_children.insert(row, item); } else { m_children.append(item); } } void NoteItem::removeAt(int row) { if (row < 0 || row >= m_children.count()) { return; } delete m_children[row]; m_children.remove(row); } NoteItem *NoteItem::takeAt(int row) { if (row < 0 || row >= m_children.count()) { return nullptr; } return m_children.takeAt(row); } void NoteItem::setBasketPath(QString path) { s_basketPath = path; } QString NoteItem::displayText() const { if (type() == NoteType::Group) { return QStringLiteral("GROUP (%1)").arg(childrenCount()); } if (!content()) { return QStringLiteral(""); } return content()->toText(); } QIcon NoteItem::decoration() const { return QIcon::fromTheme(iconNameForType(type())); } SimpleContent *NoteItem::content() const { return m_content; } NoteType::Id NoteItem::type() const { return content()->type(); } QRect NoteItem::bounds() const { return m_bounds; } NoteItem::EditionDates NoteItem::editionDates() const { return m_editInfo; } QString NoteItem::address() const { if (!m_parent) { return QStringLiteral("root"); } return QString::number(reinterpret_cast(this), 16); } QString NoteItem::toolTipInfo() const { QStringList toolTip; /* // fullAddress and position within parent (debug) toolTip << QStringLiteral("<%1> @<%2>[%3]") .arg(address()) .arg(m_parent->address()) .arg(row()); */ // type toolTip << QStringLiteral("Type: %1").arg(NoteType::typeToName(type())); // geometry const QRect geometry = bounds(); toolTip << QStringLiteral("x:%1 y:%2 w:%3 h:%4") .arg(geometry.x()).arg(geometry.y()) .arg(geometry.width()).arg(geometry.height()); // edition information const EditionDates info = editionDates(); - toolTip << QStringLiteral("created: %1").arg(info.created.toString()) - << QStringLiteral("modified: %1").arg(info.modified.toString()); - + if (info.created.isValid()) { + toolTip << QStringLiteral("created: %1").arg(info.created.toString()); + } + if (info.modified.isValid()) { + toolTip << QStringLiteral("modified: %1").arg(info.modified.toString()); + } // tags if (!m_tagIds.isEmpty()) { - toolTip << QStringLiteral("Tags: %1").arg(m_tagIds.join(QStringLiteral(", "))); + toolTip << QStringLiteral("tags: %1").arg(m_tagIds.join(QStringLiteral(", "))); } //attributes const auto attributes = m_content->attributes(); for (const QString &attrName : attributes.keys()) { toolTip << QStringLiteral("%1: %2").arg(attrName) .arg(attributes.value(attrName).toString()); } return toolTip.join(QStringLiteral("\n")); } void NoteItem::loadFromXMLNode(const QDomElement& node) { for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) { QDomElement e = n.toElement(); if (e.isNull()) { continue; } NoteItem *child = new NoteItem(); this->insertAt(-1, child); child->loadPropertiesFromXMLNode(e); if (child->type() == NoteType::Group) { child->loadFromXMLNode(e); } } } void NoteItem::loadPropertiesFromXMLNode(const QDomElement& node) { if (node.tagName() == "group") { m_content = new SimpleContent(NoteType::Group); m_content->loadFromXMLNode(node); } if (node.tagName() == "note" || node.tagName() == "item") { // "item" is to keep compatible with 0.6.0 Alpha 1 (required?) const QDomElement content = XMLWork::getElement(node, "content"); NoteType::Id type = NoteType::typeFromLowerName(node.attribute("type")); m_content = new SimpleContent(type, s_basketPath); m_content->loadFromXMLNode(content); } // Load dates if (node.hasAttribute("added")) { m_editInfo.created = QDateTime::fromString(node.attribute("added"), Qt::ISODate); } if (node.hasAttribute("lastModification")) { m_editInfo.modified = QDateTime::fromString(node.attribute("lastModification"), Qt::ISODate); } m_bounds = QRect(node.attribute("x", "0").toInt(), node.attribute("y", "0").toInt(), node.attribute("width", "200").toInt(), node.attribute("height", "200").toInt()); // Tags: const QString tagsString = XMLWork::getElementText(node, QStringLiteral("tags"), QString()); - m_tagIds = tagsString.split(QLatin1Char(';')); + if (!tagsString.isEmpty()) { + m_tagIds = tagsString.split(QLatin1Char(';')); + } } diff --git a/src/simplecontent.cpp b/src/simplecontent.cpp index a8a026f..77161a7 100644 --- a/src/simplecontent.cpp +++ b/src/simplecontent.cpp @@ -1,80 +1,83 @@ /* * SPDX-FileCopyrightText: (C) 2020 by Ismael Asensio * SPDX-License-Identifier: GPL-2.0-or-later */ #include "simplecontent.h" #include #include "common.h" SimpleContent::SimpleContent(NoteType::Id type, const QString &basketPath) : m_type(type) , m_basketPath(basketPath) { } NoteType::Id SimpleContent::type() const { return m_type; } QVariantMap SimpleContent::attributes() const { return m_attributes; } QString SimpleContent::toText() const { switch (m_type) { case NoteType::Text: case NoteType::Html: return QString::fromUtf8(m_rawData); + case NoteType::Link: + return QStringLiteral("%2").arg(m_filePath) + .arg(m_attributes.value(QStringLiteral("title")).toString()); case NoteType::Image: return m_basketPath + m_filePath; default: return m_filePath; } return QString(); //return m_filePath; } // Indicates special attributes in the XML for some types QVariantMap SimpleContent::defaultAttributes() const { switch (m_type) { case NoteType::Group: return { { QStringLiteral("folded"), false }, }; case NoteType::Link: return { { QStringLiteral("title"), QString() }, { QStringLiteral("icon"), QString() }, { QStringLiteral("autoTitle"), true }, { QStringLiteral("autoIcon"), true } }; default: return {}; } return {}; } void SimpleContent::loadFromXMLNode(QDomElement node) { // Get filename m_filePath = node.text(); //Load data m_rawData.clear(); FileStorage::loadFromFile(m_basketPath + m_filePath, &m_rawData); // Load Attributes m_attributes = defaultAttributes(); for (const QString &attrName : m_attributes.keys()) { if (node.hasAttribute(attrName)) { const QString attrValue = node.attribute(attrName); m_attributes.insert(attrName, attrValue); } } }