/* ============================================================ * rekonq * ============================================================ * SPDX-License-Identifier: GPL-3.0-only * Copyright (C) 2022 aqua * ============================================================ * Description: rekonq bookmarks model * ============================================================ */ #include "bookmarkstreeformat_xbel.h" #include "bookmarkstreeitem.hpp" #include inline void writeNodeAttributes(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { // id if (const auto id = item->data(BookmarksTreeItem::Id).toString(); !id.isEmpty()) writer.writeAttribute(xbel::attr_id, id); // added if (const auto added = item->data(BookmarksTreeItem::Added).toDateTime(); !added.isNull()) writer.writeAttribute(xbel::attr_added, added.toString(Qt::ISODate)); } inline void writeUrlAttributes(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { // href (required) writer.writeAttribute(xbel::attr_href, item->data(BookmarksTreeItem::Href).toString()); // visited if (const auto visited = item->data(BookmarksTreeItem::Visited).toDateTime(); !visited.isNull()) writer.writeAttribute(xbel::attr_visited, visited.toString(Qt::ISODate)); // modified if (const auto modified = item->data(BookmarksTreeItem::Modified).toDateTime(); !modified.isNull()) writer.writeAttribute(xbel::attr_modified, modified.toString(Qt::ISODate)); } inline void writeItemTitle(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { if (const auto title = item->data(BookmarksTreeItem::Title).toString(); !title.isEmpty()) writer.writeTextElement(xbel::elem_title, title); } inline void writeItemInfo(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { if (!item->metadata.isEmpty()) { writer.writeStartElement(xbel::elem_info); for (const auto &meta : item->metadata) { writer.writeStartElement(xbel::elem_metadata); writer.writeAttribute(xbel::elem_metadata_owner, xbel::elem_metadata_owner_value); writer.writeCDATA(meta); writer.writeEndElement(); // elem_metadata } writer.writeEndElement(); // elem_info } } inline void writeItemDesc(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { if (const auto desc = item->data(BookmarksTreeItem::Description).toString(); !desc.isEmpty()) writer.writeTextElement(xbel::elem_desc, desc); } inline void writeChildElements(QXmlStreamWriter &writer, const BookmarksTreeItem *item) { switch (item->type()) { case BookmarksTreeItem::Root: // node.att writeNodeAttributes(writer, item); // title writeItemTitle(writer, item); // info writeItemInfo(writer, item); // desc writeItemDesc(writer, item); // children for (int i = 0; i < item->childCount(); ++i) { writeChildElements(writer, item->child(i)); } break; case BookmarksTreeItem::Folder: writer.writeStartElement(xbel::elem_folder); // note.att writeNodeAttributes(writer, item); // folded writer.writeAttribute(xbel::attr_folded, !item->isExpanded() ? xbel::attr_folded_yes : xbel::attr_folded_no); // title writeItemTitle(writer, item); // info writeItemInfo(writer, item); // desc writeItemDesc(writer, item); // children for (int i = 0; i < item->childCount(); ++i) { writeChildElements(writer, item->child(i)); } break; case BookmarksTreeItem::Bookmark: writer.writeStartElement(xbel::elem_bookmark); // node.att writeNodeAttributes(writer, item); // url.att writeUrlAttributes(writer, item); // title writeItemTitle(writer, item); // info writeItemInfo(writer, item); // desc writeItemDesc(writer, item); break; case BookmarksTreeItem::Separator: writer.writeStartElement(xbel::elem_separator); // empty break; case BookmarksTreeItem::Alias: writer.writeStartElement(xbel::elem_alias); // ref writer.writeAttribute(xbel::attr_ref, item->data(BookmarksTreeItem::Id).toString()); break; } writer.writeEndElement(); } bool xbel::write(QIODevice *device, const QVector &items) { QXmlStreamWriter xmlWriter(device); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeDTD(""); xmlWriter.writeStartElement(xbel::elem_xbel); xmlWriter.writeAttribute(xbel::attr_version, xbel::attr_version_value); for (const auto *item : items) writeChildElements(xmlWriter, item); xmlWriter.writeEndDocument(); return true; }