Edward Welbourne f339262217 XBEL stream reader: shuffle order of functions
Put readBookmark() first of the constituent parts, as it's the most
intelligible (albeit currently undocumented) and gives some clue to
the purpose of readTitle(), which is next.

Task-number: QTBUG-111228
Change-Id: I91d3d6bf8adc3f3001c90274bb62a9da6bf05362
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
(cherry picked from commit b610c7aa89dd6224fbf58983ad8c2a391b2a559e)
2023-07-13 17:07:27 +02:00

139 lines
3.8 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "xbelreader.h"
#include <QStyle>
#include <QTreeWidget>
using namespace Qt::StringLiterals;
//! [0]
XbelReader::XbelReader(QTreeWidget *treeWidget)
: treeWidget(treeWidget)
{
QStyle *style = treeWidget->style();
folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirClosedIcon),
QIcon::Normal, QIcon::Off);
folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon),
QIcon::Normal, QIcon::On);
bookmarkIcon.addPixmap(style->standardPixmap(QStyle::SP_FileIcon));
}
//! [0]
//! [1]
bool XbelReader::read(QIODevice *device)
{
xml.setDevice(device);
if (xml.readNextStartElement()) {
if (xml.name() == "xbel"_L1
&& xml.attributes().value("version"_L1) == "1.0"_L1) {
readXBEL();
} else {
xml.raiseError(QObject::tr("The file is not an XBEL version 1.0 file."));
}
}
return !xml.error();
}
//! [1]
//! [2]
QString XbelReader::errorString() const
{
return QObject::tr("%1\nLine %2, column %3")
.arg(xml.errorString())
.arg(xml.lineNumber())
.arg(xml.columnNumber());
}
//! [2]
//! [3]
void XbelReader::readXBEL()
{
Q_ASSERT(xml.isStartElement() && xml.name() == "xbel"_L1);
while (xml.readNextStartElement()) {
if (xml.name() == "folder"_L1)
readFolder(nullptr);
else if (xml.name() == "bookmark"_L1)
readBookmark(nullptr);
else if (xml.name() == "separator"_L1)
readSeparator(nullptr);
else
xml.skipCurrentElement();
}
}
//! [3]
void XbelReader::readBookmark(QTreeWidgetItem *item)
{
Q_ASSERT(xml.isStartElement() && xml.name() == "bookmark"_L1);
QTreeWidgetItem *bookmark = createChildItem(item);
bookmark->setFlags(bookmark->flags() | Qt::ItemIsEditable);
bookmark->setIcon(0, bookmarkIcon);
bookmark->setText(0, QObject::tr("Unknown title"));
bookmark->setText(1, xml.attributes().value("href"_L1).toString());
while (xml.readNextStartElement()) {
if (xml.name() == "title"_L1)
readTitle(bookmark);
else
xml.skipCurrentElement();
}
}
//! [4]
void XbelReader::readTitle(QTreeWidgetItem *item)
{
Q_ASSERT(xml.isStartElement() && xml.name() == "title"_L1);
item->setText(0, xml.readElementText());
}
//! [4]
//! [5]
void XbelReader::readSeparator(QTreeWidgetItem *item)
{
Q_ASSERT(xml.isStartElement() && xml.name() == "separator"_L1);
constexpr char16_t midDot = u'\xB7';
static const QString dots(30, midDot);
QTreeWidgetItem *separator = createChildItem(item);
separator->setFlags(item ? item->flags() & ~Qt::ItemIsSelectable : Qt::ItemFlags{});
separator->setText(0, dots);
xml.skipCurrentElement();
}
//! [5]
void XbelReader::readFolder(QTreeWidgetItem *item)
{
Q_ASSERT(xml.isStartElement() && xml.name() == "folder"_L1);
QTreeWidgetItem *folder = createChildItem(item);
bool folded = xml.attributes().value("folded"_L1) != "no"_L1;
folder->setExpanded(!folded);
while (xml.readNextStartElement()) {
if (xml.name() == "title"_L1)
readTitle(folder);
else if (xml.name() == "folder"_L1)
readFolder(folder);
else if (xml.name() == "bookmark"_L1)
readBookmark(folder);
else if (xml.name() == "separator"_L1)
readSeparator(folder);
else
xml.skipCurrentElement();
}
}
QTreeWidgetItem *XbelReader::createChildItem(QTreeWidgetItem *item)
{
QTreeWidgetItem *childItem = item ? new QTreeWidgetItem(item) : new QTreeWidgetItem(treeWidget);
childItem->setData(0, Qt::UserRole, xml.name().toString());
return childItem;
}