Polish the XML bookmarks examples
- Use Qt 5 connect syntax. - Streamline code, remove unused members. - Add a context menu for copying and opening the URLs. - Add const to XML code. - In the XML code, show the use of QStringLiteral in static inline functions to create strings versus QLatin1String in comparison overloads to avoid allocating strings from const char * literals. Change-Id: Ib5e62ca188e271ffe01996dff3c9ea8e0b60739a Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
This commit is contained in:
parent
146f6d261b
commit
8d71fae080
@ -58,13 +58,13 @@ MainWindow::MainWindow()
|
|||||||
xbelTree = new XbelTree;
|
xbelTree = new XbelTree;
|
||||||
setCentralWidget(xbelTree);
|
setCentralWidget(xbelTree);
|
||||||
|
|
||||||
createActions();
|
|
||||||
createMenus();
|
createMenus();
|
||||||
|
|
||||||
statusBar()->showMessage(tr("Ready"));
|
statusBar()->showMessage(tr("Ready"));
|
||||||
|
|
||||||
setWindowTitle(tr("DOM Bookmarks"));
|
setWindowTitle(tr("DOM Bookmarks"));
|
||||||
resize(480, 320);
|
const QSize availableSize = QApplication::desktop()->availableGeometry(this).size();
|
||||||
|
resize(availableSize.width() / 2, availableSize.height() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
@ -80,8 +80,8 @@ void MainWindow::open()
|
|||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
||||||
tr("Cannot read file %1:\n%2.")
|
tr("Cannot read file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +102,8 @@ void MainWindow::saveAs()
|
|||||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
||||||
tr("Cannot write file %1:\n%2.")
|
tr("Cannot write file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,37 +119,21 @@ void MainWindow::about()
|
|||||||
"documents."));
|
"documents."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createActions()
|
|
||||||
{
|
|
||||||
openAct = new QAction(tr("&Open..."), this);
|
|
||||||
openAct->setShortcuts(QKeySequence::Open);
|
|
||||||
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
|
|
||||||
|
|
||||||
saveAsAct = new QAction(tr("&Save As..."), this);
|
|
||||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
|
||||||
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
|
|
||||||
|
|
||||||
exitAct = new QAction(tr("E&xit"), this);
|
|
||||||
exitAct->setShortcuts(QKeySequence::Quit);
|
|
||||||
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
|
|
||||||
|
|
||||||
aboutAct = new QAction(tr("&About"), this);
|
|
||||||
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
|
||||||
|
|
||||||
aboutQtAct = new QAction(tr("About &Qt"), this);
|
|
||||||
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::createMenus()
|
void MainWindow::createMenus()
|
||||||
{
|
{
|
||||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
fileMenu->addAction(openAct);
|
QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &MainWindow::open);
|
||||||
fileMenu->addAction(saveAsAct);
|
openAct->setShortcuts(QKeySequence::Open);
|
||||||
fileMenu->addAction(exitAct);
|
|
||||||
|
QAction *saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &MainWindow::saveAs);
|
||||||
|
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||||
|
|
||||||
|
QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
|
||||||
|
exitAct->setShortcuts(QKeySequence::Quit);
|
||||||
|
|
||||||
menuBar()->addSeparator();
|
menuBar()->addSeparator();
|
||||||
|
|
||||||
helpMenu = menuBar()->addMenu(tr("&Help"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(tr("About &Qt"), qApp, &QCoreApplication::quit);
|
||||||
}
|
}
|
||||||
|
@ -68,18 +68,9 @@ public slots:
|
|||||||
void about();
|
void about();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createActions();
|
|
||||||
void createMenus();
|
void createMenus();
|
||||||
|
|
||||||
XbelTree *xbelTree;
|
XbelTree *xbelTree;
|
||||||
|
|
||||||
QMenu *fileMenu;
|
|
||||||
QMenu *helpMenu;
|
|
||||||
QAction *openAct;
|
|
||||||
QAction *saveAsAct;
|
|
||||||
QAction *exitAct;
|
|
||||||
QAction *aboutAct;
|
|
||||||
QAction *aboutQtAct;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +52,18 @@
|
|||||||
|
|
||||||
#include "xbeltree.h"
|
#include "xbeltree.h"
|
||||||
|
|
||||||
|
enum { DomElementRole = Qt::UserRole + 1 };
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QDomElement)
|
||||||
|
|
||||||
|
static inline QString titleElement() { return QStringLiteral("title"); }
|
||||||
|
static inline QString folderElement() { return QStringLiteral("folder"); }
|
||||||
|
static inline QString bookmarkElement() { return QStringLiteral("bookmark"); }
|
||||||
|
|
||||||
|
static inline QString versionAttribute() { return QStringLiteral("version"); }
|
||||||
|
static inline QString hrefAttribute() { return QStringLiteral("href"); }
|
||||||
|
static inline QString foldedAttribute() { return QStringLiteral("folded"); }
|
||||||
|
|
||||||
XbelTree::XbelTree(QWidget *parent)
|
XbelTree::XbelTree(QWidget *parent)
|
||||||
: QTreeWidget(parent)
|
: QTreeWidget(parent)
|
||||||
{
|
{
|
||||||
@ -68,6 +80,24 @@ XbelTree::XbelTree(QWidget *parent)
|
|||||||
bookmarkIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
|
bookmarkIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void XbelTree::contextMenuEvent(QContextMenuEvent *event)
|
||||||
|
{
|
||||||
|
const QTreeWidgetItem *item = itemAt(event->pos());
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
const QString url = item->text(1);
|
||||||
|
QMenu contextMenu;
|
||||||
|
QAction *copyAction = contextMenu.addAction(tr("Copy Link to Clipboard"));
|
||||||
|
QAction *openAction = contextMenu.addAction(tr("Open"));
|
||||||
|
QAction *action = contextMenu.exec(event->globalPos());
|
||||||
|
if (action == copyAction)
|
||||||
|
QGuiApplication::clipboard()->setText(url);
|
||||||
|
else if (action == openAction)
|
||||||
|
QDesktopServices::openUrl(QUrl(url));
|
||||||
|
}
|
||||||
|
#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
|
||||||
|
|
||||||
bool XbelTree::read(QIODevice *device)
|
bool XbelTree::read(QIODevice *device)
|
||||||
{
|
{
|
||||||
QString errorStr;
|
QString errorStr;
|
||||||
@ -89,8 +119,8 @@ bool XbelTree::read(QIODevice *device)
|
|||||||
QMessageBox::information(window(), tr("DOM Bookmarks"),
|
QMessageBox::information(window(), tr("DOM Bookmarks"),
|
||||||
tr("The file is not an XBEL file."));
|
tr("The file is not an XBEL file."));
|
||||||
return false;
|
return false;
|
||||||
} else if (root.hasAttribute("version")
|
} else if (root.hasAttribute(versionAttribute())
|
||||||
&& root.attribute("version") != "1.0") {
|
&& root.attribute(versionAttribute()) != QLatin1String("1.0")) {
|
||||||
QMessageBox::information(window(), tr("DOM Bookmarks"),
|
QMessageBox::information(window(), tr("DOM Bookmarks"),
|
||||||
tr("The file is not an XBEL version 1.0 "
|
tr("The file is not an XBEL version 1.0 "
|
||||||
"file."));
|
"file."));
|
||||||
@ -99,22 +129,20 @@ bool XbelTree::read(QIODevice *device)
|
|||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
disconnect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
|
disconnect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
||||||
this, SLOT(updateDomElement(QTreeWidgetItem*,int)));
|
|
||||||
|
|
||||||
QDomElement child = root.firstChildElement("folder");
|
QDomElement child = root.firstChildElement(folderElement());
|
||||||
while (!child.isNull()) {
|
while (!child.isNull()) {
|
||||||
parseFolderElement(child);
|
parseFolderElement(child);
|
||||||
child = child.nextSiblingElement("folder");
|
child = child.nextSiblingElement(folderElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
|
connect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
||||||
this, SLOT(updateDomElement(QTreeWidgetItem*,int)));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XbelTree::write(QIODevice *device)
|
bool XbelTree::write(QIODevice *device) const
|
||||||
{
|
{
|
||||||
const int IndentSize = 4;
|
const int IndentSize = 4;
|
||||||
|
|
||||||
@ -123,21 +151,21 @@ bool XbelTree::write(QIODevice *device)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XbelTree::updateDomElement(QTreeWidgetItem *item, int column)
|
void XbelTree::updateDomElement(const QTreeWidgetItem *item, int column)
|
||||||
{
|
{
|
||||||
QDomElement element = domElementForItem.value(item);
|
QDomElement element = item->data(0, DomElementRole).value<QDomElement>();
|
||||||
if (!element.isNull()) {
|
if (!element.isNull()) {
|
||||||
if (column == 0) {
|
if (column == 0) {
|
||||||
QDomElement oldTitleElement = element.firstChildElement("title");
|
QDomElement oldTitleElement = element.firstChildElement(titleElement());
|
||||||
QDomElement newTitleElement = domDocument.createElement("title");
|
QDomElement newTitleElement = domDocument.createElement(titleElement());
|
||||||
|
|
||||||
QDomText newTitleText = domDocument.createTextNode(item->text(0));
|
QDomText newTitleText = domDocument.createTextNode(item->text(0));
|
||||||
newTitleElement.appendChild(newTitleText);
|
newTitleElement.appendChild(newTitleText);
|
||||||
|
|
||||||
element.replaceChild(newTitleElement, oldTitleElement);
|
element.replaceChild(newTitleElement, oldTitleElement);
|
||||||
} else {
|
} else {
|
||||||
if (element.tagName() == "bookmark")
|
if (element.tagName() == bookmarkElement())
|
||||||
element.setAttribute("href", item->text(1));
|
element.setAttribute(hrefAttribute(), item->text(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +175,7 @@ void XbelTree::parseFolderElement(const QDomElement &element,
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *item = createItem(element, parentItem);
|
QTreeWidgetItem *item = createItem(element, parentItem);
|
||||||
|
|
||||||
QString title = element.firstChildElement("title").text();
|
QString title = element.firstChildElement(titleElement()).text();
|
||||||
if (title.isEmpty())
|
if (title.isEmpty())
|
||||||
title = QObject::tr("Folder");
|
title = QObject::tr("Folder");
|
||||||
|
|
||||||
@ -155,25 +183,25 @@ void XbelTree::parseFolderElement(const QDomElement &element,
|
|||||||
item->setIcon(0, folderIcon);
|
item->setIcon(0, folderIcon);
|
||||||
item->setText(0, title);
|
item->setText(0, title);
|
||||||
|
|
||||||
bool folded = (element.attribute("folded") != "no");
|
bool folded = (element.attribute(foldedAttribute()) != QLatin1String("no"));
|
||||||
setItemExpanded(item, !folded);
|
setItemExpanded(item, !folded);
|
||||||
|
|
||||||
QDomElement child = element.firstChildElement();
|
QDomElement child = element.firstChildElement();
|
||||||
while (!child.isNull()) {
|
while (!child.isNull()) {
|
||||||
if (child.tagName() == "folder") {
|
if (child.tagName() == folderElement()) {
|
||||||
parseFolderElement(child, item);
|
parseFolderElement(child, item);
|
||||||
} else if (child.tagName() == "bookmark") {
|
} else if (child.tagName() == bookmarkElement()) {
|
||||||
QTreeWidgetItem *childItem = createItem(child, item);
|
QTreeWidgetItem *childItem = createItem(child, item);
|
||||||
|
|
||||||
QString title = child.firstChildElement("title").text();
|
QString title = child.firstChildElement(titleElement()).text();
|
||||||
if (title.isEmpty())
|
if (title.isEmpty())
|
||||||
title = QObject::tr("Folder");
|
title = QObject::tr("Folder");
|
||||||
|
|
||||||
childItem->setFlags(item->flags() | Qt::ItemIsEditable);
|
childItem->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||||
childItem->setIcon(0, bookmarkIcon);
|
childItem->setIcon(0, bookmarkIcon);
|
||||||
childItem->setText(0, title);
|
childItem->setText(0, title);
|
||||||
childItem->setText(1, child.attribute("href"));
|
childItem->setText(1, child.attribute(hrefAttribute()));
|
||||||
} else if (child.tagName() == "separator") {
|
} else if (child.tagName() == QLatin1String("separator")) {
|
||||||
QTreeWidgetItem *childItem = createItem(child, item);
|
QTreeWidgetItem *childItem = createItem(child, item);
|
||||||
childItem->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEditable));
|
childItem->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEditable));
|
||||||
childItem->setText(0, QString(30, 0xB7));
|
childItem->setText(0, QString(30, 0xB7));
|
||||||
@ -191,6 +219,6 @@ QTreeWidgetItem *XbelTree::createItem(const QDomElement &element,
|
|||||||
} else {
|
} else {
|
||||||
item = new QTreeWidgetItem(this);
|
item = new QTreeWidgetItem(this);
|
||||||
}
|
}
|
||||||
domElementForItem.insert(item, element);
|
item->setData(0, DomElementRole, QVariant::fromValue(element));
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@
|
|||||||
#define XBELTREE_H
|
#define XBELTREE_H
|
||||||
|
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
#include <QHash>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
|
||||||
@ -64,10 +63,15 @@ public:
|
|||||||
XbelTree(QWidget *parent = 0);
|
XbelTree(QWidget *parent = 0);
|
||||||
|
|
||||||
bool read(QIODevice *device);
|
bool read(QIODevice *device);
|
||||||
bool write(QIODevice *device);
|
bool write(QIODevice *device) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateDomElement(QTreeWidgetItem *item, int column);
|
void updateDomElement(const QTreeWidgetItem *item, int column);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseFolderElement(const QDomElement &element,
|
void parseFolderElement(const QDomElement &element,
|
||||||
@ -76,7 +80,6 @@ private:
|
|||||||
QTreeWidgetItem *parentItem = 0);
|
QTreeWidgetItem *parentItem = 0);
|
||||||
|
|
||||||
QDomDocument domDocument;
|
QDomDocument domDocument;
|
||||||
QHash<QTreeWidgetItem *, QDomElement> domElementForItem;
|
|
||||||
QIcon folderIcon;
|
QIcon folderIcon;
|
||||||
QIcon bookmarkIcon;
|
QIcon bookmarkIcon;
|
||||||
};
|
};
|
||||||
|
@ -62,17 +62,40 @@ MainWindow::MainWindow()
|
|||||||
treeWidget = new QTreeWidget;
|
treeWidget = new QTreeWidget;
|
||||||
treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);
|
treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
treeWidget->setHeaderLabels(labels);
|
treeWidget->setHeaderLabels(labels);
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(treeWidget, &QWidget::customContextMenuRequested,
|
||||||
|
this, &MainWindow::onCustomContextMenuRequested);
|
||||||
|
#endif
|
||||||
setCentralWidget(treeWidget);
|
setCentralWidget(treeWidget);
|
||||||
|
|
||||||
createActions();
|
|
||||||
createMenus();
|
createMenus();
|
||||||
|
|
||||||
statusBar()->showMessage(tr("Ready"));
|
statusBar()->showMessage(tr("Ready"));
|
||||||
|
|
||||||
setWindowTitle(tr("SAX Bookmarks"));
|
setWindowTitle(tr("SAX Bookmarks"));
|
||||||
resize(480, 320);
|
const QSize availableSize = QApplication::desktop()->availableGeometry(this).size();
|
||||||
|
resize(availableSize.width() / 2, availableSize.height() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void MainWindow::onCustomContextMenuRequested(const QPoint &pos)
|
||||||
|
{
|
||||||
|
const QTreeWidgetItem *item = treeWidget->itemAt(pos);
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
const QString url = item->text(1);
|
||||||
|
QMenu contextMenu;
|
||||||
|
QAction *copyAction = contextMenu.addAction(tr("Copy Link to Clipboard"));
|
||||||
|
QAction *openAction = contextMenu.addAction(tr("Open"));
|
||||||
|
QAction *action = contextMenu.exec(treeWidget->viewport()->mapToGlobal(pos));
|
||||||
|
if (action == copyAction)
|
||||||
|
QGuiApplication::clipboard()->setText(url);
|
||||||
|
else if (action == openAction)
|
||||||
|
QDesktopServices::openUrl(QUrl(url));
|
||||||
|
}
|
||||||
|
#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
|
||||||
|
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
{
|
{
|
||||||
QString fileName =
|
QString fileName =
|
||||||
@ -93,8 +116,8 @@ void MainWindow::open()
|
|||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
||||||
tr("Cannot read file %1:\n%2.")
|
tr("Cannot read file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,8 +139,8 @@ void MainWindow::saveAs()
|
|||||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
||||||
tr("Cannot write file %1:\n%2.")
|
tr("Cannot write file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,37 +157,21 @@ void MainWindow::about()
|
|||||||
"hand."));
|
"hand."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createActions()
|
|
||||||
{
|
|
||||||
openAct = new QAction(tr("&Open..."), this);
|
|
||||||
openAct->setShortcuts(QKeySequence::Open);
|
|
||||||
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
|
|
||||||
|
|
||||||
saveAsAct = new QAction(tr("&Save As..."), this);
|
|
||||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
|
||||||
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
|
|
||||||
|
|
||||||
exitAct = new QAction(tr("E&xit"), this);
|
|
||||||
exitAct->setShortcuts(QKeySequence::Quit);
|
|
||||||
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
|
|
||||||
|
|
||||||
aboutAct = new QAction(tr("&About"), this);
|
|
||||||
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
|
||||||
|
|
||||||
aboutQtAct = new QAction(tr("About &Qt"), this);
|
|
||||||
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::createMenus()
|
void MainWindow::createMenus()
|
||||||
{
|
{
|
||||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
fileMenu->addAction(openAct);
|
QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &MainWindow::open);
|
||||||
fileMenu->addAction(saveAsAct);
|
openAct->setShortcuts(QKeySequence::Open);
|
||||||
fileMenu->addAction(exitAct);
|
|
||||||
|
QAction *saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &MainWindow::saveAs);
|
||||||
|
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||||
|
|
||||||
|
QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
|
||||||
|
exitAct->setShortcuts(QKeySequence::Quit);
|
||||||
|
|
||||||
menuBar()->addSeparator();
|
menuBar()->addSeparator();
|
||||||
|
|
||||||
helpMenu = menuBar()->addMenu(tr("&Help"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(tr("About &Qt"), qApp, &QCoreApplication::quit);
|
||||||
}
|
}
|
||||||
|
@ -68,20 +68,13 @@ public slots:
|
|||||||
void open();
|
void open();
|
||||||
void saveAs();
|
void saveAs();
|
||||||
void about();
|
void about();
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void onCustomContextMenuRequested(const QPoint &pos);
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
void createActions();
|
|
||||||
void createMenus();
|
void createMenus();
|
||||||
|
|
||||||
QTreeWidget *treeWidget;
|
QTreeWidget *treeWidget;
|
||||||
|
|
||||||
QMenu *fileMenu;
|
|
||||||
QMenu *helpMenu;
|
|
||||||
QAction *openAct;
|
|
||||||
QAction *saveAsAct;
|
|
||||||
QAction *exitAct;
|
|
||||||
QAction *aboutAct;
|
|
||||||
QAction *aboutQtAct;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
#include "xbelgenerator.h"
|
#include "xbelgenerator.h"
|
||||||
|
|
||||||
XbelGenerator::XbelGenerator(QTreeWidget *treeWidget)
|
XbelGenerator::XbelGenerator(const QTreeWidget *treeWidget)
|
||||||
: treeWidget(treeWidget)
|
: treeWidget(treeWidget)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -81,25 +81,25 @@ QString XbelGenerator::indent(int depth)
|
|||||||
QString XbelGenerator::escapedText(const QString &str)
|
QString XbelGenerator::escapedText(const QString &str)
|
||||||
{
|
{
|
||||||
QString result = str;
|
QString result = str;
|
||||||
result.replace("&", "&");
|
result.replace('&', "&");
|
||||||
result.replace("<", "<");
|
result.replace('<', "<");
|
||||||
result.replace(">", ">");
|
result.replace('>', ">");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString XbelGenerator::escapedAttribute(const QString &str)
|
QString XbelGenerator::escapedAttribute(const QString &str)
|
||||||
{
|
{
|
||||||
QString result = escapedText(str);
|
QString result = escapedText(str);
|
||||||
result.replace("\"", """);
|
result.replace(QLatin1Char('"'), """);
|
||||||
result.prepend(QLatin1Char('"'));
|
result.prepend(QLatin1Char('"'));
|
||||||
result.append(QLatin1Char('"'));
|
result.append(QLatin1Char('"'));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XbelGenerator::generateItem(QTreeWidgetItem *item, int depth)
|
void XbelGenerator::generateItem(const QTreeWidgetItem *item, int depth)
|
||||||
{
|
{
|
||||||
QString tagName = item->data(0, Qt::UserRole).toString();
|
QString tagName = item->data(0, Qt::UserRole).toString();
|
||||||
if (tagName == "folder") {
|
if (tagName == QLatin1String("folder")) {
|
||||||
bool folded = !treeWidget->isItemExpanded(item);
|
bool folded = !treeWidget->isItemExpanded(item);
|
||||||
out << indent(depth) << "<folder folded=\"" << (folded ? "yes" : "no")
|
out << indent(depth) << "<folder folded=\"" << (folded ? "yes" : "no")
|
||||||
<< "\">\n"
|
<< "\">\n"
|
||||||
@ -110,7 +110,7 @@ void XbelGenerator::generateItem(QTreeWidgetItem *item, int depth)
|
|||||||
generateItem(item->child(i), depth + 1);
|
generateItem(item->child(i), depth + 1);
|
||||||
|
|
||||||
out << indent(depth) << "</folder>\n";
|
out << indent(depth) << "</folder>\n";
|
||||||
} else if (tagName == "bookmark") {
|
} else if (tagName == QLatin1String("bookmark")) {
|
||||||
out << indent(depth) << "<bookmark";
|
out << indent(depth) << "<bookmark";
|
||||||
if (!item->text(1).isEmpty())
|
if (!item->text(1).isEmpty())
|
||||||
out << " href=" << escapedAttribute(item->text(1));
|
out << " href=" << escapedAttribute(item->text(1));
|
||||||
@ -118,7 +118,7 @@ void XbelGenerator::generateItem(QTreeWidgetItem *item, int depth)
|
|||||||
<< indent(depth + 1) << "<title>" << escapedText(item->text(0))
|
<< indent(depth + 1) << "<title>" << escapedText(item->text(0))
|
||||||
<< "</title>\n"
|
<< "</title>\n"
|
||||||
<< indent(depth) << "</bookmark>\n";
|
<< indent(depth) << "</bookmark>\n";
|
||||||
} else if (tagName == "separator") {
|
} else if (tagName == QLatin1String("separator")) {
|
||||||
out << indent(depth) << "<separator/>\n";
|
out << indent(depth) << "<separator/>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ QT_END_NAMESPACE
|
|||||||
class XbelGenerator
|
class XbelGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XbelGenerator(QTreeWidget *treeWidget);
|
explicit XbelGenerator(const QTreeWidget *treeWidget);
|
||||||
|
|
||||||
bool write(QIODevice *device);
|
bool write(QIODevice *device);
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ private:
|
|||||||
static QString indent(int indentLevel);
|
static QString indent(int indentLevel);
|
||||||
static QString escapedText(const QString &str);
|
static QString escapedText(const QString &str);
|
||||||
static QString escapedAttribute(const QString &str);
|
static QString escapedAttribute(const QString &str);
|
||||||
void generateItem(QTreeWidgetItem *item, int depth);
|
void generateItem(const QTreeWidgetItem *item, int depth);
|
||||||
|
|
||||||
QTreeWidget *treeWidget;
|
const QTreeWidget *treeWidget;
|
||||||
QTextStream out;
|
QTextStream out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,6 +52,10 @@
|
|||||||
|
|
||||||
#include "xbelhandler.h"
|
#include "xbelhandler.h"
|
||||||
|
|
||||||
|
static inline QString versionAttribute() { return QStringLiteral("version"); }
|
||||||
|
static inline QString hrefAttribute() { return QStringLiteral("href"); }
|
||||||
|
static inline QString foldedAttribute() { return QStringLiteral("folded"); }
|
||||||
|
|
||||||
XbelHandler::XbelHandler(QTreeWidget *treeWidget)
|
XbelHandler::XbelHandler(QTreeWidget *treeWidget)
|
||||||
: treeWidget(treeWidget)
|
: treeWidget(treeWidget)
|
||||||
{
|
{
|
||||||
@ -72,32 +76,32 @@ bool XbelHandler::startElement(const QString & /* namespaceURI */,
|
|||||||
const QString &qName,
|
const QString &qName,
|
||||||
const QXmlAttributes &attributes)
|
const QXmlAttributes &attributes)
|
||||||
{
|
{
|
||||||
if (!metXbelTag && qName != "xbel") {
|
if (!metXbelTag && qName != QLatin1String("xbel")) {
|
||||||
errorStr = QObject::tr("The file is not an XBEL file.");
|
errorStr = QObject::tr("The file is not an XBEL file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qName == "xbel") {
|
if (qName == QLatin1String("xbel")) {
|
||||||
QString version = attributes.value("version");
|
QString version = attributes.value(versionAttribute());
|
||||||
if (!version.isEmpty() && version != "1.0") {
|
if (!version.isEmpty() && version != QLatin1String("1.0")) {
|
||||||
errorStr = QObject::tr("The file is not an XBEL version 1.0 file.");
|
errorStr = QObject::tr("The file is not an XBEL version 1.0 file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
metXbelTag = true;
|
metXbelTag = true;
|
||||||
} else if (qName == "folder") {
|
} else if (qName == QLatin1String("folder")) {
|
||||||
item = createChildItem(qName);
|
item = createChildItem(qName);
|
||||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||||
item->setIcon(0, folderIcon);
|
item->setIcon(0, folderIcon);
|
||||||
item->setText(0, QObject::tr("Folder"));
|
item->setText(0, QObject::tr("Folder"));
|
||||||
bool folded = (attributes.value("folded") != "no");
|
bool folded = (attributes.value(foldedAttribute()) != QLatin1String("no"));
|
||||||
treeWidget->setItemExpanded(item, !folded);
|
treeWidget->setItemExpanded(item, !folded);
|
||||||
} else if (qName == "bookmark") {
|
} else if (qName == QLatin1String("bookmark")) {
|
||||||
item = createChildItem(qName);
|
item = createChildItem(qName);
|
||||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||||
item->setIcon(0, bookmarkIcon);
|
item->setIcon(0, bookmarkIcon);
|
||||||
item->setText(0, QObject::tr("Unknown title"));
|
item->setText(0, QObject::tr("Unknown title"));
|
||||||
item->setText(1, attributes.value("href"));
|
item->setText(1, attributes.value(hrefAttribute()));
|
||||||
} else if (qName == "separator") {
|
} else if (qName == QLatin1String("separator")) {
|
||||||
item = createChildItem(qName);
|
item = createChildItem(qName);
|
||||||
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
|
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
|
||||||
item->setText(0, QString(30, 0xB7));
|
item->setText(0, QString(30, 0xB7));
|
||||||
@ -111,11 +115,11 @@ bool XbelHandler::endElement(const QString & /* namespaceURI */,
|
|||||||
const QString & /* localName */,
|
const QString & /* localName */,
|
||||||
const QString &qName)
|
const QString &qName)
|
||||||
{
|
{
|
||||||
if (qName == "title") {
|
if (qName == QLatin1String("title")) {
|
||||||
if (item)
|
if (item)
|
||||||
item->setText(0, currentText);
|
item->setText(0, currentText);
|
||||||
} else if (qName == "folder" || qName == "bookmark"
|
} else if (qName == QLatin1String("folder") || qName == QLatin1String("bookmark")
|
||||||
|| qName == "separator") {
|
|| qName == QLatin1String("separator")) {
|
||||||
item = item->parent();
|
item = item->parent();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -167,7 +167,7 @@
|
|||||||
add them to the \c fileMenu and \c helpMenu. The connections are as shown
|
add them to the \c fileMenu and \c helpMenu. The connections are as shown
|
||||||
below:
|
below:
|
||||||
|
|
||||||
\snippet streambookmarks/mainwindow.cpp 4
|
\snippet streambookmarks/mainwindow.cpp 5
|
||||||
|
|
||||||
The \c createMenus() function creates the \c fileMenu and \c helpMenu
|
The \c createMenus() function creates the \c fileMenu and \c helpMenu
|
||||||
and adds the QAction objects to them in order to create the menu shown
|
and adds the QAction objects to them in order to create the menu shown
|
||||||
|
@ -63,18 +63,41 @@ MainWindow::MainWindow()
|
|||||||
treeWidget = new QTreeWidget;
|
treeWidget = new QTreeWidget;
|
||||||
treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);
|
treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
treeWidget->setHeaderLabels(labels);
|
treeWidget->setHeaderLabels(labels);
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(treeWidget, &QWidget::customContextMenuRequested,
|
||||||
|
this, &MainWindow::onCustomContextMenuRequested);
|
||||||
|
#endif
|
||||||
setCentralWidget(treeWidget);
|
setCentralWidget(treeWidget);
|
||||||
|
|
||||||
createActions();
|
|
||||||
createMenus();
|
createMenus();
|
||||||
|
|
||||||
statusBar()->showMessage(tr("Ready"));
|
statusBar()->showMessage(tr("Ready"));
|
||||||
|
|
||||||
setWindowTitle(tr("QXmlStream Bookmarks"));
|
setWindowTitle(tr("QXmlStream Bookmarks"));
|
||||||
resize(480, 320);
|
const QSize availableSize = QApplication::desktop()->availableGeometry(this).size();
|
||||||
|
resize(availableSize.width() / 2, availableSize.height() / 3);
|
||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void MainWindow::onCustomContextMenuRequested(const QPoint &pos)
|
||||||
|
{
|
||||||
|
const QTreeWidgetItem *item = treeWidget->itemAt(pos);
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
const QString url = item->text(1);
|
||||||
|
QMenu contextMenu;
|
||||||
|
QAction *copyAction = contextMenu.addAction(tr("Copy Link to Clipboard"));
|
||||||
|
QAction *openAction = contextMenu.addAction(tr("Open"));
|
||||||
|
QAction *action = contextMenu.exec(treeWidget->viewport()->mapToGlobal(pos));
|
||||||
|
if (action == copyAction)
|
||||||
|
QGuiApplication::clipboard()->setText(url);
|
||||||
|
else if (action == openAction)
|
||||||
|
QDesktopServices::openUrl(QUrl(url));
|
||||||
|
}
|
||||||
|
#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
|
||||||
|
|
||||||
//! [1]
|
//! [1]
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
{
|
{
|
||||||
@ -92,8 +115,8 @@ void MainWindow::open()
|
|||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
||||||
tr("Cannot read file %1:\n%2.")
|
tr("Cannot read file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,8 +124,8 @@ void MainWindow::open()
|
|||||||
if (!reader.read(&file)) {
|
if (!reader.read(&file)) {
|
||||||
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
||||||
tr("Parse error in file %1:\n\n%2")
|
tr("Parse error in file %1:\n\n%2")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(reader.errorString()));
|
reader.errorString()));
|
||||||
} else {
|
} else {
|
||||||
statusBar()->showMessage(tr("File loaded"), 2000);
|
statusBar()->showMessage(tr("File loaded"), 2000);
|
||||||
}
|
}
|
||||||
@ -124,8 +147,8 @@ void MainWindow::saveAs()
|
|||||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
|
||||||
tr("Cannot write file %1:\n%2.")
|
tr("Cannot write file %1:\n%2.")
|
||||||
.arg(fileName)
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
.arg(file.errorString()));
|
file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,41 +167,23 @@ void MainWindow::about()
|
|||||||
}
|
}
|
||||||
//! [3]
|
//! [3]
|
||||||
|
|
||||||
//! [4]
|
|
||||||
void MainWindow::createActions()
|
|
||||||
{
|
|
||||||
openAct = new QAction(tr("&Open..."), this);
|
|
||||||
openAct->setShortcuts(QKeySequence::Open);
|
|
||||||
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
|
|
||||||
|
|
||||||
saveAsAct = new QAction(tr("&Save As..."), this);
|
|
||||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
|
||||||
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
|
|
||||||
|
|
||||||
exitAct = new QAction(tr("E&xit"), this);
|
|
||||||
exitAct->setShortcuts(QKeySequence::Quit);
|
|
||||||
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
|
|
||||||
|
|
||||||
aboutAct = new QAction(tr("&About"), this);
|
|
||||||
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
|
||||||
|
|
||||||
aboutQtAct = new QAction(tr("About &Qt"), this);
|
|
||||||
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
|
||||||
}
|
|
||||||
//! [4]
|
|
||||||
|
|
||||||
//! [5]
|
//! [5]
|
||||||
void MainWindow::createMenus()
|
void MainWindow::createMenus()
|
||||||
{
|
{
|
||||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
fileMenu->addAction(openAct);
|
QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &MainWindow::open);
|
||||||
fileMenu->addAction(saveAsAct);
|
openAct->setShortcuts(QKeySequence::Open);
|
||||||
fileMenu->addAction(exitAct);
|
|
||||||
|
QAction *saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &MainWindow::saveAs);
|
||||||
|
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||||
|
|
||||||
|
QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
|
||||||
|
exitAct->setShortcuts(QKeySequence::Quit);
|
||||||
|
|
||||||
menuBar()->addSeparator();
|
menuBar()->addSeparator();
|
||||||
|
|
||||||
helpMenu = menuBar()->addMenu(tr("&Help"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(tr("About &Qt"), qApp, &QCoreApplication::quit);
|
||||||
}
|
}
|
||||||
//! [5]
|
//! [5]
|
||||||
|
@ -69,20 +69,13 @@ public slots:
|
|||||||
void open();
|
void open();
|
||||||
void saveAs();
|
void saveAs();
|
||||||
void about();
|
void about();
|
||||||
|
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
||||||
|
void onCustomContextMenuRequested(const QPoint &pos);
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
void createActions();
|
|
||||||
void createMenus();
|
void createMenus();
|
||||||
|
|
||||||
QTreeWidget *treeWidget;
|
QTreeWidget *treeWidget;
|
||||||
|
|
||||||
QMenu *fileMenu;
|
|
||||||
QMenu *helpMenu;
|
|
||||||
QAction *openAct;
|
|
||||||
QAction *saveAsAct;
|
|
||||||
QAction *exitAct;
|
|
||||||
QAction *aboutAct;
|
|
||||||
QAction *aboutQtAct;
|
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -72,10 +72,12 @@ bool XbelReader::read(QIODevice *device)
|
|||||||
xml.setDevice(device);
|
xml.setDevice(device);
|
||||||
|
|
||||||
if (xml.readNextStartElement()) {
|
if (xml.readNextStartElement()) {
|
||||||
if (xml.name() == "xbel" && xml.attributes().value("version") == "1.0")
|
if (xml.name() == QLatin1String("xbel")
|
||||||
|
&& xml.attributes().value(versionAttribute()) == QLatin1String("1.0")) {
|
||||||
readXBEL();
|
readXBEL();
|
||||||
else
|
} else {
|
||||||
xml.raiseError(QObject::tr("The file is not an XBEL version 1.0 file."));
|
xml.raiseError(QObject::tr("The file is not an XBEL version 1.0 file."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !xml.error();
|
return !xml.error();
|
||||||
@ -95,14 +97,14 @@ QString XbelReader::errorString() const
|
|||||||
//! [3]
|
//! [3]
|
||||||
void XbelReader::readXBEL()
|
void XbelReader::readXBEL()
|
||||||
{
|
{
|
||||||
Q_ASSERT(xml.isStartElement() && xml.name() == "xbel");
|
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("xbel"));
|
||||||
|
|
||||||
while (xml.readNextStartElement()) {
|
while (xml.readNextStartElement()) {
|
||||||
if (xml.name() == "folder")
|
if (xml.name() == QLatin1String("folder"))
|
||||||
readFolder(0);
|
readFolder(0);
|
||||||
else if (xml.name() == "bookmark")
|
else if (xml.name() == QLatin1String("bookmark"))
|
||||||
readBookmark(0);
|
readBookmark(0);
|
||||||
else if (xml.name() == "separator")
|
else if (xml.name() == QLatin1String("separator"))
|
||||||
readSeparator(0);
|
readSeparator(0);
|
||||||
else
|
else
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
@ -113,7 +115,7 @@ void XbelReader::readXBEL()
|
|||||||
//! [4]
|
//! [4]
|
||||||
void XbelReader::readTitle(QTreeWidgetItem *item)
|
void XbelReader::readTitle(QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(xml.isStartElement() && xml.name() == "title");
|
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("title"));
|
||||||
|
|
||||||
QString title = xml.readElementText();
|
QString title = xml.readElementText();
|
||||||
item->setText(0, title);
|
item->setText(0, title);
|
||||||
@ -123,7 +125,7 @@ void XbelReader::readTitle(QTreeWidgetItem *item)
|
|||||||
//! [5]
|
//! [5]
|
||||||
void XbelReader::readSeparator(QTreeWidgetItem *item)
|
void XbelReader::readSeparator(QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(xml.isStartElement() && xml.name() == "separator");
|
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("separator"));
|
||||||
|
|
||||||
QTreeWidgetItem *separator = createChildItem(item);
|
QTreeWidgetItem *separator = createChildItem(item);
|
||||||
separator->setFlags(item->flags() & ~Qt::ItemIsSelectable);
|
separator->setFlags(item->flags() & ~Qt::ItemIsSelectable);
|
||||||
@ -134,20 +136,20 @@ void XbelReader::readSeparator(QTreeWidgetItem *item)
|
|||||||
|
|
||||||
void XbelReader::readFolder(QTreeWidgetItem *item)
|
void XbelReader::readFolder(QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(xml.isStartElement() && xml.name() == "folder");
|
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("folder"));
|
||||||
|
|
||||||
QTreeWidgetItem *folder = createChildItem(item);
|
QTreeWidgetItem *folder = createChildItem(item);
|
||||||
bool folded = (xml.attributes().value("folded") != "no");
|
bool folded = (xml.attributes().value(foldedAttribute()) != QLatin1String("no"));
|
||||||
treeWidget->setItemExpanded(folder, !folded);
|
treeWidget->setItemExpanded(folder, !folded);
|
||||||
|
|
||||||
while (xml.readNextStartElement()) {
|
while (xml.readNextStartElement()) {
|
||||||
if (xml.name() == "title")
|
if (xml.name() == QLatin1String("title"))
|
||||||
readTitle(folder);
|
readTitle(folder);
|
||||||
else if (xml.name() == "folder")
|
else if (xml.name() == QLatin1String("folder"))
|
||||||
readFolder(folder);
|
readFolder(folder);
|
||||||
else if (xml.name() == "bookmark")
|
else if (xml.name() == QLatin1String("bookmark"))
|
||||||
readBookmark(folder);
|
readBookmark(folder);
|
||||||
else if (xml.name() == "separator")
|
else if (xml.name() == QLatin1String("separator"))
|
||||||
readSeparator(folder);
|
readSeparator(folder);
|
||||||
else
|
else
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
@ -156,16 +158,16 @@ void XbelReader::readFolder(QTreeWidgetItem *item)
|
|||||||
|
|
||||||
void XbelReader::readBookmark(QTreeWidgetItem *item)
|
void XbelReader::readBookmark(QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(xml.isStartElement() && xml.name() == "bookmark");
|
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("bookmark"));
|
||||||
|
|
||||||
QTreeWidgetItem *bookmark = createChildItem(item);
|
QTreeWidgetItem *bookmark = createChildItem(item);
|
||||||
bookmark->setFlags(bookmark->flags() | Qt::ItemIsEditable);
|
bookmark->setFlags(bookmark->flags() | Qt::ItemIsEditable);
|
||||||
bookmark->setIcon(0, bookmarkIcon);
|
bookmark->setIcon(0, bookmarkIcon);
|
||||||
bookmark->setText(0, QObject::tr("Unknown title"));
|
bookmark->setText(0, QObject::tr("Unknown title"));
|
||||||
bookmark->setText(1, xml.attributes().value("href").toString());
|
bookmark->setText(1, xml.attributes().value(hrefAttribute()).toString());
|
||||||
|
|
||||||
while (xml.readNextStartElement()) {
|
while (xml.readNextStartElement()) {
|
||||||
if (xml.name() == "title")
|
if (xml.name() == QLatin1String("title"))
|
||||||
readTitle(bookmark);
|
readTitle(bookmark);
|
||||||
else
|
else
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
|
@ -71,6 +71,10 @@ public:
|
|||||||
|
|
||||||
QString errorString() const;
|
QString errorString() const;
|
||||||
|
|
||||||
|
static inline QString versionAttribute() { return QStringLiteral("version"); }
|
||||||
|
static inline QString hrefAttribute() { return QStringLiteral("href"); }
|
||||||
|
static inline QString foldedAttribute() { return QStringLiteral("folded"); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! [2]
|
//! [2]
|
||||||
void readXBEL();
|
void readXBEL();
|
||||||
|
@ -51,9 +51,14 @@
|
|||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
|
|
||||||
#include "xbelwriter.h"
|
#include "xbelwriter.h"
|
||||||
|
#include "xbelreader.h"
|
||||||
|
|
||||||
|
static inline QString yesValue() { return QStringLiteral("yes"); }
|
||||||
|
static inline QString noValue() { return QStringLiteral("no"); }
|
||||||
|
static inline QString titleElement() { return QStringLiteral("title"); }
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
XbelWriter::XbelWriter(QTreeWidget *treeWidget)
|
XbelWriter::XbelWriter(const QTreeWidget *treeWidget)
|
||||||
: treeWidget(treeWidget)
|
: treeWidget(treeWidget)
|
||||||
{
|
{
|
||||||
xml.setAutoFormatting(true);
|
xml.setAutoFormatting(true);
|
||||||
@ -66,9 +71,9 @@ bool XbelWriter::writeFile(QIODevice *device)
|
|||||||
xml.setDevice(device);
|
xml.setDevice(device);
|
||||||
|
|
||||||
xml.writeStartDocument();
|
xml.writeStartDocument();
|
||||||
xml.writeDTD("<!DOCTYPE xbel>");
|
xml.writeDTD(QStringLiteral("<!DOCTYPE xbel>"));
|
||||||
xml.writeStartElement("xbel");
|
xml.writeStartElement(QStringLiteral("xbel"));
|
||||||
xml.writeAttribute("version", "1.0");
|
xml.writeAttribute(XbelReader::versionAttribute(), QStringLiteral("1.0"));
|
||||||
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
|
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
|
||||||
writeItem(treeWidget->topLevelItem(i));
|
writeItem(treeWidget->topLevelItem(i));
|
||||||
|
|
||||||
@ -78,24 +83,24 @@ bool XbelWriter::writeFile(QIODevice *device)
|
|||||||
//! [1]
|
//! [1]
|
||||||
|
|
||||||
//! [2]
|
//! [2]
|
||||||
void XbelWriter::writeItem(QTreeWidgetItem *item)
|
void XbelWriter::writeItem(const QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
QString tagName = item->data(0, Qt::UserRole).toString();
|
QString tagName = item->data(0, Qt::UserRole).toString();
|
||||||
if (tagName == "folder") {
|
if (tagName == QLatin1String("folder")) {
|
||||||
bool folded = !treeWidget->isItemExpanded(item);
|
bool folded = !treeWidget->isItemExpanded(item);
|
||||||
xml.writeStartElement(tagName);
|
xml.writeStartElement(tagName);
|
||||||
xml.writeAttribute("folded", folded ? "yes" : "no");
|
xml.writeAttribute(XbelReader::foldedAttribute(), folded ? yesValue() : noValue());
|
||||||
xml.writeTextElement("title", item->text(0));
|
xml.writeTextElement(titleElement(), item->text(0));
|
||||||
for (int i = 0; i < item->childCount(); ++i)
|
for (int i = 0; i < item->childCount(); ++i)
|
||||||
writeItem(item->child(i));
|
writeItem(item->child(i));
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
} else if (tagName == "bookmark") {
|
} else if (tagName == QLatin1String("bookmark")) {
|
||||||
xml.writeStartElement(tagName);
|
xml.writeStartElement(tagName);
|
||||||
if (!item->text(1).isEmpty())
|
if (!item->text(1).isEmpty())
|
||||||
xml.writeAttribute("href", item->text(1));
|
xml.writeAttribute(XbelReader::hrefAttribute(), item->text(1));
|
||||||
xml.writeTextElement("title", item->text(0));
|
xml.writeTextElement(titleElement(), item->text(0));
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
} else if (tagName == "separator") {
|
} else if (tagName == QLatin1String("separator")) {
|
||||||
xml.writeEmptyElement(tagName);
|
xml.writeEmptyElement(tagName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ QT_END_NAMESPACE
|
|||||||
class XbelWriter
|
class XbelWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XbelWriter(QTreeWidget *treeWidget);
|
explicit XbelWriter(const QTreeWidget *treeWidget);
|
||||||
bool writeFile(QIODevice *device);
|
bool writeFile(QIODevice *device);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void writeItem(QTreeWidgetItem *item);
|
void writeItem(const QTreeWidgetItem *item);
|
||||||
QXmlStreamWriter xml;
|
QXmlStreamWriter xml;
|
||||||
QTreeWidget *treeWidget;
|
const QTreeWidget *treeWidget;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user