6#include <QtQml/qqmlcontext.h>
7#include <QtQml/qqmlengine.h>
8#include <QtQml/qqmlinfo.h>
9#include <QtQml/qqmlfile.h>
11#include <QtCore/qcoreapplication.h>
12#include <QtCore/qfile.h>
13#include <QtCore/qfuturewatcher.h>
14#include <QtCore/qtimer.h>
15#include <QtCore/qxmlstream.h>
17#if QT_CONFIG(qml_network)
18#include <QtNetwork/qnetworkreply.h>
19#include <QtNetwork/qnetworkrequest.h>
197 return m_elementName;
203 qmlWarning(
this) <<
tr(
"An XML element must not start with '/'");
206 qmlWarning(
this) <<
tr(
"An XML element must not end with '/'");
209 qmlWarning(
this) <<
tr(
"An XML element must not contain \"//\"");
213 if (
name == m_elementName)
215 m_elementName =
name;
236 return m_attributeName;
344 for (
auto &
w : m_watchers.values())
347 while (!m_watchers.isEmpty()) {
348 auto it = m_watchers.begin();
349 it.value()->waitForFinished();
353 m_watchers.erase(
it);
365 return !
parent.isValid() ? m_size : 0;
370 const int roleIndex = m_roles.
indexOf(role);
378 for (
int i = 0;
i < m_roles.
size(); ++
i)
403 if (m_source !=
src) {
425 "XmlListModelRoleList",
"An XmlListModel query must start with '/'");
429 if (m_query !=
query) {
452 int i = m_roleObjects.
size();
453 m_roleObjects.
append(role);
454 if (m_roleNames.contains(role->
name())) {
456 << QQmlXmlListModel::tr(
457 "\"%1\" duplicates a previous role name and will be disabled.")
461 m_roles.
insert(
i, m_highestRole);
462 m_roleNames.insert(
i, role->
name());
471 m_roleObjects.
clear();
477 auto object = qobject_cast<QQmlXmlListModel *>(
list->object);
479 object->appendRole(role);
484 auto object = qobject_cast<QQmlXmlListModel *>(
list->object);
491 auto job = createJob(
data);
492 m_queryId = job.queryId;
496 auto *
watcher =
new ResultFutureWatcher();
501 auto *
watcher =
static_cast<ResultFutureWatcher *
>(
sender());
506 for (
const auto &errorInfo :
result.errors)
507 queryError(errorInfo.
first, errorInfo.second);
512 m_watchers.remove(
id);
516 m_watchers[m_queryId] =
watcher;
520 m_errorString =
tr(
"Failed to create an instance of QRunnable query object");
534 for (
int i = 0;
i < m_roleObjects.
size();
i++) {
550int QQmlXmlListModel::nextQueryId()
552 m_nextQueryIdGenerator++;
553 if (m_nextQueryIdGenerator <= 0)
554 m_nextQueryIdGenerator = 1;
555 return m_nextQueryIdGenerator;
604 return m_errorString;
609 m_isComponentComplete =
false;
614 m_isComponentComplete =
true;
625 if (!m_isComponentComplete)
628 if (m_queryId > 0 && m_watchers.contains(m_queryId))
629 m_watchers[m_queryId]->cancel();
636#if QT_CONFIG(qml_network)
644 const auto resolvedSource =
context ?
context->resolvedUrl(m_source) : m_source;
646 if (resolvedSource.isEmpty()) {
648 notifyQueryStarted(
false);
657 notifyQueryStarted(
false);
658 if (
data.isEmpty()) {
662 tryExecuteQuery(
data);
665#if QT_CONFIG(qml_network)
666 notifyQueryStarted(
true);
672 &QQmlXmlListModel::requestFinished);
674 &QQmlXmlListModel::requestProgress);
677 notifyQueryStarted(
false);
683#if QT_CONFIG(qml_network)
684void QQmlXmlListModel::requestFinished()
687 m_errorString = m_reply->errorString();
703 if (
data.isEmpty()) {
707 tryExecuteQuery(
data);
716void QQmlXmlListModel::deleteReply()
720 m_reply->deleteLater();
726void QQmlXmlListModel::requestProgress(
qint64 received,
qint64 total)
728 if (m_status ==
Loading && total > 0) {
729 m_progress =
qreal(received) / total;
734void QQmlXmlListModel::dataCleared()
741void QQmlXmlListModel::queryError(
void *
object,
const QString &
error)
743 for (
int i = 0;
i < m_roleObjects.
size();
i++) {
746 << QQmlXmlListModel::tr(
"Query error: \"%1\"").arg(
error);
750 qmlWarning(
this) << QQmlXmlListModel::tr(
"Query error: \"%1\"").arg(
error);
755 if (
result.queryId != m_queryId)
758 int origCount = m_size;
759 bool sizeChanged =
result.data.size() != m_size;
765 m_errorString.
clear();
772 m_size =
result.data.size();
786void QQmlXmlListModel::notifyQueryStarted(
bool remoteSource)
788 m_progress = remoteSource ? 0.0 : 1.0;
790 m_errorString.
clear();
798 for (
auto idx = startIndex; idx < elementNames.size(); ++idx) {
799 if (elementNames[idx].startsWith(
name))
806 : m_job(
std::move(job))
825 return m_promise.
future();
833 QXmlStreamReader reader;
834 reader.addData(
data);
838 while (!reader.atEnd() && !m_promise.
isCanceled()) {
841 if (reader.readNextStartElement()) {
847 processElement(currentResult,
items.
at(
i), reader);
850 reader.skipCurrentElement();
853 if (
reader.tokenType() == QXmlStreamReader::Invalid) {
856 }
else if (
reader.hasError()) {
865 const QString &element, QXmlStreamReader &reader)
867 if (!
reader.isStartElement() ||
reader.name() != element)
876 if (!
reader.attributes().isEmpty()) {
878 if (elementNames.at(
index).isEmpty() && !attributes.at(
index).isEmpty()) {
897void QQmlXmlListModelQueryRunnable::readSubTree(
const QString &prefix, QXmlStreamReader &reader,
903 while (
reader.readNextStartElement()) {
912 const auto elementAttributes =
reader.attributes();
917 bool elementTextRead =
false;
925 if (elementAttributes.hasAttribute(
attribute)) {
926 roleResult = elementAttributes.value(attributes.at(
index)).toString();
932 }
else if (!elementNames.at(
index).isEmpty()) {
933 if (!elementTextRead) {
935 reader.readElementText(QXmlStreamReader::IncludeChildElements);
936 elementTextRead =
true;
938 roleResult = elementText;
945 if (!elementTextRead)
948 reader.skipCurrentElement();
955#include "moc_qqmlxmllistmodel_p.cpp"
void endRemoveRows()
Ends a row removal operation.
void endInsertRows()
Ends a row insertion operation.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void beginRemoveRows(const QModelIndex &parent, int first, int last)
Begins a row removal operation.
void beginInsertRows(const QModelIndex &parent, int first, int last)
Begins a row insertion operation.
QObject * parent() const
Returns a pointer to the parent object.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
T value(const Key &key, const T &defaultValue) const
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
QString errorString() const
Returns a human readable description of the last error that occurred.
qsizetype size() const noexcept
iterator insert(qsizetype i, parameter_type t)
void push_back(parameter_type t)
const_reference at(qsizetype i) const noexcept
T value(qsizetype i) const
void append(parameter_type t)
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
This signal is emitted to indicate the progress of the download part of this network request,...
void finished()
This signal is emitted when the reply has finished processing.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
void setRawHeader(const QByteArray &headerName, const QByteArray &value)
Sets the header headerName to be of value headerValue.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
QFuture< T > future() const
bool addResult(U &&result, int index=-1)
The QQmlContext class defines a context within a QML engine.
QQmlEngine * engine() const
Return the context's QQmlEngine, or \nullptr if the context has no QQmlEngine or the QQmlEngine was d...
static bool isLocalFile(const QString &url)
Returns true if url is a local file that can be opened with QFile.
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
QQmlXmlListModelQueryRunnable(QQmlXmlListModelQueryJob &&job)
QFuture< QQmlXmlListModelQueryResult > future() const
void run() override
Implement this pure virtual function in your subclass.
void setElementName(const QString &name)
void attributeNameChanged()
void setAttributeName(const QString &attributeName)
void elementNameChanged()
void setName(const QString &name)
void classBegin() override
Invoked after class creation, but before any properties have been set.
void reload()
\qmlmethod QtQml.XmlListModel::XmlListModel::reload()
void progressChanged(qreal progress)
QQmlListProperty< QQmlXmlListModelRole > roleObjects()
\qmlproperty list<XmlListModelRole> QtQml.XmlListModel::XmlListModel::roles
Q_INVOKABLE QString errorString() const
\qmlmethod QtQml.XmlListModel::XmlListModel::errorString()
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void appendRole(QQmlXmlListModelRole *)
void setSource(const QUrl &)
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Returns the index of the data in row and column with parent.
void statusChanged(QQmlXmlListModel::Status)
QQmlXmlListModel(QObject *parent=nullptr)
\qmltype XmlListModel \inqmlmodule QtQml.XmlListModel
int rowCount(const QModelIndex &parent) const override
Returns the number of rows under the given parent.
void setQuery(const QString &)
QVariant data(const QModelIndex &index, int role) const override
Returns the data stored under the given role for the item referred to by the index.
QHash< int, QByteArray > roleNames() const override
void setAutoDelete(bool autoDelete)
Enables auto-deletion if autoDelete is true; otherwise auto-deletion is disabled.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
void clear()
Clears the contents of the string and makes it null.
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
void start(QRunnable *runnable, int priority=0)
Reserves a thread and uses it to run runnable, unless this thread will make the current thread count ...
static QThreadPool * globalInstance()
Returns the global QThreadPool instance.
bool singleShot
whether the timer is a single-shot timer
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QImageReader reader("image.png")
[1]
std::pair< T1, T2 > QPair
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint attribute
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void GLsizei void * column
GLenum GLenum GLsizei void * row
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
QQmlContext * qmlContext(const QObject *obj)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static qsizetype findIndexOfName(const QStringList &elementNames, const QStringView &name, qsizetype startIndex=0)
#define qPrintable(string)
#define QStringLiteral(str)
QFuture< void > future
[5]
QFutureWatcher< int > watcher
\inmodule QtCore \reentrant
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
QStringList elementAttributes
QList< void * > roleQueryErrorId
QList< QPair< void *, QString > > errors
QList< QFlatMap< int, QString > > data
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent