Brush up the DOM bookmarks example
- Use modern string literals (use QStringLiteral instead of QLatin1StringView for strings that go into the DOM API). - Use mime types in the file dialog handling - Streamline code - Remove mentions of SAX - Use per class includes - Do not use QObject::tr() - Use the configure system instead of QT_NO... defines - Fix some doc text typos Complements 3dd3268ded4dd74c64d7ec726fd534375ab9f018. Task-number: QTBUG-111974 Change-Id: If0dc7b61e729d0a71f37743efc9b82e285d3f451 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 3a553507a134bee1562d34ebbf786a053d36fc05)
This commit is contained in:
parent
919d479142
commit
9e85c70b37
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
The XbelTree class has functions for reading and writing to the filesystem.
|
The XbelTree class has functions for reading and writing to the filesystem.
|
||||||
It inherits from the QTreeWidget class, contains the model for the
|
It inherits from the QTreeWidget class, contains the model for the
|
||||||
dispalying of the bookmarks, and allows it to be edited.
|
displaying of the bookmarks, and allows it to be edited.
|
||||||
|
|
||||||
\snippet dombookmarks/xbeltree.h 0
|
\snippet dombookmarks/xbeltree.h 0
|
||||||
|
|
||||||
@ -68,23 +68,22 @@
|
|||||||
|
|
||||||
\snippet dombookmarks/mainwindow.cpp 0
|
\snippet dombookmarks/mainwindow.cpp 0
|
||||||
|
|
||||||
The \c createMenus() function poulates the menus and sets keyboard
|
The \c createMenus() function populates the menus and sets keyboard
|
||||||
shortcuts.
|
shortcuts.
|
||||||
|
|
||||||
\snippet dombookmarks/mainwindow.cpp 4
|
\snippet dombookmarks/mainwindow.cpp 4
|
||||||
|
|
||||||
The \c open() function enables the user to open an XBEL file using
|
The \c open() function enables the user to open an XBEL file using
|
||||||
QFileDialog::getOpenFileName(). A warning message is displayed along
|
QFileDialog. A warning message is displayed along
|
||||||
with the \c fileName and \c errorString if the file cannot be read or
|
with the \c fileName and \c errorString if the file cannot be read or
|
||||||
if there is a parse error. If it succeeds it calls \c XbelTree::read().
|
if there is a parse error. If it succeeds it calls \c XbelTree::read().
|
||||||
|
|
||||||
\snippet dombookmarks/mainwindow.cpp 1
|
\snippet dombookmarks/mainwindow.cpp 1
|
||||||
|
|
||||||
The \c saveAs() function displays a QFileDialog, prompting the user for
|
The \c saveAs() function displays a QFileDialog, prompting the user for
|
||||||
a \c fileName using QFileDialog::getSaveFileName(). Similar to the
|
a \c fileName. Similar to the \c open() function, this function also
|
||||||
\c open() function, this function also displays a warning message if
|
displays a warning message if the file cannot be written to. If this
|
||||||
the file cannot be written to. IF this succeeds it calls \c
|
succeeds it calls \c XbelTree::write().
|
||||||
XbelTree::write().
|
|
||||||
|
|
||||||
\snippet dombookmarks/mainwindow.cpp 2
|
\snippet dombookmarks/mainwindow.cpp 2
|
||||||
|
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
// Copyright (C) 2016 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "xbeltree.h"
|
#include "xbeltree.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStatusBar>
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
@ -25,16 +34,15 @@ MainWindow::MainWindow()
|
|||||||
//! [1]
|
//! [1]
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
{
|
{
|
||||||
QString fileName =
|
QFileDialog fileDialog(this, tr("Open Bookmark File"), QDir::currentPath());
|
||||||
QFileDialog::getOpenFileName(this, tr("Open Bookmark File"),
|
fileDialog.setMimeTypeFilters({"application/x-xbel"_L1});
|
||||||
QDir::currentPath(),
|
if (fileDialog.exec() != QDialog::Accepted)
|
||||||
tr("XBEL Files (*.xbel *.xml)"));
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const QString fileName = fileDialog.selectedFiles().constFirst();
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("DOM Bookmarks"),
|
||||||
tr("Cannot read file %1:\n%2.")
|
tr("Cannot read file %1:\n%2.")
|
||||||
.arg(QDir::toNativeSeparators(fileName),
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
file.errorString()));
|
file.errorString()));
|
||||||
@ -49,16 +57,17 @@ void MainWindow::open()
|
|||||||
//! [2]
|
//! [2]
|
||||||
void MainWindow::saveAs()
|
void MainWindow::saveAs()
|
||||||
{
|
{
|
||||||
QString fileName =
|
QFileDialog fileDialog(this, tr("Save Bookmark File"), QDir::currentPath());
|
||||||
QFileDialog::getSaveFileName(this, tr("Save Bookmark File"),
|
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
QDir::currentPath(),
|
fileDialog.setDefaultSuffix("xbel"_L1);
|
||||||
tr("XBEL Files (*.xbel *.xml)"));
|
fileDialog.setMimeTypeFilters({"application/x-xbel"_L1});
|
||||||
if (fileName.isEmpty())
|
if (fileDialog.exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const QString fileName = fileDialog.selectedFiles().constFirst();
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||||
QMessageBox::warning(this, tr("SAX Bookmarks"),
|
QMessageBox::warning(this, tr("DOM Bookmarks"),
|
||||||
tr("Cannot write file %1:\n%2.")
|
tr("Cannot write file %1:\n%2.")
|
||||||
.arg(QDir::toNativeSeparators(fileName),
|
.arg(QDir::toNativeSeparators(fileName),
|
||||||
file.errorString()));
|
file.errorString()));
|
||||||
|
@ -1,31 +1,41 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
// Copyright (C) 2016 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "xbeltree.h"
|
#include "xbeltree.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
|
||||||
|
# include <QClipboard>
|
||||||
|
# include <QContextMenuEvent>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
enum { DomElementRole = Qt::UserRole + 1 };
|
enum { DomElementRole = Qt::UserRole + 1 };
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QDomElement)
|
Q_DECLARE_METATYPE(QDomElement)
|
||||||
|
|
||||||
static inline QString titleElement() { return QStringLiteral("title"); }
|
static const auto titleElement = u"title"_s;
|
||||||
static inline QString folderElement() { return QStringLiteral("folder"); }
|
static const auto folderElement = u"folder"_s;
|
||||||
static inline QString bookmarkElement() { return QStringLiteral("bookmark"); }
|
static const auto bookmarkElement = u"bookmark"_s;
|
||||||
|
|
||||||
static inline QString versionAttribute() { return QStringLiteral("version"); }
|
static const auto versionAttribute = u"version"_s;
|
||||||
static inline QString hrefAttribute() { return QStringLiteral("href"); }
|
static const auto hrefAttribute = u"href"_s;
|
||||||
static inline QString foldedAttribute() { return QStringLiteral("folded"); }
|
static const auto foldedAttribute = u"folded"_s;
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
XbelTree::XbelTree(QWidget *parent)
|
XbelTree::XbelTree(QWidget *parent)
|
||||||
: QTreeWidget(parent)
|
: QTreeWidget(parent)
|
||||||
{
|
{
|
||||||
QStringList labels;
|
|
||||||
labels << tr("Title") << tr("Location");
|
|
||||||
|
|
||||||
header()->setSectionResizeMode(QHeaderView::Stretch);
|
header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
setHeaderLabels(labels);
|
setHeaderLabels({tr("Title"), tr("Location")});
|
||||||
|
|
||||||
folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
|
folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
|
||||||
QIcon::Normal, QIcon::Off);
|
QIcon::Normal, QIcon::Off);
|
||||||
@ -35,7 +45,7 @@ XbelTree::XbelTree(QWidget *parent)
|
|||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
#if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
|
||||||
void XbelTree::contextMenuEvent(QContextMenuEvent *event)
|
void XbelTree::contextMenuEvent(QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
const QTreeWidgetItem *item = itemAt(event->pos());
|
const QTreeWidgetItem *item = itemAt(event->pos());
|
||||||
@ -51,7 +61,7 @@ void XbelTree::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
else if (action == openAction)
|
else if (action == openAction)
|
||||||
QDesktopServices::openUrl(QUrl(url));
|
QDesktopServices::openUrl(QUrl(url));
|
||||||
}
|
}
|
||||||
#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
|
#endif // QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
|
||||||
|
|
||||||
//! [1]
|
//! [1]
|
||||||
bool XbelTree::read(QIODevice *device)
|
bool XbelTree::read(QIODevice *device)
|
||||||
@ -72,8 +82,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(versionAttribute())
|
} else if (root.hasAttribute(versionAttribute)
|
||||||
&& root.attribute(versionAttribute()) != QLatin1String("1.0")) {
|
&& root.attribute(versionAttribute) != "1.0"_L1) {
|
||||||
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."));
|
||||||
@ -84,10 +94,10 @@ bool XbelTree::read(QIODevice *device)
|
|||||||
|
|
||||||
disconnect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
disconnect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
||||||
|
|
||||||
QDomElement child = root.firstChildElement(folderElement());
|
QDomElement child = root.firstChildElement(folderElement);
|
||||||
while (!child.isNull()) {
|
while (!child.isNull()) {
|
||||||
parseFolderElement(child);
|
parseFolderElement(child);
|
||||||
child = child.nextSiblingElement(folderElement());
|
child = child.nextSiblingElement(folderElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
connect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
|
||||||
@ -112,16 +122,16 @@ void XbelTree::updateDomElement(const QTreeWidgetItem *item, int column)
|
|||||||
QDomElement element = qvariant_cast<QDomElement>(item->data(0, DomElementRole));
|
QDomElement element = qvariant_cast<QDomElement>(item->data(0, DomElementRole));
|
||||||
if (!element.isNull()) {
|
if (!element.isNull()) {
|
||||||
if (column == 0) {
|
if (column == 0) {
|
||||||
QDomElement oldTitleElement = element.firstChildElement(titleElement());
|
QDomElement oldTitleElement = element.firstChildElement(titleElement);
|
||||||
QDomElement newTitleElement = domDocument.createElement(titleElement());
|
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() == bookmarkElement())
|
if (element.tagName() == bookmarkElement)
|
||||||
element.setAttribute(hrefAttribute(), item->text(1));
|
element.setAttribute(hrefAttribute, item->text(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,35 +142,35 @@ void XbelTree::parseFolderElement(const QDomElement &element,
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *item = createItem(element, parentItem);
|
QTreeWidgetItem *item = createItem(element, parentItem);
|
||||||
|
|
||||||
QString title = element.firstChildElement(titleElement()).text();
|
QString title = element.firstChildElement(titleElement).text();
|
||||||
if (title.isEmpty())
|
if (title.isEmpty())
|
||||||
title = QObject::tr("Folder");
|
title = tr("Folder");
|
||||||
|
|
||||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||||
item->setIcon(0, folderIcon);
|
item->setIcon(0, folderIcon);
|
||||||
item->setText(0, title);
|
item->setText(0, title);
|
||||||
|
|
||||||
bool folded = (element.attribute(foldedAttribute()) != QLatin1String("no"));
|
bool folded = (element.attribute(foldedAttribute) != "no"_L1);
|
||||||
item->setExpanded(!folded);
|
item->setExpanded(!folded);
|
||||||
|
|
||||||
constexpr char16_t midDot = u'\xB7';
|
constexpr char16_t midDot = u'\xB7';
|
||||||
static const QString dots = QString(30, midDot);
|
static const QString dots = QString(30, midDot);
|
||||||
QDomElement child = element.firstChildElement();
|
QDomElement child = element.firstChildElement();
|
||||||
while (!child.isNull()) {
|
while (!child.isNull()) {
|
||||||
if (child.tagName() == folderElement()) {
|
if (child.tagName() == folderElement) {
|
||||||
parseFolderElement(child, item);
|
parseFolderElement(child, item);
|
||||||
} else if (child.tagName() == bookmarkElement()) {
|
} else if (child.tagName() == bookmarkElement) {
|
||||||
QTreeWidgetItem *childItem = createItem(child, item);
|
QTreeWidgetItem *childItem = createItem(child, item);
|
||||||
|
|
||||||
QString title = child.firstChildElement(titleElement()).text();
|
QString title = child.firstChildElement(titleElement).text();
|
||||||
if (title.isEmpty())
|
if (title.isEmpty())
|
||||||
title = QObject::tr("Folder");
|
title = 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(hrefAttribute()));
|
childItem->setText(1, child.attribute(hrefAttribute));
|
||||||
} else if (child.tagName() == QLatin1String("separator")) {
|
} else if (child.tagName() == "separator"_L1) {
|
||||||
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, dots);
|
childItem->setText(0, dots);
|
||||||
|
@ -14,13 +14,13 @@ class XbelTree : public QTreeWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XbelTree(QWidget *parent = nullptr);
|
explicit XbelTree(QWidget *parent = nullptr);
|
||||||
|
|
||||||
bool read(QIODevice *device);
|
bool read(QIODevice *device);
|
||||||
bool write(QIODevice *device) const;
|
bool write(QIODevice *device) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
|
#if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user