6.5.3 clean

This commit is contained in:
kleuter
2023-11-01 18:02:52 +01:00
parent bbe896803b
commit 7018d9e6c8
2170 changed files with 57471 additions and 43550 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -3,16 +3,94 @@
/*!
\example dombookmarks
\title DOM Bookmarks Example
\examplecategory {Input/Output}
\title DOM Bookmarks Application
\examplecategory {Data Processing & I/O}
\ingroup xml-examples
\meta tag {xml}
\brief Provides a reader for XML Bookmark Exchange Language files.
The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL)
files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks
example provides an alternative way to read this type of file.
The DOM Bookmarks Application provides a reader for XML Bookmark Exchange
Language (XBEL) files that uses Qt's DOM-based XML API to read and parse
the files. The {QXmlStream Bookmarks Example} provides an alternative
way to read this type of file.
\image dombookmarks-example.png
\image screenshot.png
\section1 The XbelTree Class Definition
The XbelTree class has functions for reading and writing to the filesystem.
It inherits from the QTreeWidget class, contains the model for the
displaying of the bookmarks, and allows it to be edited.
\snippet dombookmarks/xbeltree.h 0
\section1 The XbelTree Class Implementation
The \c XbelTree constructor accepts a QWidget within which it is placed.
The \c folderIcon is set to QIcon::Normal mode where the pixmap is only
displayed when the user is not interacting with the icon. The
QStyle::SP_DirClosedIcon, QStyle::SP_DirOpenIcon, and QStyle::SP_FileIcon
correspond to standard pixmaps that follow the style of your GUI.
\snippet dombookmarks/xbeltree.cpp 0
The \c read() function opens the given QIODevice using
QDomDocument::setContent. If it succeeds opening the file and the top
level headers are verified, the contents of the class is cleared before
the file contents is parsed by iterating all the top level XML nodes and
calling \c parseFolderElement() on each of them.
\snippet dombookmarks/xbeltree.cpp 1
The \c parseFolderElement() function handles the different element types
and calls itself recursively if the element is a subfolder.
\snippet dombookmarks/xbeltree.cpp 3
The \c write() function saves the domDocument to the given QIODevice using
QDomDocument::save.
\snippet dombookmarks/xbeltree.cpp 2
\section1 The MainWindow Class Definition
The \c MainWindow class is a subclass of QMainWindow, with a
\c File menu and a \c Help menu.
\snippet dombookmarks/mainwindow.h 0
\section1 The MainWindow Class Implementation
The \c MainWindow constructor instantiates the member XbelTree object,
and sets its header with a QStringList object, \c labels.
The constructor also invokes \c createMenus() to set up the menus.
The \c statusBar() is used to display the message "Ready".
\snippet dombookmarks/mainwindow.cpp 0
The \c createMenus() function populates the menus and sets keyboard
shortcuts.
\snippet dombookmarks/mainwindow.cpp 4
The \c open() function enables the user to open an XBEL file using
QFileDialog. A warning message is displayed along
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().
\snippet dombookmarks/mainwindow.cpp 1
The \c saveAs() function displays a QFileDialog, prompting the user for
a \c fileName. Similar to the \c open() function, this function also
displays a warning message if the file cannot be written to. If this
succeeds it calls \c XbelTree::write().
\snippet dombookmarks/mainwindow.cpp 2
The \c about() function displays a QMessageBox with a brief description
of the example.
\snippet dombookmarks/mainwindow.cpp 3
See the \l{http://pyxml.sourceforge.net/topics/xbel/}{XML Bookmark Exchange Language
Resource Page} for more information about XBEL files.

View File

@ -6,7 +6,7 @@ SOURCES = main.cpp \
QT += xml widgets
requires(qtConfig(filedialog))
EXAMPLE_FILES = frank.xbel jennifer.xbel
EXAMPLE_FILES = jennifer.xbel
# install
target.path = $$[QT_INSTALL_EXAMPLES]/xml/dombookmarks

View File

@ -3,66 +3,66 @@
<xbel version="1.0">
<folder folded="no">
<title>Qt Resources</title>
<bookmark href="http://qt.io/">
<bookmark href="https://www.qt.io/">
<title>Qt home page</title>
</bookmark>
<bookmark href="https://www.qt.io/partners/">
<bookmark href="https://www.qt.io/contact-us/partners">
<title>Qt Partners</title>
</bookmark>
<bookmark href="https://www.qt.io/qt-training/">
<title>Training</title>
<bookmark href="https://www.qt.io/qt-professional-services">
<title>Professional Services</title>
</bookmark>
<bookmark href="http://doc.qt.io/">
<title>Qt 5 documentation</title>
</bookmark>
<bookmark href="http://qt-project.org/faq/">
<title>Frequently Asked Questions</title>
<bookmark href="https://doc.qt.io/">
<title>Qt Documentation</title>
</bookmark>
<folder folded="yes">
<title>Community Resources</title>
<bookmark href="http://www.qtcentre.org/content/">
<bookmark href="https://contribute.qt-project.org">
<title>The Qt Project</title>
</bookmark>
<bookmark href="https://www.qtcentre.org/content/">
<title>Qt Centre</title>
</bookmark>
<bookmark href="http://www.qtforum.org/">
<title>QtForum.org</title>
<bookmark href="https://forum.qt.io/">
<title>Forum.Qt.org</title>
</bookmark>
<bookmark href="http://digitalfanatics.org/projects/qt_tutorial/">
<bookmark href="https://digitalfanatics.org/projects/qt_tutorial/">
<title>The Independent Qt Tutorial</title>
</bookmark>
<bookmark href="http://www.qtforum.de/">
<bookmark href="https://www.qtforum.de/">
<title>German Qt Forum</title>
</bookmark>
<bookmark href="http://www.korone.net/">
<bookmark href="https://www.qt-dev.com/">
<title>Korean Qt Community Site</title>
</bookmark>
<bookmark href="http://prog.org.ru/">
<bookmark href="http://www.prog.org.ru/">
<title>Russian Qt Forum</title>
</bookmark>
</folder>
</folder>
<folder folded="no">
<title>Online Dictionaries</title>
<bookmark href="http://www.dictionary.com/">
<bookmark href="https://www.dictionary.com/">
<title>Dictionary.com</title>
</bookmark>
<bookmark href="http://www.m-w.com/">
<bookmark href="https://www.merriam-webster.com/">
<title>Merriam-Webster Online</title>
</bookmark>
<bookmark href="http://dictionary.cambridge.org/">
<bookmark href="https://dictionary.cambridge.org/">
<title>Cambridge Dictionaries Online</title>
</bookmark>
<bookmark href="http://www.onelook.com/">
<bookmark href="https://www.onelook.com/">
<title>OneLook Dictionary Search</title>
</bookmark>
<separator/>
<bookmark href="http://dict.tu-chemnitz.de/">
<title>TU Chemnitz German-English Dictionary</title>
<bookmark href="https://dict.tu-chemnitz.de/">
<title>BEOLINGUS, a service of TU Chemnitz</title>
</bookmark>
<separator/>
<bookmark href="http://atilf.atilf.fr/tlf.htm">
<title>Trésor de la Langue Française informatisé</title>
</bookmark>
<bookmark href="http://dictionnaires.atilf.fr/dictionnaires/ACADEMIE/">
<bookmark href="https://www.dictionnaire-academie.fr/">
<title>Dictionnaire de l'Académie Française</title>
</bookmark>
</folder>

View File

@ -1,11 +1,21 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "mainwindow.h"
#include "xbeltree.h"
#include <QApplication>
#include <QFileDialog>
#include <QMenuBar>
#include <QMessageBox>
#include <QStatusBar>
#include <QAction>
#include <QScreen>
using namespace Qt::StringLiterals;
//! [0]
MainWindow::MainWindow()
{
xbelTree = new XbelTree;
@ -19,19 +29,20 @@ MainWindow::MainWindow()
const QSize availableSize = screen()->availableGeometry().size();
resize(availableSize.width() / 2, availableSize.height() / 3);
}
//! [0]
//! [1]
void MainWindow::open()
{
QString fileName =
QFileDialog::getOpenFileName(this, tr("Open Bookmark File"),
QDir::currentPath(),
tr("XBEL Files (*.xbel *.xml)"));
if (fileName.isEmpty())
QFileDialog fileDialog(this, tr("Open Bookmark File"), QDir::currentPath());
fileDialog.setMimeTypeFilters({"application/x-xbel"_L1});
if (fileDialog.exec() != QDialog::Accepted)
return;
const QString fileName = fileDialog.selectedFiles().constFirst();
QFile file(fileName);
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.")
.arg(QDir::toNativeSeparators(fileName),
file.errorString()));
@ -41,19 +52,22 @@ void MainWindow::open()
if (xbelTree->read(&file))
statusBar()->showMessage(tr("File loaded"), 2000);
}
//! [1]
//! [2]
void MainWindow::saveAs()
{
QString fileName =
QFileDialog::getSaveFileName(this, tr("Save Bookmark File"),
QDir::currentPath(),
tr("XBEL Files (*.xbel *.xml)"));
if (fileName.isEmpty())
QFileDialog fileDialog(this, tr("Save Bookmark File"), QDir::currentPath());
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
fileDialog.setDefaultSuffix("xbel"_L1);
fileDialog.setMimeTypeFilters({"application/x-xbel"_L1});
if (fileDialog.exec() != QDialog::Accepted)
return;
const QString fileName = fileDialog.selectedFiles().constFirst();
QFile file(fileName);
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.")
.arg(QDir::toNativeSeparators(fileName),
file.errorString()));
@ -63,7 +77,9 @@ void MainWindow::saveAs()
if (xbelTree->write(&file))
statusBar()->showMessage(tr("File saved"), 2000);
}
//! [2]
//! [3]
void MainWindow::about()
{
QMessageBox::about(this, tr("About DOM Bookmarks"),
@ -71,7 +87,9 @@ void MainWindow::about()
"use Qt's DOM classes to read and write XML "
"documents."));
}
//! [3]
//! [4]
void MainWindow::createMenus()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
@ -88,5 +106,6 @@ void MainWindow::createMenus()
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
helpMenu->addAction(tr("About &Qt"), qApp, &QCoreApplication::quit);
helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
}
//! [4]

View File

@ -8,6 +8,7 @@
class XbelTree;
//! [0]
class MainWindow : public QMainWindow
{
Q_OBJECT
@ -25,5 +26,6 @@ private:
XbelTree *xbelTree;
};
//! [0]
#endif

View File

@ -1,30 +1,41 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#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 };
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 const auto titleElement = u"title"_s;
static const auto folderElement = u"folder"_s;
static const auto bookmarkElement = u"bookmark"_s;
static inline QString versionAttribute() { return QStringLiteral("version"); }
static inline QString hrefAttribute() { return QStringLiteral("href"); }
static inline QString foldedAttribute() { return QStringLiteral("folded"); }
static const auto versionAttribute = u"version"_s;
static const auto hrefAttribute = u"href"_s;
static const auto foldedAttribute = u"folded"_s;
//! [0]
XbelTree::XbelTree(QWidget *parent)
: QTreeWidget(parent)
{
QStringList labels;
labels << tr("Title") << tr("Location");
header()->setSectionResizeMode(QHeaderView::Stretch);
setHeaderLabels(labels);
setHeaderLabels({tr("Title"), tr("Location")});
folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
QIcon::Normal, QIcon::Off);
@ -32,8 +43,9 @@ XbelTree::XbelTree(QWidget *parent)
QIcon::Normal, QIcon::On);
bookmarkIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
}
//! [0]
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
#if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
void XbelTree::contextMenuEvent(QContextMenuEvent *event)
{
const QTreeWidgetItem *item = itemAt(event->pos());
@ -49,8 +61,9 @@ void XbelTree::contextMenuEvent(QContextMenuEvent *event)
else if (action == openAction)
QDesktopServices::openUrl(QUrl(url));
}
#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
#endif // QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
//! [1]
bool XbelTree::read(QIODevice *device)
{
QDomDocument::ParseResult result =
@ -69,8 +82,8 @@ bool XbelTree::read(QIODevice *device)
QMessageBox::information(window(), tr("DOM Bookmarks"),
tr("The file is not an XBEL file."));
return false;
} else if (root.hasAttribute(versionAttribute())
&& root.attribute(versionAttribute()) != QLatin1String("1.0")) {
} else if (root.hasAttribute(versionAttribute)
&& root.attribute(versionAttribute) != "1.0"_L1) {
QMessageBox::information(window(), tr("DOM Bookmarks"),
tr("The file is not an XBEL version 1.0 "
"file."));
@ -81,17 +94,19 @@ bool XbelTree::read(QIODevice *device)
disconnect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
QDomElement child = root.firstChildElement(folderElement());
QDomElement child = root.firstChildElement(folderElement);
while (!child.isNull()) {
parseFolderElement(child);
child = child.nextSiblingElement(folderElement());
child = child.nextSiblingElement(folderElement);
}
connect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement);
return true;
}
//! [1]
//! [2]
bool XbelTree::write(QIODevice *device) const
{
const int IndentSize = 4;
@ -100,65 +115,70 @@ bool XbelTree::write(QIODevice *device) const
domDocument.save(out, IndentSize);
return true;
}
//! [2]
void XbelTree::updateDomElement(const QTreeWidgetItem *item, int column)
{
QDomElement element = qvariant_cast<QDomElement>(item->data(0, DomElementRole));
if (!element.isNull()) {
if (column == 0) {
QDomElement oldTitleElement = element.firstChildElement(titleElement());
QDomElement newTitleElement = domDocument.createElement(titleElement());
QDomElement oldTitleElement = element.firstChildElement(titleElement);
QDomElement newTitleElement = domDocument.createElement(titleElement);
QDomText newTitleText = domDocument.createTextNode(item->text(0));
newTitleElement.appendChild(newTitleText);
element.replaceChild(newTitleElement, oldTitleElement);
} else {
if (element.tagName() == bookmarkElement())
element.setAttribute(hrefAttribute(), item->text(1));
if (element.tagName() == bookmarkElement)
element.setAttribute(hrefAttribute, item->text(1));
}
}
}
//! [3]
void XbelTree::parseFolderElement(const QDomElement &element,
QTreeWidgetItem *parentItem)
{
QTreeWidgetItem *item = createItem(element, parentItem);
QString title = element.firstChildElement(titleElement()).text();
QString title = element.firstChildElement(titleElement).text();
if (title.isEmpty())
title = QObject::tr("Folder");
title = tr("Folder");
item->setFlags(item->flags() | Qt::ItemIsEditable);
item->setIcon(0, folderIcon);
item->setText(0, title);
bool folded = (element.attribute(foldedAttribute()) != QLatin1String("no"));
bool folded = (element.attribute(foldedAttribute) != "no"_L1);
item->setExpanded(!folded);
constexpr char16_t midDot = u'\xB7';
static const QString dots = QString(30, midDot);
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.tagName() == folderElement()) {
if (child.tagName() == folderElement) {
parseFolderElement(child, item);
} else if (child.tagName() == bookmarkElement()) {
} else if (child.tagName() == bookmarkElement) {
QTreeWidgetItem *childItem = createItem(child, item);
QString title = child.firstChildElement(titleElement()).text();
QString title = child.firstChildElement(titleElement).text();
if (title.isEmpty())
title = QObject::tr("Folder");
title = tr("Folder");
childItem->setFlags(item->flags() | Qt::ItemIsEditable);
childItem->setIcon(0, bookmarkIcon);
childItem->setText(0, title);
childItem->setText(1, child.attribute(hrefAttribute()));
} else if (child.tagName() == QLatin1String("separator")) {
childItem->setText(1, child.attribute(hrefAttribute));
} else if (child.tagName() == "separator"_L1) {
QTreeWidgetItem *childItem = createItem(child, item);
childItem->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEditable));
childItem->setText(0, QString(30, u'\xB7'));
childItem->setText(0, dots);
}
child = child.nextSiblingElement();
}
}
//! [3]
QTreeWidgetItem *XbelTree::createItem(const QDomElement &element,
QTreeWidgetItem *parentItem)

View File

@ -8,18 +8,19 @@
#include <QIcon>
#include <QTreeWidget>
//! [0]
class XbelTree : public QTreeWidget
{
Q_OBJECT
public:
XbelTree(QWidget *parent = nullptr);
explicit XbelTree(QWidget *parent = nullptr);
bool read(QIODevice *device);
bool write(QIODevice *device) const;
protected:
#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
#if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu)
void contextMenuEvent(QContextMenuEvent *event) override;
#endif
@ -36,5 +37,6 @@ private:
QIcon folderIcon;
QIcon bookmarkIcon;
};
//! [0]
#endif