Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: examples/network/bearermonitor/CMakeLists.txt examples/network/CMakeLists.txt src/corelib/tools/qlinkedlist.h src/sql/kernel/qsqldriver_p.h src/sql/kernel/qsqlresult_p.h src/widgets/kernel/qwidget.cpp src/widgets/kernel/qwidget_p.h tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp tests/auto/tools/moc/allmocs_baseline_in.json Change-Id: I21a3c34570ae79ea9d30107fae71759d7eac17d9
This commit is contained in:
commit
75c0ffaf6d
@ -164,8 +164,6 @@ Build options:
|
||||
-reduce-exports ...... Reduce amount of exported symbols [auto]
|
||||
-reduce-relocations .. Reduce amount of relocations [auto] (Unix only)
|
||||
|
||||
-relocatable ......... Enable the Qt installation to be relocated [auto]
|
||||
|
||||
-plugin-manifests .... Embed manifests into plugins [no] (Windows only)
|
||||
-static-runtime ...... With -static, use static runtime [no] (Windows only)
|
||||
|
||||
|
@ -1407,6 +1407,7 @@
|
||||
},
|
||||
"relocatable": {
|
||||
"label": "Relocatable",
|
||||
"purpose": "Enable the Qt installation to be relocated.",
|
||||
"autoDetect": "features.shared",
|
||||
"condition": "features.dlopen || config.win32 || !features.shared",
|
||||
"output": [ "privateFeature" ]
|
||||
|
3
dist/changes-5.14.0
vendored
3
dist/changes-5.14.0
vendored
@ -476,6 +476,9 @@ information about a particular change.
|
||||
|
||||
- MinGW:
|
||||
* [QTBUG-4155] Added a suffix to debug mode pkgconfig files.
|
||||
* MinGW does not built with -debug-and-release mode anymore.
|
||||
Instead, the binaries are built with -release -force-debug-info
|
||||
-separate-debug-info.
|
||||
|
||||
- macOS:
|
||||
* The drawableSize of Metal layers is no longer updated automatically on
|
||||
|
@ -81,52 +81,9 @@ MapZoom::MapZoom()
|
||||
menu->addAction(nightModeAction);
|
||||
menu->addAction(osmAction);
|
||||
|
||||
QNetworkConfigurationManager manager;
|
||||
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
|
||||
// Get saved network configuration
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
const QString id =
|
||||
settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
|
||||
settings.endGroup();
|
||||
|
||||
// If the saved network configuration is not currently discovered use the system
|
||||
// default
|
||||
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
|
||||
if ((config.state() & QNetworkConfiguration::Discovered) !=
|
||||
QNetworkConfiguration::Discovered) {
|
||||
config = manager.defaultConfiguration();
|
||||
}
|
||||
|
||||
networkSession = new QNetworkSession(config, this);
|
||||
connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
|
||||
|
||||
networkSession->open();
|
||||
} else {
|
||||
networkSession = 0;
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Light Maps"));
|
||||
}
|
||||
|
||||
void MapZoom::sessionOpened()
|
||||
{
|
||||
// Save the used configuration
|
||||
QNetworkConfiguration config = networkSession->configuration();
|
||||
QString id;
|
||||
if (config.type() == QNetworkConfiguration::UserChoice) {
|
||||
id = networkSession->sessionProperty(
|
||||
QLatin1String("UserChoiceConfiguration")).toString();
|
||||
} else {
|
||||
id = config.identifier();
|
||||
}
|
||||
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MapZoom::chooseOslo()
|
||||
{
|
||||
map->setCenter(59.9138204, 10.7387413);
|
||||
|
@ -53,7 +53,6 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
class QNetworkSession;
|
||||
class LightMaps;
|
||||
|
||||
class MapZoom : public QMainWindow
|
||||
@ -64,7 +63,6 @@ public:
|
||||
MapZoom();
|
||||
|
||||
private slots:
|
||||
void sessionOpened();
|
||||
void chooseOslo();
|
||||
void chooseBerlin();
|
||||
void chooseJakarta();
|
||||
@ -72,7 +70,6 @@ private slots:
|
||||
|
||||
private:
|
||||
LightMaps *map;
|
||||
QNetworkSession *networkSession;
|
||||
};
|
||||
|
||||
#endif
|
@ -20,7 +20,6 @@ if(TARGET Qt::Widgets)
|
||||
add_subdirectory(multicastsender)
|
||||
|
||||
if(QT_FEATURE_bearermanagement)
|
||||
add_subdirectory(bearermonitor)
|
||||
add_subdirectory(fortuneclient)
|
||||
add_subdirectory(fortuneserver)
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
# Generated from bearermonitor.pro.
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(bearermonitor LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "examples/network/bearermonitor")
|
||||
|
||||
find_package(Qt6 COMPONENTS Core)
|
||||
find_package(Qt6 COMPONENTS Gui)
|
||||
find_package(Qt6 COMPONENTS Network)
|
||||
find_package(Qt6 COMPONENTS Widgets)
|
||||
|
||||
add_executable(bearermonitor
|
||||
bearermonitor.cpp bearermonitor.h
|
||||
bearermonitor_240_320.ui
|
||||
bearermonitor_640_480.ui
|
||||
main.cpp
|
||||
sessionwidget.cpp sessionwidget.h sessionwidget.ui
|
||||
)
|
||||
target_link_libraries(bearermonitor PUBLIC
|
||||
Qt::Core
|
||||
Qt::Gui
|
||||
Qt::Network
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(bearermonitor PUBLIC
|
||||
ws2_32
|
||||
)
|
||||
endif()
|
||||
|
||||
install(TARGETS bearermonitor
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -1,421 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "bearermonitor.h"
|
||||
#include "sessionwidget.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <winsock2.h>
|
||||
#undef interface
|
||||
|
||||
#ifndef NS_NLA
|
||||
#define NS_NLA 15
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BearerMonitor::BearerMonitor(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
delete tabWidget->currentWidget();
|
||||
sessionGroup->hide();
|
||||
updateConfigurations();
|
||||
onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty());
|
||||
QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
|
||||
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *item = treeWidget->topLevelItem(i);
|
||||
|
||||
if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) {
|
||||
treeWidget->setCurrentItem(item);
|
||||
showConfigurationFor(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
connect(&manager, &QNetworkConfigurationManager::onlineStateChanged,
|
||||
this, &BearerMonitor::onlineStateChanged);
|
||||
connect(&manager, &QNetworkConfigurationManager::configurationAdded,
|
||||
this, [this](const QNetworkConfiguration &config) { configurationAdded(config); });
|
||||
connect(&manager, &QNetworkConfigurationManager::configurationRemoved,
|
||||
this, &BearerMonitor::configurationRemoved);
|
||||
connect(&manager, &QNetworkConfigurationManager::configurationChanged,
|
||||
this, &BearerMonitor::configurationChanged);
|
||||
connect(&manager, &QNetworkConfigurationManager::updateCompleted,
|
||||
this, &BearerMonitor::updateConfigurations);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
connect(registerButton, &QPushButton::clicked,
|
||||
this, &BearerMonitor::registerNetwork);
|
||||
connect(unregisterButton, &QPushButton::clicked,
|
||||
this, &BearerMonitor::unregisterNetwork);
|
||||
#else // Q_OS_WIN && !Q_OS_WINRT
|
||||
nlaGroup->hide();
|
||||
#endif
|
||||
|
||||
connect(treeWidget, &QTreeWidget::itemActivated,
|
||||
this, &BearerMonitor::createSessionFor);
|
||||
connect(treeWidget, &QTreeWidget::currentItemChanged,
|
||||
this, &BearerMonitor::showConfigurationFor);
|
||||
|
||||
connect(newSessionButton, &QPushButton::clicked,
|
||||
this, &BearerMonitor::createNewSession);
|
||||
connect(deleteSessionButton, &QPushButton::clicked,
|
||||
this, &BearerMonitor::deleteSession);
|
||||
connect(scanButton, &QPushButton::clicked,
|
||||
this, &BearerMonitor::performScan);
|
||||
|
||||
// Just in case update all configurations so that all
|
||||
// configurations are up to date.
|
||||
manager.updateConfigurations();
|
||||
}
|
||||
|
||||
BearerMonitor::~BearerMonitor()
|
||||
{
|
||||
}
|
||||
|
||||
static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config)
|
||||
{
|
||||
item->setText(0, config.name());
|
||||
item->setData(0, Qt::UserRole, config.identifier());
|
||||
|
||||
QFont font = item->font(1);
|
||||
font.setBold(config.state().testFlag(QNetworkConfiguration::Active));
|
||||
item->setFont(0, font);
|
||||
}
|
||||
|
||||
void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
|
||||
{
|
||||
if (!config.isValid())
|
||||
return;
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem;
|
||||
updateItem(item, config);
|
||||
|
||||
if (parent)
|
||||
parent->addChild(item);
|
||||
else
|
||||
treeWidget->addTopLevelItem(item);
|
||||
|
||||
if (config.type() == QNetworkConfiguration::ServiceNetwork) {
|
||||
const QList<QNetworkConfiguration> children = config.children();
|
||||
for (const QNetworkConfiguration &child : children)
|
||||
configurationAdded(child, item);
|
||||
}
|
||||
}
|
||||
|
||||
void BearerMonitor::configurationRemoved(const QNetworkConfiguration &config)
|
||||
{
|
||||
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *item = treeWidget->topLevelItem(i);
|
||||
|
||||
if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
|
||||
delete item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BearerMonitor::configurationChanged(const QNetworkConfiguration &config)
|
||||
{
|
||||
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *item = treeWidget->topLevelItem(i);
|
||||
|
||||
if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
|
||||
updateItem(item, config);
|
||||
|
||||
if (config.type() == QNetworkConfiguration::ServiceNetwork)
|
||||
updateSnapConfiguration(item, config);
|
||||
|
||||
if (item == treeWidget->currentItem())
|
||||
showConfigurationFor(item);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap)
|
||||
{
|
||||
QMap<QString, QTreeWidgetItem *> itemMap;
|
||||
const QList<QTreeWidgetItem *> children = parent->takeChildren();
|
||||
for (QTreeWidgetItem *item : children)
|
||||
itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
|
||||
|
||||
QList<QNetworkConfiguration> allConfigurations = snap.children();
|
||||
|
||||
while (!allConfigurations.isEmpty()) {
|
||||
QNetworkConfiguration config = allConfigurations.takeFirst();
|
||||
|
||||
QTreeWidgetItem *item = itemMap.take(config.identifier());
|
||||
if (item) {
|
||||
updateItem(item, config);
|
||||
|
||||
parent->addChild(item);
|
||||
|
||||
if (config.type() == QNetworkConfiguration::ServiceNetwork)
|
||||
updateSnapConfiguration(item, config);
|
||||
} else {
|
||||
configurationAdded(config, parent);
|
||||
}
|
||||
}
|
||||
|
||||
qDeleteAll(itemMap);
|
||||
}
|
||||
|
||||
void BearerMonitor::updateConfigurations()
|
||||
{
|
||||
progressBar->hide();
|
||||
scanButton->show();
|
||||
|
||||
// Just in case update online state, on Symbian platform
|
||||
// WLAN scan needs to be triggered initially to have their true state.
|
||||
onlineStateChanged(manager.isOnline());
|
||||
|
||||
QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard);
|
||||
QMap<QString, QTreeWidgetItem *> itemMap;
|
||||
while (!items.isEmpty()) {
|
||||
QTreeWidgetItem *item = items.takeFirst();
|
||||
itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
|
||||
}
|
||||
|
||||
QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
|
||||
QTreeWidgetItem *defaultItem = itemMap.take(defaultConfiguration.identifier());
|
||||
|
||||
if (defaultItem) {
|
||||
updateItem(defaultItem, defaultConfiguration);
|
||||
|
||||
if (defaultConfiguration.type() == QNetworkConfiguration::ServiceNetwork)
|
||||
updateSnapConfiguration(defaultItem, defaultConfiguration);
|
||||
} else {
|
||||
configurationAdded(defaultConfiguration);
|
||||
}
|
||||
|
||||
QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();
|
||||
|
||||
while (!allConfigurations.isEmpty()) {
|
||||
QNetworkConfiguration config = allConfigurations.takeFirst();
|
||||
|
||||
if (config.identifier() == defaultConfiguration.identifier())
|
||||
continue;
|
||||
|
||||
QTreeWidgetItem *item = itemMap.take(config.identifier());
|
||||
if (item) {
|
||||
updateItem(item, config);
|
||||
|
||||
if (config.type() == QNetworkConfiguration::ServiceNetwork)
|
||||
updateSnapConfiguration(item, config);
|
||||
} else {
|
||||
configurationAdded(config);
|
||||
}
|
||||
}
|
||||
|
||||
qDeleteAll(itemMap);
|
||||
}
|
||||
|
||||
void BearerMonitor::onlineStateChanged(bool isOnline)
|
||||
{
|
||||
if (isOnline)
|
||||
onlineState->setText(tr("Online"));
|
||||
else
|
||||
onlineState->setText(tr("Offline"));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
void BearerMonitor::registerNetwork()
|
||||
{
|
||||
QTreeWidgetItem *item = treeWidget->currentItem();
|
||||
if (!item) return;
|
||||
|
||||
QNetworkConfiguration configuration =
|
||||
manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
|
||||
|
||||
const QString name = configuration.name();
|
||||
|
||||
qDebug() << "Registering" << name << "with system";
|
||||
|
||||
WSAQUERYSET networkInfo;
|
||||
memset(&networkInfo, 0, sizeof(networkInfo));
|
||||
networkInfo.dwSize = sizeof(networkInfo);
|
||||
networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
|
||||
networkInfo.dwNameSpace = NS_NLA;
|
||||
|
||||
if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
|
||||
qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError();
|
||||
}
|
||||
|
||||
void BearerMonitor::unregisterNetwork()
|
||||
{
|
||||
QTreeWidgetItem *item = treeWidget->currentItem();
|
||||
if (!item) return;
|
||||
|
||||
QNetworkConfiguration configuration =
|
||||
manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
|
||||
|
||||
const QString name = configuration.name();
|
||||
|
||||
qDebug() << "Unregistering" << name << "with system";
|
||||
|
||||
WSAQUERYSET networkInfo;
|
||||
memset(&networkInfo, 0, sizeof(networkInfo));
|
||||
networkInfo.dwSize = sizeof(networkInfo);
|
||||
networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
|
||||
networkInfo.dwNameSpace = NS_NLA;
|
||||
|
||||
if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
|
||||
qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
|
||||
}
|
||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
|
||||
void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item)
|
||||
{
|
||||
QString identifier;
|
||||
|
||||
if (item)
|
||||
identifier = item->data(0, Qt::UserRole).toString();
|
||||
|
||||
QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
|
||||
|
||||
switch (conf.state()) {
|
||||
case QNetworkConfiguration::Active:
|
||||
configurationState->setText(tr("Active"));
|
||||
break;
|
||||
case QNetworkConfiguration::Discovered:
|
||||
configurationState->setText(tr("Discovered"));
|
||||
break;
|
||||
case QNetworkConfiguration::Defined:
|
||||
configurationState->setText(tr("Defined"));
|
||||
break;
|
||||
case QNetworkConfiguration::Undefined:
|
||||
configurationState->setText(tr("Undefined"));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (conf.type()) {
|
||||
case QNetworkConfiguration::InternetAccessPoint:
|
||||
configurationType->setText(tr("Internet Access Point"));
|
||||
break;
|
||||
case QNetworkConfiguration::ServiceNetwork:
|
||||
configurationType->setText(tr("Service Network"));
|
||||
break;
|
||||
case QNetworkConfiguration::UserChoice:
|
||||
configurationType->setText(tr("User Choice"));
|
||||
break;
|
||||
case QNetworkConfiguration::Invalid:
|
||||
configurationType->setText(tr("Invalid"));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (conf.purpose()) {
|
||||
case QNetworkConfiguration::UnknownPurpose:
|
||||
configurationPurpose->setText(tr("Unknown"));
|
||||
break;
|
||||
case QNetworkConfiguration::PublicPurpose:
|
||||
configurationPurpose->setText(tr("Public"));
|
||||
break;
|
||||
case QNetworkConfiguration::PrivatePurpose:
|
||||
configurationPurpose->setText(tr("Private"));
|
||||
break;
|
||||
case QNetworkConfiguration::ServiceSpecificPurpose:
|
||||
configurationPurpose->setText(tr("Service Specific"));
|
||||
break;
|
||||
}
|
||||
|
||||
configurationIdentifier->setText(conf.identifier());
|
||||
|
||||
configurationRoaming->setText(conf.isRoamingAvailable() ? tr("Available") : tr("Not available"));
|
||||
|
||||
configurationChildren->setText(QString::number(conf.children().count()));
|
||||
|
||||
configurationName->setText(conf.name());
|
||||
}
|
||||
|
||||
void BearerMonitor::createSessionFor(QTreeWidgetItem *item)
|
||||
{
|
||||
const QString identifier = item->data(0, Qt::UserRole).toString();
|
||||
|
||||
QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
|
||||
|
||||
SessionWidget *session = new SessionWidget(conf);
|
||||
|
||||
tabWidget->addTab(session, conf.name());
|
||||
|
||||
sessionGroup->show();
|
||||
|
||||
sessionWidgets.append(session);
|
||||
}
|
||||
|
||||
void BearerMonitor::createNewSession()
|
||||
{
|
||||
QTreeWidgetItem *item = treeWidget->currentItem();
|
||||
if (!item) return;
|
||||
|
||||
createSessionFor(item);
|
||||
}
|
||||
|
||||
void BearerMonitor::deleteSession()
|
||||
{
|
||||
SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget());
|
||||
if (session) {
|
||||
sessionWidgets.removeAll(session);
|
||||
|
||||
delete session;
|
||||
|
||||
if (tabWidget->count() == 0)
|
||||
sessionGroup->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void BearerMonitor::performScan()
|
||||
{
|
||||
scanButton->hide();
|
||||
progressBar->show();
|
||||
manager.updateConfigurations();
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BEARERMONITOR_H
|
||||
#define BEARERMONITOR_H
|
||||
|
||||
#include <QNetworkConfigurationManager>
|
||||
#include "ui_bearermonitor_640_480.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class SessionWidget;
|
||||
|
||||
class BearerMonitor : public QWidget, public Ui_BearerMonitor
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BearerMonitor(QWidget *parent = nullptr);
|
||||
~BearerMonitor();
|
||||
|
||||
private slots:
|
||||
void configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent = nullptr);
|
||||
void configurationRemoved(const QNetworkConfiguration &config);
|
||||
void configurationChanged(const QNetworkConfiguration &config);
|
||||
void updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap);
|
||||
void updateConfigurations();
|
||||
|
||||
void onlineStateChanged(bool isOnline);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
void registerNetwork();
|
||||
void unregisterNetwork();
|
||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
|
||||
void showConfigurationFor(QTreeWidgetItem *item);
|
||||
|
||||
void createSessionFor(QTreeWidgetItem *item);
|
||||
void createNewSession();
|
||||
void deleteSession();
|
||||
void performScan();
|
||||
|
||||
private:
|
||||
QNetworkConfigurationManager manager;
|
||||
QVector<SessionWidget *> sessionWidgets;
|
||||
};
|
||||
|
||||
#endif //BEARERMONITOR_H
|
@ -1,22 +0,0 @@
|
||||
TARGET = bearermonitor
|
||||
QT = core gui network widgets
|
||||
requires(qtConfig(treeview))
|
||||
|
||||
HEADERS = sessionwidget.h \
|
||||
bearermonitor.h
|
||||
|
||||
SOURCES = main.cpp \
|
||||
bearermonitor.cpp \
|
||||
sessionwidget.cpp
|
||||
|
||||
FORMS = bearermonitor_240_320.ui \
|
||||
bearermonitor_640_480.ui \
|
||||
sessionwidget.ui
|
||||
|
||||
win32: QMAKE_USE += ws2_32
|
||||
|
||||
CONFIG += console
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/network/bearermonitor
|
||||
INSTALLS += target
|
@ -1,420 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BearerMonitor</class>
|
||||
<widget class="QWidget" name="BearerMonitor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>240</width>
|
||||
<height>320</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>BearerMonitor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-274</y>
|
||||
<width>206</width>
|
||||
<height>576</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="systemState">
|
||||
<property name="title">
|
||||
<string>System State</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="onlineStateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="onlineStateLabel">
|
||||
<property name="text">
|
||||
<string>Online State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="onlineState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Configurations</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationNameLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationNameLabel">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationStateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationStateLabel">
|
||||
<property name="text">
|
||||
<string>State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationTypeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationTypeLabel">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invalid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationPurposeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationPurposeLabel">
|
||||
<property name="text">
|
||||
<string>Purpose:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationPurpose">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unknown</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationIdentifierLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationIdentifierLabel">
|
||||
<property name="text">
|
||||
<string>Identifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationIdentifier">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationRoamingLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationRoamingLabel">
|
||||
<property name="text">
|
||||
<string>Roaming:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationRoaming">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationChildrenLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationChildrenLabel">
|
||||
<property name="text">
|
||||
<string>Children:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationChildren">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="nlaGroup">
|
||||
<property name="title">
|
||||
<string>Network Location Awareness</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="registerButton">
|
||||
<property name="text">
|
||||
<string>Register</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="unregisterButton">
|
||||
<property name="text">
|
||||
<string>Unregister</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="newSessionButton">
|
||||
<property name="text">
|
||||
<string>New Session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteSessionButton">
|
||||
<property name="text">
|
||||
<string>Delete Session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="scanButton">
|
||||
<property name="text">
|
||||
<string>Scan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string>%p%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="sessionGroup">
|
||||
<property name="title">
|
||||
<string>Sessions</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Session 1</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,386 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BearerMonitor</class>
|
||||
<widget class="QWidget" name="BearerMonitor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>515</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>BearerMonitor</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="systemState">
|
||||
<property name="title">
|
||||
<string>System State</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="onlineStateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="onlineStateLabel">
|
||||
<property name="text">
|
||||
<string>Online State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="onlineState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Configurations</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationNameLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationNameLabel">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationStateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationStateLabel">
|
||||
<property name="text">
|
||||
<string>State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationTypeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationTypeLabel">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invalid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationPurposeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationPurposeLabel">
|
||||
<property name="text">
|
||||
<string>Purpose:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationPurpose">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unknown</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationIdentifierLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationIdentifierLabel">
|
||||
<property name="text">
|
||||
<string>Identifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationIdentifier">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationRoamingLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationRoamingLabel">
|
||||
<property name="text">
|
||||
<string>Roaming:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationRoaming">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationChildrenLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationChildrenLabel">
|
||||
<property name="text">
|
||||
<string>Children:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationChildren">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="nlaGroup">
|
||||
<property name="title">
|
||||
<string>Network Location Awareness</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="registerButton">
|
||||
<property name="text">
|
||||
<string>Register</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="unregisterButton">
|
||||
<property name="text">
|
||||
<string>Unregister</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="newSessionButton">
|
||||
<property name="text">
|
||||
<string>New Session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteSessionButton">
|
||||
<property name="text">
|
||||
<string>Delete Session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="scanButton">
|
||||
<property name="text">
|
||||
<string>Scan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string>%p%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="sessionGroup">
|
||||
<property name="title">
|
||||
<string>Sessions</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Session 1</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,69 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "bearermonitor.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QMainWindow mainWindow;
|
||||
|
||||
BearerMonitor monitor;
|
||||
|
||||
mainWindow.setCentralWidget(&monitor);
|
||||
mainWindow.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -1,203 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sessionwidget.h"
|
||||
#include <QNetworkConfigurationManager>
|
||||
|
||||
SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
#ifdef QT_NO_NETWORKINTERFACE
|
||||
interfaceName->setVisible(false);
|
||||
interfaceNameLabel->setVisible(false);
|
||||
interfaceGuid->setVisible(false);
|
||||
interfaceGuidLabel->setVisible(false);
|
||||
#endif
|
||||
|
||||
session = new QNetworkSession(config, this);
|
||||
|
||||
connect(session, &QNetworkSession::stateChanged,
|
||||
this, &SessionWidget::updateSession);
|
||||
connect(session, QOverload<QNetworkSession::SessionError>::of(&QNetworkSession::error),
|
||||
this, &SessionWidget::updateSessionError);
|
||||
|
||||
updateSession();
|
||||
|
||||
sessionId->setText(QString("0x%1").arg(qulonglong(session), 8, 16, QChar('0')));
|
||||
|
||||
configuration->setText(session->configuration().name());
|
||||
|
||||
connect(openSessionButton, &QPushButton::clicked,
|
||||
this, &SessionWidget::openSession);
|
||||
connect(openSyncSessionButton, &QPushButton::clicked,
|
||||
this, &SessionWidget::openSyncSession);
|
||||
connect(closeSessionButton, &QPushButton::clicked,
|
||||
this, &SessionWidget::closeSession);
|
||||
connect(stopSessionButton, &QPushButton::clicked,
|
||||
this, &SessionWidget::stopSession);
|
||||
}
|
||||
|
||||
SessionWidget::~SessionWidget()
|
||||
{
|
||||
delete session;
|
||||
}
|
||||
|
||||
void SessionWidget::timerEvent(QTimerEvent *e)
|
||||
{
|
||||
if (e->timerId() == statsTimer) {
|
||||
rxData->setText(QString::number(session->bytesReceived()));
|
||||
txData->setText(QString::number(session->bytesWritten()));
|
||||
activeTime->setText(QString::number(session->activeTime()));
|
||||
}
|
||||
}
|
||||
|
||||
void SessionWidget::updateSession()
|
||||
{
|
||||
updateSessionState(session->state());
|
||||
|
||||
if (session->state() == QNetworkSession::Connected)
|
||||
statsTimer = startTimer(1000);
|
||||
else if (statsTimer != -1)
|
||||
killTimer(statsTimer);
|
||||
|
||||
if (session->configuration().type() == QNetworkConfiguration::InternetAccessPoint)
|
||||
bearer->setText(session->configuration().bearerTypeName());
|
||||
else {
|
||||
QNetworkConfigurationManager mgr;
|
||||
QNetworkConfiguration c = mgr.configurationFromIdentifier(session->sessionProperty("ActiveConfiguration").toString());
|
||||
bearer->setText(c.bearerTypeName());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
interfaceName->setText(session->interface().humanReadableName());
|
||||
interfaceGuid->setText(session->interface().name());
|
||||
#endif
|
||||
}
|
||||
|
||||
void SessionWidget::openSession()
|
||||
{
|
||||
clearError();
|
||||
session->open();
|
||||
updateSession();
|
||||
}
|
||||
|
||||
void SessionWidget::openSyncSession()
|
||||
{
|
||||
clearError();
|
||||
session->open();
|
||||
session->waitForOpened();
|
||||
updateSession();
|
||||
}
|
||||
|
||||
void SessionWidget::closeSession()
|
||||
{
|
||||
clearError();
|
||||
session->close();
|
||||
updateSession();
|
||||
}
|
||||
|
||||
void SessionWidget::stopSession()
|
||||
{
|
||||
clearError();
|
||||
session->stop();
|
||||
updateSession();
|
||||
}
|
||||
|
||||
void SessionWidget::updateSessionState(QNetworkSession::State state)
|
||||
{
|
||||
QString s = tr("%1 (%2)");
|
||||
|
||||
switch (state) {
|
||||
case QNetworkSession::Invalid:
|
||||
s = s.arg(tr("Invalid"));
|
||||
break;
|
||||
case QNetworkSession::NotAvailable:
|
||||
s = s.arg(tr("Not Available"));
|
||||
break;
|
||||
case QNetworkSession::Connecting:
|
||||
s = s.arg(tr("Connecting"));
|
||||
break;
|
||||
case QNetworkSession::Connected:
|
||||
s = s.arg(tr("Connected"));
|
||||
break;
|
||||
case QNetworkSession::Closing:
|
||||
s = s.arg(tr("Closing"));
|
||||
break;
|
||||
case QNetworkSession::Disconnected:
|
||||
s = s.arg(tr("Disconnected"));
|
||||
break;
|
||||
case QNetworkSession::Roaming:
|
||||
s = s.arg(tr("Roaming"));
|
||||
break;
|
||||
default:
|
||||
s = s.arg(tr("Unknown"));
|
||||
}
|
||||
|
||||
if (session->isOpen())
|
||||
s = s.arg(tr("Open"));
|
||||
else
|
||||
s = s.arg(tr("Closed"));
|
||||
|
||||
sessionState->setText(s);
|
||||
}
|
||||
|
||||
void SessionWidget::updateSessionError(QNetworkSession::SessionError error)
|
||||
{
|
||||
lastError->setText(QString::number(error));
|
||||
errorString->setText(session->errorString());
|
||||
}
|
||||
|
||||
void SessionWidget::clearError()
|
||||
{
|
||||
lastError->clear();
|
||||
errorString->clear();
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef SESSIONWIDGET_H
|
||||
#define SESSIONWIDGET_H
|
||||
|
||||
#include <QNetworkSession>
|
||||
|
||||
#include "ui_sessionwidget.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class SessionWidget : public QWidget, public Ui_SessionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SessionWidget(const QNetworkConfiguration &config, QWidget *parent = nullptr);
|
||||
~SessionWidget();
|
||||
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
||||
private:
|
||||
void updateSessionState(QNetworkSession::State state);
|
||||
void clearError();
|
||||
|
||||
private Q_SLOTS:
|
||||
void openSession();
|
||||
void openSyncSession();
|
||||
void closeSession();
|
||||
void stopSession();
|
||||
void updateSession();
|
||||
void updateSessionError(QNetworkSession::SessionError error);
|
||||
|
||||
private:
|
||||
QNetworkSession *session = nullptr;
|
||||
int statsTimer = -1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,307 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SessionWidget</class>
|
||||
<widget class="QWidget" name="SessionWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>340</width>
|
||||
<height>276</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Session Details</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="sessionIdLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="sessionIdLabel">
|
||||
<property name="text">
|
||||
<string>Session ID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sessionId">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="sessionStateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="sessionStateLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Session State:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sessionState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invalid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="configurationLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="configurationLabel">
|
||||
<property name="text">
|
||||
<string>Configuration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configuration">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="bearerLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="bearerLabel">
|
||||
<property name="text">
|
||||
<string>Bearer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="bearer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="interfaceNameLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="interfaceNameLabel">
|
||||
<property name="text">
|
||||
<string>Interface Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="interfaceName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="interfaceGuidLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="interfaceGuidLabel">
|
||||
<property name="text">
|
||||
<string>Interface GUID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="interfaceGuid">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="lastErrorLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lastErrorLabel">
|
||||
<property name="text">
|
||||
<string>Last Error:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lastError">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="errorStringLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="errorStringLabel">
|
||||
<property name="text">
|
||||
<string>Error String:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="errorString">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="rxData">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="txData">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Active Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="activeTime">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 seconds</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="openSessionButton">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="openSyncSessionButton">
|
||||
<property name="text">
|
||||
<string>Blocking Open</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeSessionButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="stopSessionButton">
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -150,29 +150,6 @@ Client::Client(QWidget *parent)
|
||||
|
||||
setWindowTitle(QGuiApplication::applicationDisplayName());
|
||||
portLineEdit->setFocus();
|
||||
|
||||
QNetworkConfigurationManager manager;
|
||||
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
|
||||
// Get saved network configuration
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
|
||||
settings.endGroup();
|
||||
|
||||
// If the saved network configuration is not currently discovered use the system default
|
||||
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
|
||||
if ((config.state() & QNetworkConfiguration::Discovered) !=
|
||||
QNetworkConfiguration::Discovered) {
|
||||
config = manager.defaultConfiguration();
|
||||
}
|
||||
|
||||
networkSession = new QNetworkSession(config, this);
|
||||
connect(networkSession, &QNetworkSession::opened, this, &Client::sessionOpened);
|
||||
|
||||
getFortuneButton->setEnabled(false);
|
||||
statusLabel->setText(tr("Opening network session."));
|
||||
networkSession->open();
|
||||
}
|
||||
//! [5]
|
||||
}
|
||||
//! [5]
|
||||
@ -241,30 +218,7 @@ void Client::displayError(QAbstractSocket::SocketError socketError)
|
||||
|
||||
void Client::enableGetFortuneButton()
|
||||
{
|
||||
getFortuneButton->setEnabled((!networkSession || networkSession->isOpen()) &&
|
||||
!hostCombo->currentText().isEmpty() &&
|
||||
getFortuneButton->setEnabled(!hostCombo->currentText().isEmpty() &&
|
||||
!portLineEdit->text().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
void Client::sessionOpened()
|
||||
{
|
||||
// Save the used configuration
|
||||
QNetworkConfiguration config = networkSession->configuration();
|
||||
QString id;
|
||||
if (config.type() == QNetworkConfiguration::UserChoice)
|
||||
id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
|
||||
else
|
||||
id = config.identifier();
|
||||
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
|
||||
settings.endGroup();
|
||||
|
||||
statusLabel->setText(tr("This examples requires that you run the "
|
||||
"Fortune Server example as well."));
|
||||
|
||||
enableGetFortuneButton();
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,6 @@ class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QTcpSocket;
|
||||
class QNetworkSession;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
@ -77,7 +76,6 @@ private slots:
|
||||
void readFortune();
|
||||
void displayError(QAbstractSocket::SocketError socketError);
|
||||
void enableGetFortuneButton();
|
||||
void sessionOpened();
|
||||
|
||||
private:
|
||||
QComboBox *hostCombo = nullptr;
|
||||
@ -88,8 +86,6 @@ private:
|
||||
QTcpSocket *tcpSocket = nullptr;
|
||||
QDataStream in;
|
||||
QString currentFortune;
|
||||
|
||||
QNetworkSession *networkSession = nullptr;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -61,29 +61,7 @@ Server::Server(QWidget *parent)
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
statusLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
|
||||
QNetworkConfigurationManager manager;
|
||||
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
|
||||
// Get saved network configuration
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
|
||||
settings.endGroup();
|
||||
|
||||
// If the saved network configuration is not currently discovered use the system default
|
||||
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
|
||||
if ((config.state() & QNetworkConfiguration::Discovered) !=
|
||||
QNetworkConfiguration::Discovered) {
|
||||
config = manager.defaultConfiguration();
|
||||
}
|
||||
|
||||
networkSession = new QNetworkSession(config, this);
|
||||
connect(networkSession, &QNetworkSession::opened, this, &Server::sessionOpened);
|
||||
|
||||
statusLabel->setText(tr("Opening network session."));
|
||||
networkSession->open();
|
||||
} else {
|
||||
sessionOpened();
|
||||
}
|
||||
initServer();
|
||||
|
||||
//! [2]
|
||||
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
|
||||
@ -128,23 +106,8 @@ Server::Server(QWidget *parent)
|
||||
setWindowTitle(QGuiApplication::applicationDisplayName());
|
||||
}
|
||||
|
||||
void Server::sessionOpened()
|
||||
void Server::initServer()
|
||||
{
|
||||
// Save the used configuration
|
||||
if (networkSession) {
|
||||
QNetworkConfiguration config = networkSession->configuration();
|
||||
QString id;
|
||||
if (config.type() == QNetworkConfiguration::UserChoice)
|
||||
id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
|
||||
else
|
||||
id = config.identifier();
|
||||
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
//! [0] //! [1]
|
||||
tcpServer = new QTcpServer(this);
|
||||
if (!tcpServer->listen()) {
|
||||
|
@ -58,7 +58,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLabel;
|
||||
class QTcpServer;
|
||||
class QNetworkSession;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
@ -70,14 +69,14 @@ public:
|
||||
explicit Server(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void sessionOpened();
|
||||
void sendFortune();
|
||||
|
||||
private:
|
||||
void initServer();
|
||||
|
||||
QLabel *statusLabel = nullptr;
|
||||
QTcpServer *tcpServer = nullptr;
|
||||
QVector<QString> fortunes;
|
||||
QNetworkSession *networkSession = nullptr;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -53,50 +53,11 @@
|
||||
#include "chatdialog.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtNetwork/QNetworkConfigurationManager>
|
||||
#include <QtNetwork/QNetworkSession>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QNetworkConfigurationManager manager;
|
||||
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
|
||||
// Get saved network configuration
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
|
||||
settings.endGroup();
|
||||
|
||||
// If the saved network configuration is not currently discovered use the system default
|
||||
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
|
||||
if ((config.state() & QNetworkConfiguration::Discovered) !=
|
||||
QNetworkConfiguration::Discovered) {
|
||||
config = manager.defaultConfiguration();
|
||||
}
|
||||
|
||||
QNetworkSession *networkSession = new QNetworkSession(config, &app);
|
||||
networkSession->open();
|
||||
networkSession->waitForOpened();
|
||||
|
||||
if (networkSession->isOpen()) {
|
||||
// Save the used configuration
|
||||
QNetworkConfiguration config = networkSession->configuration();
|
||||
QString id;
|
||||
if (config.type() == QNetworkConfiguration::UserChoice) {
|
||||
id = networkSession->sessionProperty(
|
||||
QLatin1String("UserChoiceConfiguration")).toString();
|
||||
} else {
|
||||
id = config.identifier();
|
||||
}
|
||||
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("QtNetwork"));
|
||||
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
ChatDialog dialog;
|
||||
dialog.show();
|
||||
return app.exec();
|
||||
|
@ -19,15 +19,11 @@ qtHaveModule(widgets) {
|
||||
multicastreceiver \
|
||||
multicastsender
|
||||
|
||||
qtConfig(bearermanagement) {
|
||||
qtConfig(processenvironment): SUBDIRS += network-chat
|
||||
qtConfig(processenvironment): SUBDIRS += network-chat
|
||||
|
||||
SUBDIRS += \
|
||||
bearermonitor \
|
||||
fortuneclient \
|
||||
fortuneserver
|
||||
|
||||
}
|
||||
SUBDIRS += \
|
||||
fortuneclient \
|
||||
fortuneserver
|
||||
|
||||
qtConfig(ssl): SUBDIRS += securesocketclient
|
||||
qtConfig(dtls): SUBDIRS += secureudpserver secureudpclient
|
||||
|
@ -246,11 +246,7 @@
|
||||
|
||||
\section1 Other Code Editor Features
|
||||
|
||||
It is possible to implement parenthesis matching with
|
||||
QSyntaxHighlighter. The "Matching Parentheses with
|
||||
QSyntaxHighlighter" article in Qt Quarterly 31
|
||||
(\l{http://doc.qt.io/archives/qq/}) implements this. We also have
|
||||
the \l{Code Editor Example}, which shows how to implement line
|
||||
The \l{Code Editor Example} shows how to implement line
|
||||
numbers and how to highlight the current line.
|
||||
|
||||
*/
|
||||
|
@ -106,7 +106,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
|
||||
break;
|
||||
case QEvent::TabletMove:
|
||||
#ifndef Q_OS_IOS
|
||||
if (event->device() == QTabletEvent::RotationStylus)
|
||||
if (event->deviceType() == QTabletEvent::RotationStylus)
|
||||
updateCursor(event);
|
||||
#endif
|
||||
if (m_deviceDown) {
|
||||
@ -161,7 +161,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
|
||||
static qreal maxPenRadius = pressureToWidth(1.0);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
switch (event->device()) {
|
||||
switch (event->deviceType()) {
|
||||
//! [6]
|
||||
case QTabletEvent::Airbrush:
|
||||
{
|
||||
@ -251,7 +251,7 @@ void TabletCanvas::updateBrush(const QTabletEvent *event)
|
||||
m_color.setAlphaF(event->pressure());
|
||||
break;
|
||||
case TangentialPressureValuator:
|
||||
if (event->device() == QTabletEvent::Airbrush)
|
||||
if (event->deviceType() == QTabletEvent::Airbrush)
|
||||
m_color.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0));
|
||||
else
|
||||
m_color.setAlpha(255);
|
||||
@ -312,7 +312,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
|
||||
if (event->pointerType() == QTabletEvent::Eraser) {
|
||||
cursor = QCursor(QPixmap(":/images/cursor-eraser.png"), 3, 28);
|
||||
} else {
|
||||
switch (event->device()) {
|
||||
switch (event->deviceType()) {
|
||||
case QTabletEvent::Stylus:
|
||||
cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0);
|
||||
break;
|
||||
|
@ -35,6 +35,7 @@ embed_translations {
|
||||
!isEmpty(QM_FILES_INSTALL_PATH) {
|
||||
qm_files.files = $$QM_FILES
|
||||
qm_files.path = $$QM_FILES_INSTALL_PATH
|
||||
qm_files.CONFIG = no_check_exist
|
||||
INSTALLS += qm_files
|
||||
}
|
||||
lrelease.CONFIG += target_predeps no_clean
|
||||
|
@ -1,2 +1,2 @@
|
||||
load(default_pre)
|
||||
load(emcc_ver)
|
||||
load(default_pre)
|
||||
|
@ -3,7 +3,9 @@ defineReplace(qtEmccRecommendedVersion) {
|
||||
}
|
||||
|
||||
defineReplace(qtSystemEmccVersion) {
|
||||
E_VERSION = $$system("emcc -v 2>&1 | perl -alne $$shell_quote($_ = $F[9]; s/://; print;) ")
|
||||
EMCC = $$system("emcc -v 2>&1", lines)
|
||||
EMCC_LINE = $$find(EMCC, "^.*\b(emcc)\b.*$")
|
||||
E_VERSION = $$section(EMCC_LINE, " ", 9,9)
|
||||
return ($${E_VERSION})
|
||||
}
|
||||
|
||||
|
@ -960,6 +960,10 @@
|
||||
default is used.
|
||||
\row \li thread \li Thread support is enabled. This is enabled when CONFIG
|
||||
includes \c qt, which is the default.
|
||||
\row \li utf8_source \li Specifies that the project's source files use the
|
||||
UTF-8 encoding. By default, the compiler default is used.
|
||||
\row \li hide_symbols \li Set the default visibility of symbols in the binary
|
||||
to hidden. By default, the compiler default is used.
|
||||
\row \li c99 \li C99 support is enabled. This option has no effect if
|
||||
the compiler does not support C99, or can't select the C standard.
|
||||
By default, the compiler default is used.
|
||||
|
@ -558,6 +558,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' '
|
||||
<< incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS");
|
||||
} else {
|
||||
ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
|
||||
cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS)"), objectParts.second);
|
||||
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
|
||||
<< " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
|
||||
<< ' ' << depVar("POST_TARGETDEPS");
|
||||
|
@ -736,6 +736,18 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
|
||||
if(targetdir.right(1) != Option::dir_sep)
|
||||
targetdir += Option::dir_sep;
|
||||
|
||||
const ProStringList &targets = project->values(ProKey(t + ".targets"));
|
||||
for (int i = 0; i < targets.size(); ++i) {
|
||||
QString src = targets.at(i).toQString(),
|
||||
dst = escapeFilePath(filePrefixRoot(root, targetdir + src.section('/', -1)));
|
||||
if (!ret.isEmpty())
|
||||
ret += "\n\t";
|
||||
ret += "$(QINSTALL) " + escapeFilePath(Option::fixPathToTargetOS(src, false)) + ' ' + dst;
|
||||
if (!uninst.isEmpty())
|
||||
uninst.append("\n\t");
|
||||
uninst.append("-$(DEL_FILE) " + dst);
|
||||
}
|
||||
|
||||
if(t == "target" && project->first("TEMPLATE") == "lib") {
|
||||
if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") &&
|
||||
!project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
|
||||
@ -744,6 +756,8 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
|
||||
if(slsh != -1)
|
||||
dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
|
||||
dst_prl = filePrefixRoot(root, targetdir + dst_prl);
|
||||
if (!ret.isEmpty())
|
||||
ret += "\n\t";
|
||||
ret += installMetaFile(ProKey("QMAKE_PRL_INSTALL_REPLACE"), project->first("QMAKE_INTERNAL_PRL_FILE").toQString(), dst_prl);
|
||||
if(!uninst.isEmpty())
|
||||
uninst.append("\n\t");
|
||||
|
596
src/3rdparty/md4c/md4c.c
vendored
596
src/3rdparty/md4c/md4c.c
vendored
File diff suppressed because it is too large
Load Diff
19
src/3rdparty/md4c/md4c.h
vendored
19
src/3rdparty/md4c/md4c.h
vendored
@ -2,7 +2,7 @@
|
||||
* MD4C: Markdown parser for C
|
||||
* (http://github.com/mity/md4c)
|
||||
*
|
||||
* Copyright (c) 2016-2019 Martin Mitas
|
||||
* Copyright (c) 2016-2020 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -135,7 +135,16 @@ typedef enum MD_SPANTYPE {
|
||||
* Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled.
|
||||
*/
|
||||
MD_SPAN_LATEXMATH,
|
||||
MD_SPAN_LATEXMATH_DISPLAY
|
||||
MD_SPAN_LATEXMATH_DISPLAY,
|
||||
|
||||
/* Wiki links
|
||||
* Note: Recognized only when MD_FLAG_WIKILINKS is enabled.
|
||||
*/
|
||||
MD_SPAN_WIKILINK,
|
||||
|
||||
/* <u>...</u>
|
||||
* Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */
|
||||
MD_SPAN_U
|
||||
} MD_SPANTYPE;
|
||||
|
||||
/* Text is the actual textual contents of span. */
|
||||
@ -268,6 +277,10 @@ typedef struct MD_SPAN_IMG_DETAIL {
|
||||
MD_ATTRIBUTE title;
|
||||
} MD_SPAN_IMG_DETAIL;
|
||||
|
||||
/* Detailed info for MD_SPAN_WIKILINK. */
|
||||
typedef struct MD_SPAN_WIKILINK {
|
||||
MD_ATTRIBUTE target;
|
||||
} MD_SPAN_WIKILINK_DETAIL;
|
||||
|
||||
/* Flags specifying extensions/deviations from CommonMark specification.
|
||||
*
|
||||
@ -286,6 +299,8 @@ typedef struct MD_SPAN_IMG_DETAIL {
|
||||
#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x0400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */
|
||||
#define MD_FLAG_TASKLISTS 0x0800 /* Enable task list extension. */
|
||||
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
|
||||
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
|
||||
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
|
||||
|
||||
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
|
||||
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)
|
||||
|
6
src/3rdparty/md4c/qt_attribution.json
vendored
6
src/3rdparty/md4c/qt_attribution.json
vendored
@ -9,7 +9,7 @@
|
||||
"License": "MIT License",
|
||||
"LicenseId": "MIT",
|
||||
"LicenseFile": "LICENSE.md",
|
||||
"Version": "0.3.4",
|
||||
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.3.4",
|
||||
"Copyright": "Copyright © 2016-2019 Martin Mitáš"
|
||||
"Version": "0.4.3",
|
||||
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.3",
|
||||
"Copyright": "Copyright © 2016-2020 Martin Mitáš"
|
||||
}
|
||||
|
@ -47,11 +47,13 @@ import java.util.concurrent.Semaphore;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Service;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.UriPermission;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@ -73,6 +75,7 @@ import java.lang.reflect.Method;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
@ -152,35 +155,79 @@ public class QtNative
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean openURL(String url, String mime)
|
||||
private static Uri getUriWithValidPermission(Context context, String uri, String openMode)
|
||||
{
|
||||
boolean ok = true;
|
||||
|
||||
try {
|
||||
Uri uri = Uri.parse(url);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
if (!mime.isEmpty())
|
||||
intent.setDataAndType(uri, mime);
|
||||
activity().startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
List<UriPermission> permissions = context.getContentResolver().getPersistedUriPermissions();
|
||||
String uriStr = Uri.parse(uri).getPath();
|
||||
|
||||
for (int i = 0; i < permissions.size(); ++i) {
|
||||
Uri iterUri = permissions.get(i).getUri();
|
||||
boolean isRightPermission = permissions.get(i).isReadPermission();
|
||||
|
||||
if (!openMode.equals("r"))
|
||||
isRightPermission = permissions.get(i).isWritePermission();
|
||||
|
||||
if (iterUri.getPath().equals(uriStr) && isRightPermission)
|
||||
return iterUri;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
ok = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean openURL(Context context, String url, String mime)
|
||||
{
|
||||
Uri uri = getUriWithValidPermission(context, url, "r");
|
||||
|
||||
if (uri == null) {
|
||||
Log.e(QtTAG, "openURL(): No permissions to open Uri");
|
||||
return false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (!mime.isEmpty())
|
||||
intent.setDataAndType(uri, mime);
|
||||
|
||||
activity().startActivity(intent);
|
||||
|
||||
return true;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(QtTAG, "openURL(): Invalid Uri");
|
||||
return false;
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.e(QtTAG, "openURL(): Unsupported operation for given Uri");
|
||||
return false;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static int openFdForContentUrl(Context context, String contentUrl, String openMode)
|
||||
{
|
||||
Uri uri = getUriWithValidPermission(context, contentUrl, openMode);
|
||||
int error = -1;
|
||||
|
||||
if (uri == null) {
|
||||
Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
|
||||
return error;
|
||||
}
|
||||
|
||||
try {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode);
|
||||
ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(uri, openMode);
|
||||
return fdDesc.detachFd();
|
||||
} catch (FileNotFoundException e) {
|
||||
return -1;
|
||||
} catch (SecurityException e) {
|
||||
Log.e(QtTAG, "Exception when opening file", e);
|
||||
return -1;
|
||||
return error;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -930,6 +930,7 @@ QString QUtf32::convertToUnicode(const char *chars, int len, QTextCodec::Convert
|
||||
tuple[num++] = *chars++;
|
||||
if (num == 4) {
|
||||
if (!headerdone) {
|
||||
headerdone = true;
|
||||
if (endian == DetectEndianness) {
|
||||
if (tuple[0] == 0xff && tuple[1] == 0xfe && tuple[2] == 0 && tuple[3] == 0 && endian != BigEndianness) {
|
||||
endian = LittleEndianness;
|
||||
|
@ -505,7 +505,7 @@ namespace Qt {
|
||||
AA_DontUseNativeMenuBar = 6,
|
||||
AA_MacDontSwapCtrlAndMeta = 7,
|
||||
AA_Use96Dpi = 8,
|
||||
AA_MSWindowsDisableVirtualKeyboard = 9,
|
||||
AA_DisableNativeVirtualKeyboard = 9,
|
||||
#if QT_DEPRECATED_SINCE(5, 14)
|
||||
AA_X11InitThreads Q_DECL_ENUMERATOR_DEPRECATED = 10,
|
||||
#endif
|
||||
|
@ -293,10 +293,10 @@
|
||||
This attribute must be set before QGuiApplication is constructed.
|
||||
This value was added in 5.13
|
||||
|
||||
\value AA_MSWindowsDisableVirtualKeyboard When this attribute is set,
|
||||
Windows' native on-screen virtual keyboard will not be shown
|
||||
automatically when a text input widget gains focus on a system
|
||||
without a physical keyboard.
|
||||
\value AA_DisableNativeVirtualKeyboard When this attribute is set, the native
|
||||
on-screen virtual keyboard will not be shown automatically when a
|
||||
text input widget gains focus on a system without a physical keyboard.
|
||||
Currently supported on the Windows platform only.
|
||||
This value was added in 5.15
|
||||
|
||||
The following values are deprecated or obsolete:
|
||||
@ -3339,6 +3339,8 @@
|
||||
|
||||
This is a dummy type, designed to help users transition from certain deprecated APIs to their replacement APIs.
|
||||
|
||||
\omitvalue ReturnByValue
|
||||
|
||||
\sa QCursor::bitmap()
|
||||
\sa QCursor::mask()
|
||||
\sa QLabel::picture()
|
||||
|
@ -2230,8 +2230,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
|
||||
startProcess();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.15
|
||||
|
||||
static QStringList parseCombinedArgString(const QString &program)
|
||||
Splits the string \a command into a list of tokens, and returns
|
||||
the list.
|
||||
|
||||
Tokens with spaces can be surrounded by double quotes; three
|
||||
consecutive double quotes represent the quote character itself.
|
||||
*/
|
||||
QStringList QProcess::splitCommand(const QString &command)
|
||||
{
|
||||
QStringList args;
|
||||
QString tmp;
|
||||
@ -2241,13 +2249,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
||||
// handle quoting. tokens can be surrounded by double quotes
|
||||
// "hello world". three consecutive double quotes represent
|
||||
// the quote character itself.
|
||||
for (int i = 0; i < program.size(); ++i) {
|
||||
if (program.at(i) == QLatin1Char('"')) {
|
||||
for (int i = 0; i < command.size(); ++i) {
|
||||
if (command.at(i) == QLatin1Char('"')) {
|
||||
++quoteCount;
|
||||
if (quoteCount == 3) {
|
||||
// third consecutive quote
|
||||
quoteCount = 0;
|
||||
tmp += program.at(i);
|
||||
tmp += command.at(i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -2256,13 +2264,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
||||
inQuote = !inQuote;
|
||||
quoteCount = 0;
|
||||
}
|
||||
if (!inQuote && program.at(i).isSpace()) {
|
||||
if (!inQuote && command.at(i).isSpace()) {
|
||||
if (!tmp.isEmpty()) {
|
||||
args += tmp;
|
||||
tmp.clear();
|
||||
}
|
||||
} else {
|
||||
tmp += program.at(i);
|
||||
tmp += command.at(i);
|
||||
}
|
||||
}
|
||||
if (!tmp.isEmpty())
|
||||
@ -2272,6 +2280,7 @@ static QStringList parseCombinedArgString(const QString &program)
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
\overload
|
||||
|
||||
Starts the command \a command in a new process.
|
||||
@ -2308,11 +2317,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
||||
list-based API. In these rare cases you need to use setProgram() and
|
||||
setNativeArguments() instead of this function.
|
||||
|
||||
\sa splitCommand()
|
||||
|
||||
*/
|
||||
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
||||
void QProcess::start(const QString &command, OpenMode mode)
|
||||
{
|
||||
QStringList args = parseCombinedArgString(command);
|
||||
QStringList args = splitCommand(command);
|
||||
if (args.isEmpty()) {
|
||||
Q_D(QProcess);
|
||||
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
|
||||
@ -2477,6 +2488,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
\overload
|
||||
|
||||
Starts the program \a command in a new process, waits for it to finish,
|
||||
@ -2487,7 +2499,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
|
||||
After the \a command string has been split and unquoted, this function
|
||||
behaves like the overload which takes the arguments as a string list.
|
||||
|
||||
\sa start()
|
||||
\sa start(), splitCommand()
|
||||
*/
|
||||
int QProcess::execute(const QString &command)
|
||||
{
|
||||
@ -2543,6 +2555,7 @@ bool QProcess::startDetached(const QString &program,
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
\overload startDetached()
|
||||
|
||||
Starts the command \a command in a new process, and detaches from it.
|
||||
@ -2553,11 +2566,11 @@ bool QProcess::startDetached(const QString &program,
|
||||
After the \a command string has been split and unquoted, this function
|
||||
behaves like the overload which takes the arguments as a string list.
|
||||
|
||||
\sa start(const QString &command, QIODevice::OpenMode mode)
|
||||
\sa start(const QString &command, QIODevice::OpenMode mode), splitCommand()
|
||||
*/
|
||||
bool QProcess::startDetached(const QString &command)
|
||||
{
|
||||
QStringList args = parseCombinedArgString(command);
|
||||
QStringList args = splitCommand(command);
|
||||
if (args.isEmpty())
|
||||
return false;
|
||||
|
||||
|
@ -160,7 +160,13 @@ public:
|
||||
|
||||
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
|
||||
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X(
|
||||
"Use QProcess::start(const QString &program, const QStringList &arguments,"
|
||||
"OpenMode mode = ReadWrite) instead"
|
||||
)
|
||||
void start(const QString &command, OpenMode mode = ReadWrite);
|
||||
#endif
|
||||
#endif
|
||||
void start(OpenMode mode = ReadWrite);
|
||||
bool startDetached(qint64 *pid = nullptr);
|
||||
@ -250,8 +256,12 @@ public:
|
||||
bool atEnd() const override; // ### Qt6: remove trivial override
|
||||
|
||||
static int execute(const QString &program, const QStringList &arguments);
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X(
|
||||
"Use QProcess::execute(const QString &program, const QStringList &arguments) instead"
|
||||
)
|
||||
static int execute(const QString &command);
|
||||
|
||||
#endif
|
||||
static bool startDetached(const QString &program, const QStringList &arguments,
|
||||
const QString &workingDirectory
|
||||
#if defined(Q_QDOC)
|
||||
@ -261,12 +271,19 @@ public:
|
||||
#if !defined(Q_QDOC)
|
||||
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
|
||||
#endif
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X(
|
||||
"Use QProcess::startDetached(const QString &program, const QStringList &arguments) instead"
|
||||
)
|
||||
static bool startDetached(const QString &command);
|
||||
#endif
|
||||
|
||||
static QStringList systemEnvironment();
|
||||
|
||||
static QString nullDevice();
|
||||
|
||||
static QStringList splitCommand(const QString &command);
|
||||
|
||||
public Q_SLOTS:
|
||||
void terminate();
|
||||
void kill();
|
||||
|
@ -343,7 +343,10 @@ QT_BEGIN_NAMESPACE
|
||||
OS configuration, locale, or they may change in future Qt versions.
|
||||
|
||||
\note On Android, applications with open files on the external storage (<USER> locations),
|
||||
will be killed if the external storage is unmounted.
|
||||
will be killed if the external storage is unmounted.
|
||||
|
||||
\note On Android 6.0 (API 23) or higher, the "WRITE_EXTERNAL_STORAGE" permission must be
|
||||
requested at runtime when using QStandardPaths::writableLocation or QStandardPaths::standardLocations.
|
||||
|
||||
\note On Android, reading/writing to GenericDataLocation needs the READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permission granted.
|
||||
|
||||
|
@ -4149,7 +4149,7 @@ static bool isIp6(const QString &text)
|
||||
|
||||
/*!
|
||||
Returns a valid URL from a user supplied \a userInput string if one can be
|
||||
deducted. In the case that is not possible, an invalid QUrl() is returned.
|
||||
deduced. In the case that is not possible, an invalid QUrl() is returned.
|
||||
|
||||
This overload takes a \a workingDirectory path, in order to be able to
|
||||
handle relative paths. This is especially useful when handling command
|
||||
|
@ -3056,12 +3056,8 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
|
||||
Returns \c true if the item in the column indicated by the given \a source_column
|
||||
and \a source_parent should be included in the model; otherwise returns \c false.
|
||||
|
||||
The default implementation returns \c true if the value held by the relevant item
|
||||
matches the filter string, wildcard string or regular expression.
|
||||
|
||||
\note By default, the Qt::DisplayRole is used to determine if the column
|
||||
should be accepted or not. This can be changed by setting the \l
|
||||
filterRole property.
|
||||
\note The default implementation always returns \c true. You must reimplement this
|
||||
method to get the described behavior.
|
||||
|
||||
\sa filterAcceptsRow(), setFilterFixedString(), setFilterRegExp(), setFilterWildcard()
|
||||
*/
|
||||
|
@ -51,8 +51,6 @@
|
||||
\value M_2_SQRTPI Two divided by the square root of pi, 2 / \unicode{0x221A}\unicode{0x3C0}
|
||||
\value M_SQRT2 The square root of two, \unicode{0x221A}2
|
||||
\value M_SQRT1_2 The square roof of half, 1 / \unicode{0x221A}2
|
||||
|
||||
\pagekeywords math trigonometry qmath floor ceiling absolute sine cosine tangent inverse tan exponent power natural logarithm pi
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -714,7 +714,7 @@ QMetaType &QMetaType::operator=(const QMetaType &other)
|
||||
as the QMetaType \a b, otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*! \fn bool operator!=(const QMetaType &a, const QMetaType &c)
|
||||
/*! \fn bool operator!=(const QMetaType &a, const QMetaType &b)
|
||||
\since 5.15
|
||||
\relates QMetaType
|
||||
\overload
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "qabstracteventdispatcher_p.h"
|
||||
#include "qcoreapplication.h"
|
||||
#include "qcoreapplication_p.h"
|
||||
#include "qloggingcategory.h"
|
||||
#include "qvariant.h"
|
||||
#include "qmetaobject.h"
|
||||
#include <qregexp.h>
|
||||
@ -78,6 +79,8 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
static int DIRECT_CONNECTION_ONLY = 0;
|
||||
|
||||
Q_LOGGING_CATEGORY(lcConnections, "qt.core.qmetaobject.connectslotsbyname")
|
||||
|
||||
Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
|
||||
|
||||
void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
|
||||
@ -183,15 +186,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const
|
||||
QObjectPrivate::QObjectPrivate(int version)
|
||||
: threadData(nullptr), currentChildBeingDeleted(nullptr)
|
||||
{
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
// Don't check the version parameter in internal builds.
|
||||
// This allows incompatible versions to be loaded, possibly for testing.
|
||||
Q_UNUSED(version);
|
||||
#else
|
||||
if (Q_UNLIKELY(version != QObjectPrivateVersion))
|
||||
qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
|
||||
version, QObjectPrivateVersion);
|
||||
#endif
|
||||
checkForIncompatibleLibraryVersion(version);
|
||||
|
||||
// QObjectData initialization
|
||||
q_ptr = nullptr;
|
||||
@ -3555,6 +3550,37 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
|
||||
return success;
|
||||
}
|
||||
|
||||
// Helpers for formatting the connect statements of connectSlotsByName()'s debug mode
|
||||
static QByteArray formatConnectionSignature(const char *className, const QMetaMethod &method)
|
||||
{
|
||||
const auto signature = method.methodSignature();
|
||||
Q_ASSERT(signature.endsWith(')'));
|
||||
const int openParen = signature.indexOf('(');
|
||||
const bool hasParameters = openParen >= 0 && openParen < signature.size() - 2;
|
||||
QByteArray result;
|
||||
if (hasParameters) {
|
||||
result += "qOverload<"
|
||||
+ signature.mid(openParen + 1, signature.size() - openParen - 2) + ">(";
|
||||
}
|
||||
result += '&';
|
||||
result += className + QByteArrayLiteral("::") + method.name();
|
||||
if (hasParameters)
|
||||
result += ')';
|
||||
return result;
|
||||
}
|
||||
|
||||
static QByteArray msgConnect(const QMetaObject *senderMo, const QByteArray &senderName,
|
||||
const QMetaMethod &signal, const QObject *receiver, int receiverIndex)
|
||||
{
|
||||
const auto receiverMo = receiver->metaObject();
|
||||
const auto slot = receiverMo->method(receiverIndex);
|
||||
QByteArray message = QByteArrayLiteral("QObject::connect(")
|
||||
+ senderName + ", " + formatConnectionSignature(senderMo->className(), signal)
|
||||
+ ", " + receiver->objectName().toLatin1() + ", "
|
||||
+ formatConnectionSignature(receiverMo->className(), slot) + ");";
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QMetaObject::connectSlotsByName(QObject *object)
|
||||
|
||||
@ -3636,6 +3662,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
|
||||
// we connect it...
|
||||
if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
|
||||
foundIt = true;
|
||||
qCDebug(lcConnections, "%s",
|
||||
msgConnect(smeta, coName, QMetaObjectPrivate::signal(smeta, sigIndex), o, i).constData());
|
||||
// ...and stop looking for further objects with the same name.
|
||||
// Note: the Designer will make sure each object name is unique in the above
|
||||
// 'list' but other code may create two child objects with the same name. In
|
||||
|
@ -310,6 +310,8 @@ public:
|
||||
virtual ~QObjectPrivate();
|
||||
void deleteChildren();
|
||||
|
||||
inline void checkForIncompatibleLibraryVersion(int version) const;
|
||||
|
||||
void setParent_helper(QObject *);
|
||||
void moveToThread_helper();
|
||||
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
|
||||
@ -384,6 +386,28 @@ public:
|
||||
|
||||
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE);
|
||||
|
||||
/*
|
||||
Catch mixing of incompatible library versions.
|
||||
|
||||
Should be called from the constructor of every non-final subclass
|
||||
of QObjectPrivate, to ensure we catch incompatibilities between
|
||||
the intermediate base and subclasses thereof.
|
||||
*/
|
||||
inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) const
|
||||
{
|
||||
#if defined(QT_BUILD_INTERNAL)
|
||||
// Don't check the version parameter in internal builds.
|
||||
// This allows incompatible versions to be loaded, possibly for testing.
|
||||
Q_UNUSED(version);
|
||||
#else
|
||||
if (Q_UNLIKELY(version != QObjectPrivateVersion)) {
|
||||
qFatal("Cannot mix incompatible Qt library (%d.%d.%d) with this library (%d.%d.%d)",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff,
|
||||
(QObjectPrivateVersion >> 16) & 0xff, (QObjectPrivateVersion >> 8) & 0xff, QObjectPrivateVersion & 0xff);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
|
||||
{
|
||||
return declarativeData && QAbstractDeclarativeData::isSignalConnected
|
||||
|
@ -356,7 +356,7 @@ struct Q_CORE_EXPORT QMetaObject
|
||||
static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
|
||||
&& QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
|
||||
&& !std::is_convertible<Func, const char*>::value, bool>::type
|
||||
invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret)
|
||||
invokeMethod(QObject *context, Func function, decltype(function()) *ret)
|
||||
{
|
||||
return invokeMethodImpl(context,
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
|
||||
|
@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE
|
||||
\brief The <QtCborCommon> header contains definitions common to both the
|
||||
streaming classes (QCborStreamReader and QCborStreamWriter) and to
|
||||
QCborValue.
|
||||
|
||||
\sa QCborError
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -203,7 +205,7 @@ QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st)
|
||||
/*!
|
||||
\class QCborError
|
||||
\inmodule QtCore
|
||||
\relates <QtCborCommon>
|
||||
\inheaderfile <QtCborCommon>
|
||||
\reentrant
|
||||
\since 5.12
|
||||
|
||||
|
@ -72,7 +72,7 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
|
||||
|
||||
void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
|
||||
{
|
||||
#if !QT_CONFIG(library)
|
||||
#if !QT_CONFIG(library) || defined(Q_OS_WASM)
|
||||
Q_UNUSED(library);
|
||||
Q_UNUSED(version);
|
||||
Q_UNUSED(symbol);
|
||||
|
@ -7397,6 +7397,8 @@ float QString::toFloat(bool *ok) const
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
/*! \fn QString &QString::setNum(uint n, int base)
|
||||
@ -7454,6 +7456,8 @@ QString &QString::setNum(qulonglong n, int base)
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
QString &QString::setNum(double n, char f, int prec)
|
||||
@ -7472,6 +7476,8 @@ QString &QString::setNum(double n, char f, int prec)
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
|
||||
|
@ -1116,7 +1116,7 @@ int QStringView::toWCharArray(wchar_t *array) const
|
||||
if (sizeof(wchar_t) == sizeof(QChar)) {
|
||||
if (auto src = data())
|
||||
memcpy(array, src, sizeof(QChar) * size());
|
||||
return size();
|
||||
return int(size()); // ### q6sizetype
|
||||
} else {
|
||||
return QString::toUcs4_helper(reinterpret_cast<const ushort *>(data()), int(size()),
|
||||
reinterpret_cast<uint *>(array));
|
||||
|
@ -528,9 +528,9 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString QStringView::arg(Args &&...args) const
|
||||
\fn QString QLatin1String::arg(Args &&...args) const
|
||||
\fn QString QString::arg(Args &&...args) const
|
||||
\fn template <typename...Args> QString QStringView::arg(Args &&...args) const
|
||||
\fn template <typename...Args> QString QLatin1String::arg(Args &&...args) const
|
||||
\fn template <typename...Args> QString QString::arg(Args &&...args) const
|
||||
\since 5.14
|
||||
|
||||
Replaces occurrences of \c{%N} in this string with the corresponding
|
||||
|
@ -212,7 +212,6 @@ QMutex::~QMutex()
|
||||
}
|
||||
|
||||
/*! \fn void QMutex::lock()
|
||||
\fn QRecursiveMutex::lock()
|
||||
|
||||
Locks the mutex. If another thread has locked the mutex then this
|
||||
call will block until that thread has unlocked it.
|
||||
@ -237,7 +236,6 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
|
||||
}
|
||||
|
||||
/*! \fn bool QMutex::tryLock(int timeout)
|
||||
\fn bool QRecursiveMutex::tryLock(int timeout)
|
||||
|
||||
Attempts to lock the mutex. This function returns \c true if the lock
|
||||
was obtained; otherwise it returns \c false. If another thread has
|
||||
@ -272,7 +270,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
}
|
||||
|
||||
/*! \fn bool QMutex::try_lock()
|
||||
\fn bool QRecursiveMutex::try_lock()
|
||||
\since 5.8
|
||||
|
||||
Attempts to lock the mutex. This function returns \c true if the lock
|
||||
@ -286,7 +283,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
*/
|
||||
|
||||
/*! \fn template <class Rep, class Period> bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
|
||||
\fn template <class Rep, class Period> bool QRecursiveMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
|
||||
\since 5.8
|
||||
|
||||
Attempts to lock the mutex. This function returns \c true if the lock
|
||||
@ -311,7 +307,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
*/
|
||||
|
||||
/*! \fn template<class Clock, class Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
|
||||
\fn template<class Clock, class Duration> bool QRecursiveMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
|
||||
\since 5.8
|
||||
|
||||
Attempts to lock the mutex. This function returns \c true if the lock
|
||||
@ -336,7 +331,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
*/
|
||||
|
||||
/*! \fn void QMutex::unlock()
|
||||
\fn void QRecursiveMutex::unlock()
|
||||
|
||||
Unlocks the mutex. Attempting to unlock a mutex in a different
|
||||
thread to the one that locked it results in an error. Unlocking a
|
||||
|
@ -1100,9 +1100,10 @@ QString QDate::longDayName(int weekday, MonthNameType type)
|
||||
|
||||
#if QT_CONFIG(datestring) // depends on, so implies, textdate
|
||||
|
||||
static QString toStringTextDate(QDate date, QCalendar cal)
|
||||
static QString toStringTextDate(QDate date)
|
||||
{
|
||||
if (date.isValid()) {
|
||||
QCalendar cal; // Always Gregorian
|
||||
const auto parts = cal.partsFromDate(date);
|
||||
if (parts.isValid()) {
|
||||
const QLatin1Char sp(' ');
|
||||
@ -1123,14 +1124,10 @@ static QString toStringIsoDate(QDate date)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString QDate::toString(Qt::DateFormat format) const
|
||||
\fn QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
|
||||
\overload
|
||||
|
||||
Returns the date as a string. The \a format parameter determines the format
|
||||
of the string. If \a cal is supplied, it determines the calendar used to
|
||||
represent the date; it defaults to Gregorian.
|
||||
of the string.
|
||||
|
||||
If the \a format is Qt::TextDate, the string is formatted in the default
|
||||
way. The day and month names will be localized names using the system
|
||||
@ -1168,16 +1165,44 @@ static QString toStringIsoDate(QDate date)
|
||||
*/
|
||||
QString QDate::toString(Qt::DateFormat format) const
|
||||
{
|
||||
return toString(format, QCalendar());
|
||||
if (!isValid())
|
||||
return QString();
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toString(*this, QLocale::ShortFormat);
|
||||
case Qt::SystemLocaleLongDate:
|
||||
return QLocale::system().toString(*this, QLocale::LongFormat);
|
||||
case Qt::LocaleDate:
|
||||
case Qt::DefaultLocaleShortDate:
|
||||
return QLocale().toString(*this, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toString(*this, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::RFC2822Date:
|
||||
return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"));
|
||||
default:
|
||||
case Qt::TextDate:
|
||||
return toStringTextDate(*this);
|
||||
case Qt::ISODate:
|
||||
case Qt::ISODateWithMs:
|
||||
// No calendar dependence
|
||||
return toStringIsoDate(*this);
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
{
|
||||
if (!isValid())
|
||||
return QString();
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
|
||||
@ -1188,18 +1213,19 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
return QLocale().toString(*this, QLocale::ShortFormat, cal);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toString(*this, QLocale::LongFormat, cal);
|
||||
#endif // 5.15
|
||||
QT_WARNING_POP
|
||||
case Qt::RFC2822Date:
|
||||
return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"), cal);
|
||||
default:
|
||||
case Qt::TextDate:
|
||||
return toStringTextDate(*this, cal);
|
||||
return toStringTextDate(*this);
|
||||
case Qt::ISODate:
|
||||
case Qt::ISODateWithMs:
|
||||
// No calendar dependence
|
||||
return toStringIsoDate(*this);
|
||||
}
|
||||
}
|
||||
#endif // 5.15
|
||||
|
||||
/*!
|
||||
\fn QString QDate::toString(const QString &format) const
|
||||
@ -1208,7 +1234,7 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
\fn QString QDate::toString(QStringView format, QCalendar cal) const
|
||||
|
||||
Returns the date as a string. The \a format parameter determines the format
|
||||
of the result string. If \cal is supplied, it determines the calendar used
|
||||
of the result string. If \a cal is supplied, it determines the calendar used
|
||||
to represent the date; it defaults to Gregorian.
|
||||
|
||||
These expressions may be used:
|
||||
@ -1643,6 +1669,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toDate(string, QLocale::ShortFormat);
|
||||
@ -1653,6 +1680,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
|
||||
return QLocale().toDate(string, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toDate(string, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::RFC2822Date:
|
||||
return rfcDateImpl(string).date;
|
||||
@ -2033,6 +2061,7 @@ QString QTime::toString(Qt::DateFormat format) const
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toString(*this, QLocale::ShortFormat);
|
||||
@ -2043,6 +2072,7 @@ QString QTime::toString(Qt::DateFormat format) const
|
||||
return QLocale().toString(*this, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toString(*this, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::ISODateWithMs:
|
||||
return QString::asprintf("%02d:%02d:%02d.%03d", hour(), minute(), second(), msec());
|
||||
@ -2434,6 +2464,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toTime(string, QLocale::ShortFormat);
|
||||
@ -2444,6 +2475,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
return QLocale().toTime(string, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toTime(string, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::RFC2822Date:
|
||||
return rfcDateImpl(string).time;
|
||||
@ -4279,14 +4311,9 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
|
||||
|
||||
#if QT_CONFIG(datestring) // depends on, so implies, textdate
|
||||
/*!
|
||||
\fn QString QDateTime::toString(Qt::DateFormat format) const
|
||||
\fn QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
|
||||
\overload
|
||||
|
||||
Returns the datetime as a string in the \a format given. If \cal is
|
||||
supplied, it determines the calendar used to represent the date; it defaults
|
||||
to Gregorian.
|
||||
Returns the datetime as a string in the \a format given.
|
||||
|
||||
If the \a format is Qt::TextDate, the string is formatted in the default
|
||||
way. The day and month names will be localized names using the system
|
||||
@ -4328,11 +4355,6 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
|
||||
*/
|
||||
|
||||
QString QDateTime::toString(Qt::DateFormat format) const
|
||||
{
|
||||
return toString(format, QCalendar());
|
||||
}
|
||||
|
||||
QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
{
|
||||
QString buf;
|
||||
if (!isValid())
|
||||
@ -4340,26 +4362,28 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
|
||||
return QLocale::system().toString(*this, QLocale::ShortFormat);
|
||||
case Qt::SystemLocaleLongDate:
|
||||
return QLocale::system().toString(*this, QLocale::LongFormat, cal);
|
||||
return QLocale::system().toString(*this, QLocale::LongFormat);
|
||||
case Qt::LocaleDate:
|
||||
case Qt::DefaultLocaleShortDate:
|
||||
return QLocale().toString(*this, QLocale::ShortFormat, cal);
|
||||
return QLocale().toString(*this, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toString(*this, QLocale::LongFormat, cal);
|
||||
return QLocale().toString(*this, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::RFC2822Date: {
|
||||
buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ", cal);
|
||||
buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ");
|
||||
buf += toOffsetString(Qt::TextDate, offsetFromUtc());
|
||||
return buf;
|
||||
}
|
||||
default:
|
||||
case Qt::TextDate: {
|
||||
const QPair<QDate, QTime> p = getDateTime(d);
|
||||
buf = toStringTextDate(p.first, cal);
|
||||
buf = toStringTextDate(p.first);
|
||||
// Insert time between date's day and year:
|
||||
buf.insert(buf.lastIndexOf(QLatin1Char(' ')),
|
||||
QLatin1Char(' ') + p.second.toString(Qt::TextDate));
|
||||
@ -4381,7 +4405,6 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
}
|
||||
case Qt::ISODate:
|
||||
case Qt::ISODateWithMs: {
|
||||
// No calendar dependence
|
||||
const QPair<QDate, QTime> p = getDateTime(d);
|
||||
buf = toStringIsoDate(p.first);
|
||||
if (buf.isEmpty())
|
||||
@ -4412,7 +4435,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
|
||||
\fn QString QDateTime::toString(QStringView format, QCalendar cal) const
|
||||
|
||||
Returns the datetime as a string. The \a format parameter determines the
|
||||
format of the result string. If \cal is supplied, it determines the calendar
|
||||
format of the result string. If \a cal is supplied, it determines the calendar
|
||||
used to represent the date; it defaults to Gregorian. See QTime::toString()
|
||||
and QDate::toString() for the supported specifiers for time and date,
|
||||
respectively.
|
||||
@ -5228,6 +5251,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
|
||||
switch (format) {
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
|
||||
case Qt::SystemLocaleDate:
|
||||
case Qt::SystemLocaleShortDate:
|
||||
return QLocale::system().toDateTime(string, QLocale::ShortFormat);
|
||||
@ -5238,6 +5262,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
return QLocale().toDateTime(string, QLocale::ShortFormat);
|
||||
case Qt::DefaultLocaleLongDate:
|
||||
return QLocale().toDateTime(string, QLocale::LongFormat);
|
||||
QT_WARNING_POP
|
||||
#endif // 5.15
|
||||
case Qt::RFC2822Date: {
|
||||
const ParsedRfcDateTime rfc = rfcDateImpl(string);
|
||||
|
@ -111,7 +111,11 @@ public:
|
||||
#endif // textdate && deprecated
|
||||
#if QT_CONFIG(datestring)
|
||||
QString toString(Qt::DateFormat format = Qt::TextDate) const;
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
// Only the deprecated locale-dependent formats use the calendar.
|
||||
QT_DEPRECATED_X("Use QLocale or omit the calendar")
|
||||
QString toString(Qt::DateFormat format, QCalendar cal) const;
|
||||
#endif
|
||||
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
QString toString(const QString &format) const;
|
||||
@ -334,7 +338,6 @@ public:
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
QString toString(Qt::DateFormat format = Qt::TextDate) const;
|
||||
QString toString(Qt::DateFormat format, QCalendar cal) const;
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
QString toString(const QString &format) const;
|
||||
QString toString(const QString &format, QCalendar cal) const;
|
||||
|
@ -1999,7 +1999,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\sa replace()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMultiMap<Key, T>::const_iterator pos, const Key &key, const T &value)
|
||||
/*! \fn [qmultimap-insert-pos] template <class Key, class T> typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMultiMap<Key, T>::const_iterator pos, const Key &key, const T &value)
|
||||
|
||||
\since 5.1
|
||||
Inserts a new item with the key \a key and value \a value and with hint \a pos
|
||||
@ -2128,7 +2128,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
once in the returned list.
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
|
||||
/*!
|
||||
\fn [qmultimap-unite] template <class Key, class T> QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
|
||||
|
||||
Inserts all the items in the \a other map into this map. If a
|
||||
key is common to both maps, the resulting map will contain the
|
||||
|
@ -1086,14 +1086,14 @@ public:
|
||||
QList<Key> uniqueKeys() const;
|
||||
QList<T> values(const Key &key) const;
|
||||
|
||||
using typename QMap<Key, T>::iterator;
|
||||
using typename QMap<Key, T>::const_iterator;
|
||||
|
||||
inline typename QMap<Key, T>::iterator replace(const Key &key, const T &value)
|
||||
{ return QMap<Key, T>::insert(key, value); }
|
||||
iterator insert(const Key &key, const T &value);
|
||||
iterator insert(const_iterator pos, const Key &key, const T &value);
|
||||
typename QMap<Key, T>::iterator insert(const Key &key, const T &value);
|
||||
//! [qmultimap-insert-pos]
|
||||
typename QMap<Key, T>::iterator insert(typename QMap<Key, T>::const_iterator pos,
|
||||
const Key &key, const T &value);
|
||||
|
||||
//! [qmultimap-unite]
|
||||
QMultiMap &unite(const QMultiMap &other);
|
||||
inline QMultiMap &operator+=(const QMultiMap &other)
|
||||
{ return unite(other); }
|
||||
@ -1151,7 +1151,7 @@ Q_OUTOFLINE_TEMPLATE QList<Key> QMultiMap<Key, T>::uniqueKeys() const
|
||||
{
|
||||
QList<Key> res;
|
||||
res.reserve(size()); // May be too much, but assume short lifetime
|
||||
const_iterator i = this->begin();
|
||||
typename QMap<Key, T>::const_iterator i = this->begin();
|
||||
if (i != this->end()) {
|
||||
for (;;) {
|
||||
const Key &aKey = i.key();
|
||||
@ -1172,7 +1172,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiMap<Key, T>::values(const Key &akey) const
|
||||
QList<T> res;
|
||||
Node *n = this->d->findNode(akey);
|
||||
if (n) {
|
||||
const_iterator it(n);
|
||||
typename QMap<Key, T>::const_iterator it(n);
|
||||
do {
|
||||
res.append(*it);
|
||||
++it;
|
||||
@ -1182,8 +1182,8 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiMap<Key, T>::values(const Key &akey) const
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey,
|
||||
const T &avalue)
|
||||
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey,
|
||||
const T &avalue)
|
||||
{
|
||||
detach();
|
||||
Node* y = this->d->end();
|
||||
@ -1195,11 +1195,13 @@ Q_INLINE_TEMPLATE typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert
|
||||
x = left ? x->leftNode() : x->rightNode();
|
||||
}
|
||||
Node *z = this->d->createNode(akey, avalue, y, left);
|
||||
return iterator(z);
|
||||
return typename QMap<Key, T>::iterator(z);
|
||||
}
|
||||
|
||||
#ifndef Q_CLANG_QDOC
|
||||
template <class Key, class T>
|
||||
typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator pos, const Key &akey, const T &avalue)
|
||||
typename QMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMap<Key, T>::const_iterator pos,
|
||||
const Key &akey, const T &avalue)
|
||||
{
|
||||
if (this->d->ref.isShared())
|
||||
return insert(akey, avalue);
|
||||
@ -1216,7 +1218,7 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
|
||||
if (!qMapLessThanKey(n->key, akey))
|
||||
return insert(akey, avalue); // ignore hint
|
||||
Node *z = this->d->createNode(akey, avalue, n, false); // insert right most
|
||||
return iterator(z);
|
||||
return typename QMap<Key, T>::iterator(z);
|
||||
}
|
||||
return insert(akey, avalue);
|
||||
} else {
|
||||
@ -1229,7 +1231,7 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
|
||||
if (pos == this->constBegin()) {
|
||||
// There is no previous value (insert left most)
|
||||
Node *z = this->d->createNode(akey, avalue, this->begin().i, true);
|
||||
return iterator(z);
|
||||
return typename QMap<Key, T>::iterator(z);
|
||||
} else {
|
||||
Node *prev = const_cast<Node*>(pos.i->previousNode());
|
||||
if (!qMapLessThanKey(prev->key, akey))
|
||||
@ -1238,11 +1240,11 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
|
||||
// Hint is ok - do insert
|
||||
if (prev->right == nullptr) {
|
||||
Node *z = this->d->createNode(akey, avalue, prev, false);
|
||||
return iterator(z);
|
||||
return typename QMap<Key, T>::iterator(z);
|
||||
}
|
||||
if (next->left == nullptr) {
|
||||
Node *z = this->d->createNode(akey, avalue, next, true);
|
||||
return iterator(z);
|
||||
return typename QMap<Key, T>::iterator(z);
|
||||
}
|
||||
Q_ASSERT(false); // We should have prev->right == nullptr or next->left == nullptr.
|
||||
return insert(akey, avalue);
|
||||
@ -1254,14 +1256,15 @@ template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
|
||||
{
|
||||
QMultiMap<Key, T> copy(other);
|
||||
const_iterator it = copy.constEnd();
|
||||
const const_iterator b = copy.constBegin();
|
||||
typename QMap<Key, T>::const_iterator it = copy.constEnd();
|
||||
const typename QMap<Key, T>::const_iterator b = copy.constBegin();
|
||||
while (it != b) {
|
||||
--it;
|
||||
insert(it.key(), it.value());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // Q_CLANG_QDOC
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE bool QMultiMap<Key, T>::contains(const Key &key, const T &value) const
|
||||
@ -1293,8 +1296,8 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &akey) const
|
||||
QMultiMap::Node *lastNode;
|
||||
this->d->nodeRange(akey, &firstNode, &lastNode);
|
||||
|
||||
const_iterator ci_first(firstNode);
|
||||
const const_iterator ci_last(lastNode);
|
||||
typename QMap<Key, T>::const_iterator ci_first(firstNode);
|
||||
const typename QMap<Key, T>::const_iterator ci_last(lastNode);
|
||||
int cnt = 0;
|
||||
while (ci_first != ci_last) {
|
||||
++cnt;
|
||||
|
@ -903,7 +903,7 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
template <typename T, int Prealloc> uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
|
||||
\fn template <typename T, int Prealloc> uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
|
||||
\relates QVarLengthArray
|
||||
\since 5.14
|
||||
|
||||
|
@ -494,7 +494,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_textmarkdownreader
|
||||
)
|
||||
|
||||
qt_extend_target(Gui CONDITION QT_FEATURE_system_textmarkdownreader AND QT_FEATURE_textmarkdownreader
|
||||
PUBLIC_LIBRARIES
|
||||
LIBRARIES
|
||||
libmd4c
|
||||
)
|
||||
|
||||
|
@ -599,7 +599,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_textmarkdownreader
|
||||
)
|
||||
|
||||
qt_extend_target(Gui CONDITION QT_FEATURE_system_textmarkdownreader AND QT_FEATURE_textmarkdownreader
|
||||
PUBLIC_LIBRARIES
|
||||
LIBRARIES
|
||||
libmd4c
|
||||
)
|
||||
|
||||
|
@ -231,7 +231,8 @@ public:
|
||||
bool hasAlphaChannel() const;
|
||||
void setAlphaChannel(const QImage &alphaChannel);
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED QImage alphaChannel() const;
|
||||
QT_DEPRECATED_X("Use convertToFormat(QImage::Format_Alpha8)")
|
||||
QImage alphaChannel() const;
|
||||
#endif
|
||||
QImage createAlphaMask(Qt::ImageConversionFlags flags = Qt::AutoColor) const;
|
||||
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
|
||||
|
@ -2368,6 +2368,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
|
||||
{
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
/*!
|
||||
Construct a tablet event of the given \a type.
|
||||
|
||||
@ -2411,6 +2412,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
|
||||
tangentialPressure, rotation, z, keyState, uniqueID, Qt::NoButton, Qt::NoButton)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\internal
|
||||
@ -2451,6 +2453,12 @@ Qt::MouseButtons QTabletEvent::buttons() const
|
||||
/*!
|
||||
\fn TabletDevices QTabletEvent::device() const
|
||||
|
||||
\deprecated Use deviceType().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn TabletDevices QTabletEvent::deviceType() const
|
||||
|
||||
Returns the type of device that generated the event.
|
||||
|
||||
\sa TabletDevice
|
||||
@ -2615,12 +2623,16 @@ Qt::MouseButtons QTabletEvent::buttons() const
|
||||
\fn qreal &QTabletEvent::hiResGlobalX() const
|
||||
|
||||
The high precision x position of the tablet device.
|
||||
|
||||
\obsolete use globalPosF()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn qreal &QTabletEvent::hiResGlobalY() const
|
||||
|
||||
The high precision y position of the tablet device.
|
||||
|
||||
\obsolete use globalPosF()
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -280,10 +280,15 @@ public:
|
||||
Q_ENUM(TabletDevice)
|
||||
enum PointerType { UnknownPointer, Pen, Cursor, Eraser };
|
||||
Q_ENUM(PointerType)
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
// Actually deprecated since 5.4, in docs
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use the other QTabletEvent constructor")
|
||||
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
|
||||
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
|
||||
qreal tangentialPressure, qreal rotation, int z,
|
||||
Qt::KeyboardModifiers keyState, qint64 uniqueID); // ### remove in Qt 6
|
||||
#endif
|
||||
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
|
||||
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
|
||||
qreal tangentialPressure, qreal rotation, int z,
|
||||
@ -304,9 +309,15 @@ public:
|
||||
inline int y() const { return qRound(mPos.y()); }
|
||||
inline int globalX() const { return qRound(mGPos.x()); }
|
||||
inline int globalY() const { return qRound(mGPos.y()); }
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_VERSION_X_5_15("use globalPosF().x()")
|
||||
inline qreal hiResGlobalX() const { return mGPos.x(); }
|
||||
QT_DEPRECATED_VERSION_X_5_15("use globalPosF().y()")
|
||||
inline qreal hiResGlobalY() const { return mGPos.y(); }
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use deviceType()")
|
||||
inline TabletDevice device() const { return TabletDevice(mDev); }
|
||||
#endif
|
||||
inline TabletDevice deviceType() const { return TabletDevice(mDev); }
|
||||
inline PointerType pointerType() const { return PointerType(mPointerType); }
|
||||
inline qint64 uniqueId() const { return mUnique; }
|
||||
inline qreal pressure() const { return mPress; }
|
||||
|
@ -610,7 +610,7 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
|
||||
\li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and
|
||||
\c none disables them.
|
||||
|
||||
\li \c {dpiawareness=[0|1|2} Sets the DPI awareness of the process
|
||||
\li \c {dpiawareness=[0|1|2]} Sets the DPI awareness of the process
|
||||
(see \l{High DPI Displays}, since Qt 5.4).
|
||||
\li \c {fontengine=freetype}, uses the FreeType font engine.
|
||||
\li \c {fontengine=directwrite}, uses the experimental DirectWrite
|
||||
@ -1738,6 +1738,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
|
||||
|
||||
window_list.clear();
|
||||
screen_list.clear();
|
||||
|
||||
self = nullptr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1891,6 +1893,10 @@ bool QGuiApplication::event(QEvent *e)
|
||||
{
|
||||
if(e->type() == QEvent::LanguageChange) {
|
||||
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
|
||||
for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) {
|
||||
if (topLevelWindow->flags() != Qt::Desktop)
|
||||
postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange));
|
||||
}
|
||||
} else if (e->type() == QEvent::Quit) {
|
||||
// Close open windows. This is done in order to deliver de-expose
|
||||
// events while the event loop is still running.
|
||||
@ -3412,8 +3418,11 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
|
||||
*/
|
||||
QFont QGuiApplication::font()
|
||||
{
|
||||
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
|
||||
const auto locker = qt_scoped_lock(applicationFontMutex);
|
||||
if (!QGuiApplicationPrivate::self && !QGuiApplicationPrivate::app_font) {
|
||||
qWarning("QGuiApplication::font(): no QGuiApplication instance and no application font set.");
|
||||
return QFont(); // in effect: QFont((QFontPrivate*)nullptr), so no recursion
|
||||
}
|
||||
initFontUnlocked();
|
||||
return *QGuiApplicationPrivate::app_font;
|
||||
}
|
||||
|
@ -3224,6 +3224,7 @@ const uint qt_inv_premul_factor[256] = {
|
||||
/*!
|
||||
\namespace QColorConstants
|
||||
\inmodule QtGui
|
||||
\since 5.14
|
||||
|
||||
\brief The QColorConstants namespace contains QColor predefined constants.
|
||||
|
||||
|
@ -87,6 +87,11 @@ constexpr quint32 IccTag(uchar a, uchar b, uchar c, uchar d)
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
}
|
||||
|
||||
enum class ColorSpaceType : quint32 {
|
||||
Rgb = IccTag('R', 'G', 'B', ' '),
|
||||
Gray = IccTag('G', 'R', 'A', 'Y'),
|
||||
};
|
||||
|
||||
enum class ProfileClass : quint32 {
|
||||
Input = IccTag('s', 'c', 'r', 'n'),
|
||||
Display = IccTag('m', 'n', 't', 'r'),
|
||||
@ -105,6 +110,7 @@ enum class Tag : quint32 {
|
||||
rTRC = IccTag('r', 'T', 'R', 'C'),
|
||||
gTRC = IccTag('g', 'T', 'R', 'C'),
|
||||
bTRC = IccTag('b', 'T', 'R', 'C'),
|
||||
kTRC = IccTag('k', 'T', 'R', 'C'),
|
||||
A2B0 = IccTag('A', '2', 'B', '0'),
|
||||
A2B1 = IccTag('A', '2', 'B', '1'),
|
||||
B2A0 = IccTag('B', '2', 'A', '0'),
|
||||
@ -219,8 +225,10 @@ static bool isValidIccProfile(const ICCProfileHeader &header)
|
||||
}
|
||||
|
||||
// Don't overflow 32bit integers:
|
||||
if (header.tagCount >= INT32_MAX / sizeof(TagTableEntry))
|
||||
if (header.tagCount >= INT32_MAX / sizeof(TagTableEntry)) {
|
||||
qCWarning(lcIcc, "Failed tag count sanity");
|
||||
return false;
|
||||
}
|
||||
if (header.profileSize - sizeof(ICCProfileHeader) < header.tagCount * sizeof(TagTableEntry)) {
|
||||
qCWarning(lcIcc, "Failed basic size sanity");
|
||||
return false;
|
||||
@ -231,7 +239,8 @@ static bool isValidIccProfile(const ICCProfileHeader &header)
|
||||
qCWarning(lcIcc, "Unsupported ICC profile class %x", quint32(header.profileClass));
|
||||
return false;
|
||||
}
|
||||
if (header.inputColorSpace != 0x52474220 /* 'RGB '*/) {
|
||||
if (header.inputColorSpace != uint(ColorSpaceType::Rgb)
|
||||
&& header.inputColorSpace != uint(ColorSpaceType::Gray)) {
|
||||
qCWarning(lcIcc, "Unsupported ICC input color space %x", quint32(header.inputColorSpace));
|
||||
return false;
|
||||
}
|
||||
@ -610,10 +619,8 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
|
||||
return false;
|
||||
}
|
||||
const ICCProfileHeader *header = (const ICCProfileHeader *)data.constData();
|
||||
if (!isValidIccProfile(*header)) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: failed general sanity check";
|
||||
return false;
|
||||
}
|
||||
if (!isValidIccProfile(*header))
|
||||
return false; // if failed we already printing a warning
|
||||
if (qsizetype(header->profileSize) > data.size()) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: failed size sanity 2";
|
||||
return false;
|
||||
@ -658,39 +665,74 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
|
||||
}
|
||||
|
||||
// Check the profile is three-component matrix based (what we currently support):
|
||||
if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) ||
|
||||
!tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) ||
|
||||
!tagIndex.contains(Tag::wtpt)) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based";
|
||||
return false;
|
||||
if (header->inputColorSpace == uint(ColorSpaceType::Rgb)) {
|
||||
if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) ||
|
||||
!tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) ||
|
||||
!tagIndex.contains(Tag::wtpt)) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Q_ASSERT(header->inputColorSpace == uint(ColorSpaceType::Gray));
|
||||
if (!tagIndex.contains(Tag::kTRC) || !tagIndex.contains(Tag::wtpt)) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - not valid gray scale based";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace);
|
||||
|
||||
// Parse XYZ tags
|
||||
if (!parseXyzData(data, tagIndex[Tag::rXYZ], colorspaceDPtr->toXyz.r))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::gXYZ], colorspaceDPtr->toXyz.g))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::bXYZ], colorspaceDPtr->toXyz.b))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint))
|
||||
return false;
|
||||
if (header->inputColorSpace == uint(ColorSpaceType::Rgb)) {
|
||||
// Parse XYZ tags
|
||||
if (!parseXyzData(data, tagIndex[Tag::rXYZ], colorspaceDPtr->toXyz.r))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::gXYZ], colorspaceDPtr->toXyz.g))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::bXYZ], colorspaceDPtr->toXyz.b))
|
||||
return false;
|
||||
if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint))
|
||||
return false;
|
||||
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
|
||||
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: sRGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
|
||||
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: Adobe RGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::AdobeRgb;
|
||||
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
|
||||
}
|
||||
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::ProPhotoRgb;
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
|
||||
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: sRGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
|
||||
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: Adobe RGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::AdobeRgb;
|
||||
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
|
||||
}
|
||||
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
|
||||
qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::ProPhotoRgb;
|
||||
}
|
||||
} else {
|
||||
// We will use sRGB primaries and fit to match the given white-point if
|
||||
// it doesn't match sRGB's.
|
||||
QColorVector whitePoint;
|
||||
if (!parseXyzData(data, tagIndex[Tag::wtpt], whitePoint))
|
||||
return false;
|
||||
if (!qFuzzyCompare(whitePoint.y, 1.0f) || (1.0f + whitePoint.z - whitePoint.x) == 0.0f) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - gray white-point not normalized";
|
||||
return false;
|
||||
}
|
||||
if (whitePoint == QColorVector::D65()) {
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
|
||||
} else {
|
||||
colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
|
||||
// Calculate chromaticity from xyz (assuming y == 1.0f).
|
||||
float y = 1.0f / (1.0f + whitePoint.z - whitePoint.x);
|
||||
float x = whitePoint.x * y;
|
||||
QColorSpacePrimaries primaries(QColorSpace::Primaries::SRgb);
|
||||
primaries.whitePoint = QPointF(x,y);
|
||||
if (!primaries.areValid()) {
|
||||
qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - invalid white-point";
|
||||
return false;
|
||||
}
|
||||
colorspaceDPtr->toXyz = primaries.toXyzMatrix();
|
||||
}
|
||||
}
|
||||
// Reset the matrix to our canonical values:
|
||||
if (colorspaceDPtr->primaries != QColorSpace::Primaries::Custom)
|
||||
@ -700,7 +742,11 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
|
||||
TagEntry rTrc;
|
||||
TagEntry gTrc;
|
||||
TagEntry bTrc;
|
||||
if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) {
|
||||
if (header->inputColorSpace == uint(ColorSpaceType::Gray)) {
|
||||
rTrc = tagIndex[Tag::kTRC];
|
||||
gTrc = tagIndex[Tag::kTRC];
|
||||
bTrc = tagIndex[Tag::kTRC];
|
||||
} else if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) {
|
||||
// Apple extension for parametric version of TRCs in ICCv2:
|
||||
rTrc = tagIndex[Tag::aarg];
|
||||
gTrc = tagIndex[Tag::aagg];
|
||||
|
@ -577,6 +577,11 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
|
||||
specifying a non-zero level in QRhiReadbackDescription leads to returning
|
||||
an all-zero image. In practice this feature will be unsupported with OpenGL
|
||||
ES 2.0, while it will likely be supported everywhere else.
|
||||
|
||||
\value TexelFetch Indicates that texelFetch() is available in shaders. In
|
||||
practice this will be reported as unsupported with OpenGL ES 2.0 and OpenGL
|
||||
2.x contexts, because GLSL 100 es and versions before 130 do not support
|
||||
this function.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -622,18 +627,27 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
|
||||
is what some OpenGL ES implementations provide.
|
||||
|
||||
\value FramesInFlight The number of frames the backend may keep "in
|
||||
flight". The value has no relevance, and is unspecified, with backends like
|
||||
OpenGL and Direct3D 11. With backends like Vulkan or Metal, it is the
|
||||
responsibility of QRhi to block whenever starting a new frame and finding
|
||||
the CPU is already \c{N - 1} frames ahead of the GPU (because the command
|
||||
buffer submitted in frame no. \c{current} - \c{N} has not yet completed).
|
||||
The value N is what is returned from here, and is typically 2. This can be
|
||||
relevant to applications that integrate rendering done directly with the
|
||||
graphics API, as such rendering code may want to perform double (if the
|
||||
value is 2) buffering for resources, such as, buffers, similarly to the
|
||||
QRhi backends themselves. The current frame slot index (a value running 0,
|
||||
1, .., N-1, then wrapping around) is retrievable from
|
||||
QRhi::currentFrameSlot().
|
||||
flight": with backends like Vulkan or Metal, it is the responsibility of
|
||||
QRhi to block whenever starting a new frame and finding the CPU is already
|
||||
\c{N - 1} frames ahead of the GPU (because the command buffer submitted in
|
||||
frame no. \c{current} - \c{N} has not yet completed). The value N is what
|
||||
is returned from here, and is typically 2. This can be relevant to
|
||||
applications that integrate rendering done directly with the graphics API,
|
||||
as such rendering code may want to perform double (if the value is 2)
|
||||
buffering for resources, such as, buffers, similarly to the QRhi backends
|
||||
themselves. The current frame slot index (a value running 0, 1, .., N-1,
|
||||
then wrapping around) is retrievable from QRhi::currentFrameSlot(). The
|
||||
value is 1 for backends where the graphics API offers no such low level
|
||||
control over the command submission process. Note that pipelining may still
|
||||
happen even when this value is 1 (some backends, such as D3D11, are
|
||||
designed to attempt to enable this, for instance, by using an update
|
||||
strategy for uniform buffers that does not stall the pipeline), but that is
|
||||
then not controlled by QRhi and so not reflected here in the API.
|
||||
|
||||
\value MaxAsyncReadbackFrames The number of \l{QRhi::endFrame()}{submitted}
|
||||
frames (including the one that contains the readback) after which an
|
||||
asynchronous texture or buffer readback is guaranteed to complete upon
|
||||
\l{QRhi::beginFrame()}{starting a new frame}.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -1945,6 +1959,40 @@ quint64 QRhiResource::globalResourceId() const
|
||||
size() will always report the size requested in \a sz.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QRhiBuffer::NativeBuffer
|
||||
\brief Contains information about the underlying native resources of a buffer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\variable QRhiBuffer::NativeBuffer::objects
|
||||
\brief an array with pointers to the native object handles.
|
||||
|
||||
With OpenGL, the native handle is a GLuint value, so the elements in the \c
|
||||
objects array are pointers to a GLuint. With Vulkan, the native handle is a
|
||||
VkBuffer, so the elements of the array are pointers to a VkBuffer. With
|
||||
Direct3D 11 and Metal the elements are pointers to a ID3D11Buffer or
|
||||
MTLBuffer pointer, respectively.
|
||||
|
||||
\note Pay attention to the fact that the elements are always pointers to
|
||||
the native buffer handle type, even if the native type itself is a pointer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\variable QRhiBuffer::NativeBuffer::slotCount
|
||||
\brief Specifies the number of valid elements in the objects array.
|
||||
|
||||
The value can be 0, 1, 2, or 3 in practice. 0 indicates that the QRhiBuffer
|
||||
is not backed by any native buffer objects. This can happen with
|
||||
QRhiBuffers with the usage UniformBuffer when the underlying API does not
|
||||
support (or the backend chooses not to use) native uniform buffers. 1 is
|
||||
commonly used for Immutable and Static types (but some backends may
|
||||
differ). 2 or 3 is typical when the type is Dynamic (but some backends may
|
||||
differ).
|
||||
|
||||
\sa QRhi::currentFrameSlot(), QRhi::FramesInFlight
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
@ -1973,6 +2021,46 @@ QRhiResource::Type QRhiBuffer::resourceType() const
|
||||
Regardless of the return value, calling release() is always safe.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\return the underlying native resources for this buffer. The returned value
|
||||
will be empty if exposing the underlying native resources is not supported by
|
||||
the backend.
|
||||
|
||||
A QRhiBuffer may be backed by multiple native buffer objects, depending on
|
||||
the type() and the QRhi backend in use. When this is the case, all of them
|
||||
are returned in the objects array in the returned struct, with slotCount
|
||||
specifying the number of native buffer objects. While
|
||||
\l{QRhi::beginFrame()}{recording a frame}, QRhi::currentFrameSlot() can be
|
||||
used to determine which of the native buffers QRhi is using for operations
|
||||
that read or write from this QRhiBuffer within the frame being recorded.
|
||||
|
||||
In some cases a QRhiBuffer will not be backed by a native buffer object at
|
||||
all. In this case slotCount will be set to 0 and no valid native objects
|
||||
are returned. This is not an error, and is perfectly valid when a given
|
||||
backend does not use native buffers for QRhiBuffers with certain types or
|
||||
usages.
|
||||
|
||||
\note Be aware that QRhi backends may employ various buffer update
|
||||
strategies. Unlike textures, where uploading image data always means
|
||||
recording a buffer-to-image (or similar) copy command on the command
|
||||
buffer, buffers, in particular Dynamic and UniformBuffer ones, can operate
|
||||
in many different ways. For example, a QRhiBuffer with usage type
|
||||
UniformBuffer may not even be backed by a native buffer object at all if
|
||||
uniform buffers are not used or supported by a given backend and graphics
|
||||
API. There are also differences to how data is written to the buffer and
|
||||
the type of backing memory used, and, if host visible memory is involved,
|
||||
when memory writes become available and visible. Therefore, in general it
|
||||
is recommended to limit native buffer object access to vertex and index
|
||||
buffers with types Static or Immutable, because these operate in a
|
||||
relatively uniform manner with all backends.
|
||||
|
||||
\sa QRhi::currentFrameSlot(), QRhi::FramesInFlight
|
||||
*/
|
||||
QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QRhiRenderBuffer
|
||||
\internal
|
||||
@ -4334,7 +4422,15 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da
|
||||
is supported only when the QRhi::ReadBackNonUniformBuffer feature is
|
||||
reported as supported.
|
||||
|
||||
\a readBackTexture(), QRhi::isFeatureSupported()
|
||||
\note The asynchronous readback is guaranteed to have completed when one of
|
||||
the following conditions is met: \l{QRhi::finish()}{finish()} has been
|
||||
called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted},
|
||||
including the frame that issued the readback operation, and the
|
||||
\l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c
|
||||
N is the \l{QRhi::resourceLimit()}{resource limit value} returned for
|
||||
QRhi::MaxAsyncReadbackFrames.
|
||||
|
||||
\sa readBackTexture(), QRhi::isFeatureSupported(), QRhi::resourceLimit()
|
||||
*/
|
||||
void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
|
||||
{
|
||||
@ -4425,6 +4521,16 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co
|
||||
happens with a byte ordered format. A \l{QRhiTexture::RGBA8}{RGBA8} texture
|
||||
maps therefore to byte ordered QImage formats, such as,
|
||||
QImage::Format_RGBA8888.
|
||||
|
||||
\note The asynchronous readback is guaranteed to have completed when one of
|
||||
the following conditions is met: \l{QRhi::finish()}{finish()} has been
|
||||
called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted},
|
||||
including the frame that issued the readback operation, and the
|
||||
\l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c
|
||||
N is the \l{QRhi::resourceLimit()}{resource limit value} returned for
|
||||
QRhi::MaxAsyncReadbackFrames.
|
||||
|
||||
\sa readBackBuffer(), QRhi::resourceLimit()
|
||||
*/
|
||||
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
|
||||
{
|
||||
|
@ -681,6 +681,11 @@ public:
|
||||
};
|
||||
Q_DECLARE_FLAGS(UsageFlags, UsageFlag)
|
||||
|
||||
struct NativeBuffer {
|
||||
const void *objects[3];
|
||||
int slotCount;
|
||||
};
|
||||
|
||||
QRhiResource::Type resourceType() const override;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
@ -694,6 +699,8 @@ public:
|
||||
|
||||
virtual bool build() = 0;
|
||||
|
||||
virtual NativeBuffer nativeBuffer();
|
||||
|
||||
protected:
|
||||
QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_);
|
||||
Type m_type;
|
||||
@ -1430,7 +1437,8 @@ public:
|
||||
BaseInstance,
|
||||
TriangleFanTopology,
|
||||
ReadBackNonUniformBuffer,
|
||||
ReadBackNonBaseMipLevel
|
||||
ReadBackNonBaseMipLevel,
|
||||
TexelFetch
|
||||
};
|
||||
|
||||
enum BeginFrameFlag {
|
||||
@ -1447,7 +1455,8 @@ public:
|
||||
TextureSizeMin = 1,
|
||||
TextureSizeMax,
|
||||
MaxColorAttachments,
|
||||
FramesInFlight
|
||||
FramesInFlight,
|
||||
MaxAsyncReadbackFrames
|
||||
};
|
||||
|
||||
~QRhi();
|
||||
|
@ -464,6 +464,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
|
||||
return true;
|
||||
case QRhi::ReadBackNonBaseMipLevel:
|
||||
return true;
|
||||
case QRhi::TexelFetch:
|
||||
return true;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return false;
|
||||
@ -480,7 +482,13 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const
|
||||
case QRhi::MaxColorAttachments:
|
||||
return 8;
|
||||
case QRhi::FramesInFlight:
|
||||
return 2; // dummy
|
||||
// From our perspective. What D3D does internally is another question
|
||||
// (there could be pipelining, helped f.ex. by our MAP_DISCARD based
|
||||
// uniform buffer update strategy), but that's out of our hands and
|
||||
// does not concern us here.
|
||||
return 1;
|
||||
case QRhi::MaxAsyncReadbackFrames:
|
||||
return 1;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
@ -2378,6 +2386,11 @@ bool QD3D11Buffer::build()
|
||||
return true;
|
||||
}
|
||||
|
||||
QRhiBuffer::NativeBuffer QD3D11Buffer::nativeBuffer()
|
||||
{
|
||||
return { { &buffer }, 1 };
|
||||
}
|
||||
|
||||
ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
|
||||
{
|
||||
if (uav)
|
||||
|
@ -64,6 +64,7 @@ struct QD3D11Buffer : public QRhiBuffer
|
||||
~QD3D11Buffer();
|
||||
void release() override;
|
||||
bool build() override;
|
||||
QRhiBuffer::NativeBuffer nativeBuffer() override;
|
||||
|
||||
ID3D11UnorderedAccessView *unorderedAccessView();
|
||||
|
||||
|
@ -512,6 +512,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
|
||||
else
|
||||
caps.nonBaseLevelFramebufferTexture = true;
|
||||
|
||||
caps.texelFetch = caps.ctxMajor >= 3; // 3.0 or ES 3.0
|
||||
|
||||
if (!caps.gles) {
|
||||
f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
f->glEnable(GL_POINT_SPRITE);
|
||||
@ -765,6 +767,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
|
||||
return !caps.gles || caps.properMapBuffer;
|
||||
case QRhi::ReadBackNonBaseMipLevel:
|
||||
return caps.nonBaseLevelFramebufferTexture;
|
||||
case QRhi::TexelFetch:
|
||||
return caps.texelFetch;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return false;
|
||||
@ -781,7 +785,11 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const
|
||||
case QRhi::MaxColorAttachments:
|
||||
return caps.maxDrawBuffers;
|
||||
case QRhi::FramesInFlight:
|
||||
return 2; // dummy
|
||||
// From our perspective. What the GL impl does internally is another
|
||||
// question, but that's out of our hands and does not concern us here.
|
||||
return 1;
|
||||
case QRhi::MaxAsyncReadbackFrames:
|
||||
return 1;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
@ -3293,6 +3301,14 @@ bool QGles2Buffer::build()
|
||||
return true;
|
||||
}
|
||||
|
||||
QRhiBuffer::NativeBuffer QGles2Buffer::nativeBuffer()
|
||||
{
|
||||
if (m_usage.testFlag(QRhiBuffer::UniformBuffer))
|
||||
return { {}, 0 };
|
||||
|
||||
return { { &buffer }, 1 };
|
||||
}
|
||||
|
||||
QGles2RenderBuffer::QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags)
|
||||
|
@ -64,6 +64,7 @@ struct QGles2Buffer : public QRhiBuffer
|
||||
~QGles2Buffer();
|
||||
void release() override;
|
||||
bool build() override;
|
||||
QRhiBuffer::NativeBuffer nativeBuffer() override;
|
||||
|
||||
GLuint buffer = 0;
|
||||
GLenum targetForDataOps;
|
||||
@ -778,7 +779,8 @@ public:
|
||||
compute(false),
|
||||
textureCompareMode(false),
|
||||
properMapBuffer(false),
|
||||
nonBaseLevelFramebufferTexture(false)
|
||||
nonBaseLevelFramebufferTexture(false),
|
||||
texelFetch(false)
|
||||
{ }
|
||||
int ctxMajor;
|
||||
int ctxMinor;
|
||||
@ -811,6 +813,7 @@ public:
|
||||
uint textureCompareMode : 1;
|
||||
uint properMapBuffer : 1;
|
||||
uint nonBaseLevelFramebufferTexture : 1;
|
||||
uint texelFetch : 1;
|
||||
} caps;
|
||||
QGles2SwapChain *currentSwapChain = nullptr;
|
||||
QVector<GLint> supportedCompressedFormats;
|
||||
|
@ -562,6 +562,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
|
||||
return true;
|
||||
case QRhi::ReadBackNonBaseMipLevel:
|
||||
return true;
|
||||
case QRhi::TexelFetch:
|
||||
return true;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return false;
|
||||
@ -579,6 +581,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const
|
||||
return 8;
|
||||
case QRhi::FramesInFlight:
|
||||
return QMTL_FRAMES_IN_FLIGHT;
|
||||
case QRhi::MaxAsyncReadbackFrames:
|
||||
return QMTL_FRAMES_IN_FLIGHT;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
@ -2196,6 +2200,19 @@ bool QMetalBuffer::build()
|
||||
return true;
|
||||
}
|
||||
|
||||
QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer()
|
||||
{
|
||||
if (d->slotted) {
|
||||
NativeBuffer b;
|
||||
Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QMTL_FRAMES_IN_FLIGHT));
|
||||
for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
|
||||
b.objects[i] = &d->buf[i];
|
||||
b.slotCount = QMTL_FRAMES_IN_FLIGHT;
|
||||
return b;
|
||||
}
|
||||
return { { &d->buf[0] }, 1 };
|
||||
}
|
||||
|
||||
QMetalRenderBuffer::QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags),
|
||||
|
@ -65,6 +65,7 @@ struct QMetalBuffer : public QRhiBuffer
|
||||
~QMetalBuffer();
|
||||
void release() override;
|
||||
bool build() override;
|
||||
QRhiBuffer::NativeBuffer nativeBuffer() override;
|
||||
|
||||
QMetalBufferData *d;
|
||||
uint generation = 0;
|
||||
|
@ -146,7 +146,9 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const
|
||||
case QRhi::MaxColorAttachments:
|
||||
return 8;
|
||||
case QRhi::FramesInFlight:
|
||||
return 2; // dummy
|
||||
return 1;
|
||||
case QRhi::MaxAsyncReadbackFrames:
|
||||
return 1;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
|
@ -3990,6 +3990,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
|
||||
return true;
|
||||
case QRhi::ReadBackNonBaseMipLevel:
|
||||
return true;
|
||||
case QRhi::TexelFetch:
|
||||
return true;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return false;
|
||||
@ -4007,6 +4009,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const
|
||||
return int(physDevProperties.limits.maxColorAttachments);
|
||||
case QRhi::FramesInFlight:
|
||||
return QVK_FRAMES_IN_FLIGHT;
|
||||
case QRhi::MaxAsyncReadbackFrames:
|
||||
return QVK_FRAMES_IN_FLIGHT;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
@ -5181,6 +5185,19 @@ bool QVkBuffer::build()
|
||||
return true;
|
||||
}
|
||||
|
||||
QRhiBuffer::NativeBuffer QVkBuffer::nativeBuffer()
|
||||
{
|
||||
if (m_type == Dynamic) {
|
||||
NativeBuffer b;
|
||||
Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QVK_FRAMES_IN_FLIGHT));
|
||||
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
|
||||
b.objects[i] = &buffers[i];
|
||||
b.slotCount = QVK_FRAMES_IN_FLIGHT;
|
||||
return b;
|
||||
}
|
||||
return { { &buffers[0] }, 1 };
|
||||
}
|
||||
|
||||
QVkRenderBuffer::QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
|
||||
int sampleCount, Flags flags)
|
||||
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags)
|
||||
|
@ -76,6 +76,7 @@ struct QVkBuffer : public QRhiBuffer
|
||||
~QVkBuffer();
|
||||
void release() override;
|
||||
bool build() override;
|
||||
QRhiBuffer::NativeBuffer nativeBuffer() override;
|
||||
|
||||
VkBuffer buffers[QVK_FRAMES_IN_FLIGHT];
|
||||
QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT];
|
||||
|
@ -904,6 +904,9 @@ int QTextDocument::lineCount() const
|
||||
|
||||
Returns the number of characters of this document.
|
||||
|
||||
\note As a QTextDocument always contains at least one
|
||||
QChar::ParagraphSeparator, this method will return at least 1.
|
||||
|
||||
\sa blockCount(), characterAt()
|
||||
*/
|
||||
int QTextDocument::characterCount() const
|
||||
|
@ -99,7 +99,7 @@ qtConfig(textodfwriter) {
|
||||
|
||||
qtConfig(textmarkdownreader) {
|
||||
qtConfig(system-textmarkdownreader) {
|
||||
QMAKE_USE += libmd4c
|
||||
QMAKE_USE_PRIVATE += libmd4c
|
||||
} else {
|
||||
include($$PWD/../../3rdparty/md4c.pri)
|
||||
}
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "qshaderlanguage_p.h"
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(ShaderGenerator, "ShaderGenerator", QtWarningMsg)
|
||||
@ -344,10 +346,9 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
code << QByteArrayLiteral("void main()");
|
||||
code << QByteArrayLiteral("{");
|
||||
|
||||
const QRegularExpression localToGlobalRegExp(QStringLiteral("^.*\\s+(\\w+)\\s*=\\s*((?:\\w+\\(.*\\))|(?:\\w+)).*;$"));
|
||||
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("^(.*\\s+(v\\d+))\\s*=\\s*(.*);$"));
|
||||
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("([^;]*\\s+(v\\d+))\\s*=\\s*([^;]*);"));
|
||||
const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
|
||||
const QRegularExpression outputToTemporaryAssignmentRegExp(QStringLiteral("^\\s*(\\w+)\\s*=\\s*(.*);$"));
|
||||
const QRegularExpression statementRegExp(QStringLiteral("\\s*(\\w+)\\s*=\\s*([^;]*);"));
|
||||
|
||||
struct Variable;
|
||||
|
||||
@ -457,6 +458,13 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
QByteArray line = node.rule(format).substitution;
|
||||
const QVector<QShaderNodePort> ports = node.ports();
|
||||
|
||||
struct VariableReplacement {
|
||||
QByteArray placeholder;
|
||||
QByteArray variable;
|
||||
};
|
||||
|
||||
QVector<VariableReplacement> variableReplacements;
|
||||
|
||||
// Generate temporary variable names vN
|
||||
for (const QShaderNodePort &port : ports) {
|
||||
const QString portName = port.name;
|
||||
@ -472,23 +480,65 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
if (variableIndex < 0)
|
||||
continue;
|
||||
|
||||
const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8());
|
||||
const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex));
|
||||
VariableReplacement replacement;
|
||||
replacement.placeholder = QByteArrayLiteral("$") + portName.toUtf8();
|
||||
replacement.variable = QByteArrayLiteral("v") + QByteArray::number(variableIndex);
|
||||
|
||||
line.replace(placeholder, variable);
|
||||
variableReplacements.append(std::move(replacement));
|
||||
}
|
||||
|
||||
int begin = 0;
|
||||
while ((begin = line.indexOf('$', begin)) != -1) {
|
||||
int end = begin + 1;
|
||||
char endChar = line.at(end);
|
||||
const int size = line.size();
|
||||
while (end < size && (std::isalnum(endChar) || endChar == '_')) {
|
||||
++end;
|
||||
endChar = line.at(end);
|
||||
}
|
||||
|
||||
const int placeholderLength = end - begin;
|
||||
|
||||
const QByteArray variableName = line.mid(begin, placeholderLength);
|
||||
const auto replacementIt = std::find_if(variableReplacements.cbegin(), variableReplacements.cend(),
|
||||
[&variableName](const VariableReplacement &replacement) {
|
||||
return variableName == replacement.placeholder;
|
||||
});
|
||||
|
||||
if (replacementIt != variableReplacements.cend()) {
|
||||
line.replace(begin, placeholderLength, replacementIt->variable);
|
||||
begin += replacementIt->variable.length();
|
||||
} else {
|
||||
begin = end;
|
||||
}
|
||||
}
|
||||
|
||||
// Substitute variable names by generated vN variable names
|
||||
const QByteArray substitutionedLine = replaceParameters(line, node, format);
|
||||
|
||||
Variable *v = nullptr;
|
||||
QRegularExpressionMatchIterator matches;
|
||||
|
||||
switch (node.type()) {
|
||||
// Record name of temporary variable that possibly references a global input
|
||||
// We will replace the temporary variables by the matching global variables later
|
||||
case QShaderNode::Input: {
|
||||
const QRegularExpressionMatch match = localToGlobalRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Input:
|
||||
case QShaderNode::Output:
|
||||
matches = statementRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||
break;
|
||||
case QShaderNode::Function:
|
||||
matches = temporaryVariableToAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||
break;
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
while (matches.hasNext()) {
|
||||
QRegularExpressionMatch match = matches.next();
|
||||
|
||||
Variable *v = nullptr;
|
||||
|
||||
switch (node.type()) {
|
||||
// Record name of temporary variable that possibly references a global input
|
||||
// We will replace the temporary variables by the matching global variables later
|
||||
case QShaderNode::Input: {
|
||||
const QString localVariable = match.captured(1);
|
||||
const QString globalVariable = match.captured(2);
|
||||
|
||||
@ -499,13 +549,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
Assignment assignment;
|
||||
assignment.expression = globalVariable;
|
||||
v->assignment = assignment;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QShaderNode::Function: {
|
||||
const QRegularExpressionMatch match = temporaryVariableToAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Function: {
|
||||
const QString localVariableDeclaration = match.captured(1);
|
||||
const QString localVariableName = match.captured(2);
|
||||
const QString assignmentContent = match.captured(3);
|
||||
@ -518,13 +565,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
|
||||
// Find variables that may be referenced in the assignment
|
||||
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QShaderNode::Output: {
|
||||
const QRegularExpressionMatch match = outputToTemporaryAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Output: {
|
||||
const QString outputDeclaration = match.captured(1);
|
||||
const QString assignmentContent = match.captured(2);
|
||||
|
||||
@ -539,17 +583,17 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
|
||||
// Find variables that may be referenced in the assignment
|
||||
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
|
||||
break;
|
||||
}
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
LineContent lineContent;
|
||||
lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
|
||||
lineContent.var = v;
|
||||
lines << lineContent;
|
||||
LineContent lineContent;
|
||||
lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
|
||||
lineContent.var = v;
|
||||
lines << lineContent;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through all lines
|
||||
|
@ -44,13 +44,20 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace
|
||||
{
|
||||
QVector<QShaderNode> copyOutputNodes(const QVector<QShaderNode> &nodes)
|
||||
QVector<QShaderNode> copyOutputNodes(const QVector<QShaderNode> &nodes, const QVector<QShaderGraph::Edge> &edges)
|
||||
{
|
||||
auto res = QVector<QShaderNode>();
|
||||
std::copy_if(nodes.cbegin(), nodes.cend(),
|
||||
std::back_inserter(res),
|
||||
[] (const QShaderNode &node) {
|
||||
return node.type() == QShaderNode::Output;
|
||||
[&edges] (const QShaderNode &node) {
|
||||
return node.type() == QShaderNode::Output ||
|
||||
(node.type() == QShaderNode::Function &&
|
||||
!std::any_of(edges.cbegin(),
|
||||
edges.cend(),
|
||||
[&node] (const QShaderGraph::Edge &edge) {
|
||||
return edge.sourceNodeUuid ==
|
||||
node.uuid();
|
||||
}));
|
||||
});
|
||||
return res;
|
||||
}
|
||||
@ -116,6 +123,50 @@ namespace
|
||||
}
|
||||
return targetStatement;
|
||||
}
|
||||
|
||||
void removeNodesWithUnboundInputs(QVector<QShaderGraph::Statement> &statements,
|
||||
const QVector<QShaderGraph::Edge> &allEdges)
|
||||
{
|
||||
// A node is invalid if any of its input ports is disconected
|
||||
// or connected to the output port of another invalid node.
|
||||
|
||||
// Keeps track of the edges from the nodes we know to be valid
|
||||
// to unvisited nodes
|
||||
auto currentEdges = QVector<QShaderGraph::Edge>();
|
||||
|
||||
statements.erase(std::remove_if(statements.begin(),
|
||||
statements.end(),
|
||||
[¤tEdges, &allEdges] (const QShaderGraph::Statement &statement) {
|
||||
const QShaderNode &node = statement.node;
|
||||
const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, node.uuid());
|
||||
const QVector<QShaderNodePort> ports = node.ports();
|
||||
|
||||
bool allInputsConnected = true;
|
||||
for (const QShaderNodePort &port : node.ports()) {
|
||||
if (port.direction == QShaderNodePort::Output)
|
||||
continue;
|
||||
|
||||
const auto edgeIt = std::find_if(outgoing.cbegin(),
|
||||
outgoing.cend(),
|
||||
[&port] (const QShaderGraph::Edge &edge) {
|
||||
return edge.targetPortName == port.name;
|
||||
});
|
||||
|
||||
if (edgeIt != outgoing.cend())
|
||||
currentEdges.removeAll(*edgeIt);
|
||||
else
|
||||
allInputsConnected = false;
|
||||
}
|
||||
|
||||
if (allInputsConnected) {
|
||||
const QVector<QShaderGraph::Edge> incoming = incomingEdges(allEdges, node.uuid());
|
||||
currentEdges.append(incoming);
|
||||
}
|
||||
|
||||
return !allInputsConnected;
|
||||
}),
|
||||
statements.end());
|
||||
}
|
||||
}
|
||||
|
||||
QUuid QShaderGraph::Statement::uuid() const noexcept
|
||||
@ -210,8 +261,8 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
|
||||
|
||||
auto result = QVector<Statement>();
|
||||
QVector<Edge> currentEdges = enabledEdges;
|
||||
QVector<QUuid> currentUuids = [enabledNodes] {
|
||||
const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes);
|
||||
QVector<QUuid> currentUuids = [enabledNodes, enabledEdges] {
|
||||
const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes, enabledEdges);
|
||||
auto res = QVector<QUuid>();
|
||||
std::transform(inputs.cbegin(), inputs.cend(),
|
||||
std::back_inserter(res),
|
||||
@ -241,6 +292,9 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
|
||||
}
|
||||
|
||||
std::reverse(result.begin(), result.end());
|
||||
|
||||
removeNodesWithUnboundInputs(result, enabledEdges);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1098,6 +1098,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
|
||||
if (reply) {
|
||||
reply->d_func()->errorString = errorString;
|
||||
reply->d_func()->httpErrorCode = errorCode;
|
||||
emit reply->finishedWithError(errorCode, errorString);
|
||||
reply = nullptr;
|
||||
if (protocolHandler)
|
||||
|
@ -158,6 +158,11 @@ QString QHttpNetworkReply::errorString() const
|
||||
return d_func()->errorString;
|
||||
}
|
||||
|
||||
QNetworkReply::NetworkError QHttpNetworkReply::errorCode() const
|
||||
{
|
||||
return d_func()->httpErrorCode;
|
||||
}
|
||||
|
||||
QString QHttpNetworkReply::reasonPhrase() const
|
||||
{
|
||||
return d_func()->reasonPhrase;
|
||||
|
@ -115,6 +115,8 @@ public:
|
||||
QString errorString() const;
|
||||
void setErrorString(const QString &error);
|
||||
|
||||
QNetworkReply::NetworkError errorCode() const;
|
||||
|
||||
QString reasonPhrase() const;
|
||||
|
||||
qint64 bytesAvailable() const;
|
||||
@ -255,6 +257,7 @@ public:
|
||||
qint64 removedContentLength;
|
||||
QPointer<QHttpNetworkConnection> connection;
|
||||
QPointer<QHttpNetworkConnectionChannel> connectionChannel;
|
||||
QNetworkReply::NetworkError httpErrorCode = QNetworkReply::NoError;
|
||||
|
||||
bool autoDecompress;
|
||||
|
||||
|
@ -417,6 +417,12 @@ void QHttpThreadDelegate::startRequest()
|
||||
|
||||
connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
|
||||
this, SLOT(cacheCredentialsSlot(QHttpNetworkRequest,QAuthenticator*)));
|
||||
if (httpReply->errorCode() != QNetworkReply::NoError) {
|
||||
if (synchronous)
|
||||
synchronousFinishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
|
||||
else
|
||||
finishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
|
||||
}
|
||||
}
|
||||
|
||||
// This gets called from the user thread or by the synchronous HTTP timeout timer
|
||||
|
@ -220,27 +220,6 @@ static void ensureInitialized()
|
||||
can be:
|
||||
\snippet code/src_network_access_qnetworkaccessmanager.cpp 1
|
||||
|
||||
\section1 Network and Roaming Support
|
||||
|
||||
With the addition of the \l {Bearer Management} API to Qt 4.7
|
||||
QNetworkAccessManager gained the ability to manage network connections.
|
||||
QNetworkAccessManager can start the network interface if the device is
|
||||
offline and terminates the interface if the current process is the last
|
||||
one to use the uplink. Note that some platforms utilize grace periods from
|
||||
when the last application stops using a uplink until the system actually
|
||||
terminates the connectivity link. Roaming is equally transparent. Any
|
||||
queued/pending network requests are automatically transferred to the new
|
||||
access point.
|
||||
|
||||
Clients wanting to utilize this feature should not require any changes. In fact
|
||||
it is likely that existing platform specific connection code can simply be
|
||||
removed from the application.
|
||||
|
||||
\note The network and roaming support in QNetworkAccessManager is conditional
|
||||
upon the platform supporting connection management. The
|
||||
\l QNetworkConfigurationManager::NetworkSessionRequired can be used to
|
||||
detect whether QNetworkAccessManager utilizes this feature.
|
||||
|
||||
\sa QNetworkRequest, QNetworkReply, QNetworkProxy
|
||||
*/
|
||||
|
||||
@ -1475,7 +1454,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
|
||||
// immediately set 'networkAccessible' even before we start
|
||||
// the monitor.
|
||||
#ifdef QT_NO_BEARERMANAGEMENT
|
||||
if (d->networkAccessible
|
||||
if (!d->networkAccessible
|
||||
#else
|
||||
if (d->networkAccessible == NotAccessible
|
||||
#endif // QT_NO_BEARERMANAGEMENT
|
||||
|
@ -170,7 +170,7 @@ public:
|
||||
void setAutoDeleteReplies(bool autoDelete);
|
||||
|
||||
int transferTimeout() const;
|
||||
void setTransferTimeout(int timeout = QNetworkRequest::TransferTimeoutPreset);
|
||||
void setTransferTimeout(int timeout = QNetworkRequest::DefaultTransferTimeoutConstant);
|
||||
|
||||
Q_SIGNALS:
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
|
@ -414,9 +414,9 @@ QT_BEGIN_NAMESPACE
|
||||
A constant that can be used for enabling transfer
|
||||
timeouts with a preset value.
|
||||
|
||||
\value TransferTimeoutPreset The transfer timeout in milliseconds.
|
||||
Used if setTimeout() is called
|
||||
without an argument.
|
||||
\value DefaultTransferTimeoutConstant The transfer timeout in milliseconds.
|
||||
Used if setTimeout() is called
|
||||
without an argument.
|
||||
*/
|
||||
|
||||
class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
};
|
||||
|
||||
enum TransferTimeoutConstant {
|
||||
TransferTimeoutPreset = 30000
|
||||
DefaultTransferTimeoutConstant = 30000
|
||||
};
|
||||
|
||||
QNetworkRequest();
|
||||
@ -182,7 +182,7 @@ public:
|
||||
void setHttp2Configuration(const QHttp2Configuration &configuration);
|
||||
|
||||
int transferTimeout() const;
|
||||
void setTransferTimeout(int timeout = TransferTimeoutPreset);
|
||||
void setTransferTimeout(int timeout = DefaultTransferTimeoutConstant);
|
||||
#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
|
||||
private:
|
||||
QSharedDataPointer<QNetworkRequestPrivate> d;
|
||||
|
@ -261,29 +261,4 @@
|
||||
by passing a factory to QNetworkProxyFactory::setApplicationProxyFactory()
|
||||
and a custom proxying policy can be created by subclassing
|
||||
QNetworkProxyFactory; see the class documentation for details.
|
||||
|
||||
\section1 Bearer Management Support
|
||||
|
||||
Bearer Management controls the connectivity state of the device such that
|
||||
the application can start or stop network interfaces and roam
|
||||
transparently between access points.
|
||||
|
||||
The QNetworkConfigurationManager class manages the list of network
|
||||
configurations known to the device. A network configuration describes the
|
||||
set of parameters used to start a network interface and is represented by
|
||||
the QNetworkConfiguration class.
|
||||
|
||||
A network interface is started by openning a QNetworkSession based on a
|
||||
given network configuration. In most situations creating a network session
|
||||
based on the platform specified default network configuration is
|
||||
appropriate. The default network configuration is returned by the
|
||||
QNetworkConfigurationManager::defaultConfiguration() function.
|
||||
|
||||
On some platforms it is a platform requirement that the application open a
|
||||
network session before any network operations can be performed. This can be
|
||||
tested by the presents of the
|
||||
QNetworkConfigurationManager::NetworkSessionRequired flag in the value
|
||||
returned by the QNetworkConfigurationManager::capabilities() function.
|
||||
|
||||
\sa {Bearer Management}
|
||||
*/
|
||||
|
@ -54,7 +54,6 @@
|
||||
applications with networking capabilities.
|
||||
\list
|
||||
\li \l{Network Programming with Qt} - Programming applications with networking capabilities
|
||||
\li \l{Bearer Management} - An API to control the system's connectivity state
|
||||
\li \l{Secure Sockets Layer (SSL) Classes} - Classes for secure communication over network sockets
|
||||
\endlist
|
||||
|
||||
|
@ -163,11 +163,14 @@ private:
|
||||
ComPtr<QNetworkConnectionEvents> connectionEvents;
|
||||
// We can assume we have access to internet/subnet when this class is created because
|
||||
// connection has already been established to the peer:
|
||||
NLM_CONNECTIVITY connectivity =
|
||||
NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
|
||||
| NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET);
|
||||
NLM_CONNECTIVITY connectivity = NLM_CONNECTIVITY(
|
||||
NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
|
||||
| NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET
|
||||
| NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK
|
||||
| NLM_CONNECTIVITY_IPV4_NOTRAFFIC | NLM_CONNECTIVITY_IPV6_NOTRAFFIC);
|
||||
|
||||
bool sameSubnet = false;
|
||||
bool isLinkLocal = false;
|
||||
bool monitoring = false;
|
||||
bool comInitFailed = false;
|
||||
bool remoteIsIPv6 = false;
|
||||
@ -370,6 +373,7 @@ bool QNetworkConnectionMonitorPrivate::setTargets(const QHostAddress &local,
|
||||
return false;
|
||||
}
|
||||
sameSubnet = remote.isInSubnet(local, it->prefixLength());
|
||||
isLinkLocal = remote.isLinkLocal() && local.isLinkLocal();
|
||||
remoteIsIPv6 = remote.protocol() == QAbstractSocket::IPv6Protocol;
|
||||
|
||||
return connectionEvents->setTarget(iface);
|
||||
@ -461,9 +465,28 @@ void QNetworkConnectionMonitor::stopMonitoring()
|
||||
bool QNetworkConnectionMonitor::isReachable()
|
||||
{
|
||||
Q_D(QNetworkConnectionMonitor);
|
||||
NLM_CONNECTIVITY required = d->sameSubnet
|
||||
? (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_SUBNET : NLM_CONNECTIVITY_IPV4_SUBNET)
|
||||
: (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_INTERNET : NLM_CONNECTIVITY_IPV4_INTERNET);
|
||||
|
||||
const NLM_CONNECTIVITY RequiredSameSubnetIPv6 =
|
||||
NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV6_SUBNET | NLM_CONNECTIVITY_IPV6_LOCALNETWORK
|
||||
| NLM_CONNECTIVITY_IPV6_INTERNET);
|
||||
const NLM_CONNECTIVITY RequiredSameSubnetIPv4 =
|
||||
NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV4_LOCALNETWORK
|
||||
| NLM_CONNECTIVITY_IPV4_INTERNET);
|
||||
|
||||
NLM_CONNECTIVITY required;
|
||||
if (d->isLinkLocal) {
|
||||
required = NLM_CONNECTIVITY(
|
||||
d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_NOTRAFFIC | RequiredSameSubnetIPv6
|
||||
: NLM_CONNECTIVITY_IPV4_NOTRAFFIC | RequiredSameSubnetIPv4);
|
||||
} else if (d->sameSubnet) {
|
||||
required =
|
||||
NLM_CONNECTIVITY(d->remoteIsIPv6 ? RequiredSameSubnetIPv6 : RequiredSameSubnetIPv4);
|
||||
|
||||
} else {
|
||||
required = NLM_CONNECTIVITY(d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_INTERNET
|
||||
: NLM_CONNECTIVITY_IPV4_INTERNET);
|
||||
}
|
||||
|
||||
return d_func()->connectivity & required;
|
||||
}
|
||||
|
||||
@ -695,7 +718,8 @@ bool QNetworkStatusMonitor::isNetworkAccessible()
|
||||
{
|
||||
return d_func()->connectivity
|
||||
& (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
|
||||
| NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET);
|
||||
| NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET
|
||||
| NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK);
|
||||
}
|
||||
|
||||
bool QNetworkStatusMonitor::isEnabled()
|
||||
|
@ -1465,13 +1465,8 @@ QAbstractSocket::QAbstractSocket(SocketType socketType,
|
||||
\sa socketType(), QTcpSocket, QUdpSocket
|
||||
*/
|
||||
QAbstractSocket::QAbstractSocket(SocketType socketType, QObject *parent)
|
||||
: QIODevice(*new QAbstractSocketPrivate, parent)
|
||||
: QAbstractSocket(socketType, *new QAbstractSocketPrivate, parent)
|
||||
{
|
||||
Q_D(QAbstractSocket);
|
||||
#if defined(QABSTRACTSOCKET_DEBUG)
|
||||
qDebug("QAbstractSocket::QAbstractSocket(%p)", parent);
|
||||
#endif
|
||||
d->socketType = socketType;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
On Windows this is a named pipe and on Unix this is a local domain socket.
|
||||
|
||||
If an error occurs, socketError() returns the type of error, and
|
||||
If an error occurs, error() returns the type of error, and
|
||||
errorString() can be called to get a human readable description
|
||||
of what happened.
|
||||
|
||||
|
@ -590,7 +590,8 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
|
||||
// local address of the socket which bound on both IPv4 and IPv6 interfaces.
|
||||
// This address does not match to any special address and should not be used
|
||||
// to send the data. So, replace it with QHostAddress::Any.
|
||||
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
|
||||
const uchar ipv6MappedNet[] = {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
|
||||
if (localAddress.isInSubnet(QHostAddress(ipv6MappedNet), 128 - 32)) {
|
||||
bool ok = false;
|
||||
const quint32 localIPv4 = localAddress.toIPv4Address(&ok);
|
||||
if (ok && localIPv4 == INADDR_ANY) {
|
||||
|
@ -219,5 +219,6 @@
|
||||
#define UIA_CenterPointPropertyId 30165
|
||||
#define UIA_RotationPropertyId 30166
|
||||
#define UIA_SizePropertyId 30167
|
||||
#define UIA_IsDialogPropertyId 30174
|
||||
|
||||
#endif
|
||||
|
@ -383,4 +383,21 @@ __CRT_UUID_DECL(IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __IExpandCollapseProvider_INTERFACE_DEFINED__
|
||||
#define __IExpandCollapseProvider_INTERFACE_DEFINED__
|
||||
DEFINE_GUID(IID_IExpandCollapseProvider, 0xd847d3a5, 0xcab0, 0x4a98, 0x8c,0x32, 0xec,0xb4,0x5c,0x59,0xad,0x24);
|
||||
MIDL_INTERFACE("d847d3a5-cab0-4a98-8c32-ecb45c59ad24")
|
||||
IExpandCollapseProvider : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE Expand() = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE Collapse() = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE get_ExpandCollapseState(__RPC__out enum ExpandCollapseState *pRetVal) = 0;
|
||||
};
|
||||
#ifdef __CRT_UUID_DECL
|
||||
__CRT_UUID_DECL(IExpandCollapseProvider, 0xd847d3a5, 0xcab0, 0x4a98, 0x8c,0x32, 0xec,0xb4,0x5c,0x59,0xad,0x24)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -155,6 +155,13 @@ enum WindowInteractionState {
|
||||
WindowInteractionState_NotResponding = 4
|
||||
};
|
||||
|
||||
enum ExpandCollapseState {
|
||||
ExpandCollapseState_Collapsed = 0,
|
||||
ExpandCollapseState_Expanded = 1,
|
||||
ExpandCollapseState_PartiallyExpanded = 2,
|
||||
ExpandCollapseState_LeafNode = 3
|
||||
};
|
||||
|
||||
struct UiaRect {
|
||||
double left;
|
||||
double top;
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "qandroidplatformfiledialoghelper.h"
|
||||
|
||||
#include <androidjnimain.h>
|
||||
#include <private/qjni_p.h>
|
||||
#include <jni.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -50,9 +49,11 @@ namespace QtAndroidFileDialogHelper {
|
||||
#define RESULT_OK -1
|
||||
#define REQUEST_CODE 1305 // Arbitrary
|
||||
|
||||
const char JniIntentClass[] = "android/content/Intent";
|
||||
|
||||
QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper()
|
||||
: QPlatformFileDialogHelper()
|
||||
, m_selectedFile()
|
||||
: QPlatformFileDialogHelper(),
|
||||
m_activity(QtAndroid::activity())
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,48 +62,155 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
|
||||
if (requestCode != REQUEST_CODE)
|
||||
return false;
|
||||
|
||||
if (resultCode == RESULT_OK) {
|
||||
const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
|
||||
const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
|
||||
const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString();
|
||||
m_selectedFile = QUrl(uriStr);
|
||||
Q_EMIT fileSelected(m_selectedFile);
|
||||
Q_EMIT accept();
|
||||
} else {
|
||||
if (resultCode != RESULT_OK) {
|
||||
Q_EMIT reject();
|
||||
return true;
|
||||
}
|
||||
|
||||
const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
|
||||
|
||||
const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
|
||||
if (uri.isValid()) {
|
||||
takePersistableUriPermission(uri);
|
||||
m_selectedFile.append(QUrl(uri.toString()));
|
||||
Q_EMIT fileSelected(m_selectedFile.first());
|
||||
Q_EMIT accept();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const QJNIObjectPrivate uriClipData =
|
||||
intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
|
||||
if (uriClipData.isValid()) {
|
||||
const int size = uriClipData.callMethod<jint>("getItemCount");
|
||||
for (int i = 0; i < size; ++i) {
|
||||
QJNIObjectPrivate item = uriClipData.callObjectMethod(
|
||||
"getItemAt", "(I)Landroid/content/ClipData$Item;", i);
|
||||
|
||||
QJNIObjectPrivate itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;");
|
||||
takePersistableUriPermission(itemUri);
|
||||
m_selectedFile.append(itemUri.toString());
|
||||
Q_EMIT filesSelected(m_selectedFile);
|
||||
Q_EMIT accept();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIObjectPrivate &uri)
|
||||
{
|
||||
int modeFlags = QJNIObjectPrivate::getStaticField<jint>(
|
||||
JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION");
|
||||
|
||||
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
|
||||
modeFlags |= QJNIObjectPrivate::getStaticField<jint>(
|
||||
JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
|
||||
}
|
||||
|
||||
QJNIObjectPrivate contentResolver = m_activity.callObjectMethod(
|
||||
"getContentResolver", "()Landroid/content/ContentResolver;");
|
||||
contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
|
||||
uri.object(), modeFlags);
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setLocalFilesOnly(bool localOnly)
|
||||
{
|
||||
const QJNIObjectPrivate extraLocalOnly = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, "EXTRA_LOCAL_ONLY", "Ljava/lang/String;");
|
||||
m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
|
||||
extraLocalOnly.object(), localOnly);
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
|
||||
{
|
||||
const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
|
||||
m_intent.callObjectMethod("putExtra",
|
||||
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
|
||||
extraTitle.object(), QJNIObjectPrivate::fromString(title).object());
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setOpenableCategory()
|
||||
{
|
||||
const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
|
||||
m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
|
||||
CATEGORY_OPENABLE.object());
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
|
||||
{
|
||||
const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
|
||||
m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
|
||||
allowMultipleSelections.object(), allowMultiple);
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setMimeTypes()
|
||||
{
|
||||
m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
|
||||
QJNIObjectPrivate::fromString("*/*").object());
|
||||
|
||||
const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
|
||||
for (const QString &type : options()->mimeTypeFilters()) {
|
||||
m_intent.callObjectMethod(
|
||||
"putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
|
||||
extraMimeType.object(), QJNIObjectPrivate::fromString(type).object());
|
||||
}
|
||||
}
|
||||
|
||||
QJNIObjectPrivate QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType)
|
||||
{
|
||||
const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField(
|
||||
JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;");
|
||||
return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V",
|
||||
ACTION_OPEN_DOCUMENT.object());
|
||||
}
|
||||
|
||||
bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
|
||||
{
|
||||
Q_UNUSED(windowFlags)
|
||||
Q_UNUSED(windowModality)
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile)
|
||||
return false;
|
||||
bool isDirDialog = false;
|
||||
|
||||
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
|
||||
m_intent = getFileDialogIntent("ACTION_CREATE_DOCUMENT");
|
||||
} else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) {
|
||||
switch (options()->fileMode()) {
|
||||
case QFileDialogOptions::FileMode::DirectoryOnly:
|
||||
case QFileDialogOptions::FileMode::Directory:
|
||||
m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT_TREE");
|
||||
isDirDialog = true;
|
||||
break;
|
||||
case QFileDialogOptions::FileMode::ExistingFiles:
|
||||
m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
|
||||
setAllowMultipleSelections(true);
|
||||
break;
|
||||
case QFileDialogOptions::FileMode::AnyFile:
|
||||
case QFileDialogOptions::FileMode::ExistingFile:
|
||||
m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDirDialog) {
|
||||
setOpenableCategory();
|
||||
setMimeTypes();
|
||||
}
|
||||
|
||||
setIntentTitle(options()->windowTitle());
|
||||
setLocalFilesOnly(true);
|
||||
|
||||
QtAndroidPrivate::registerActivityResultListener(this);
|
||||
|
||||
const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;");
|
||||
QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object());
|
||||
const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;");
|
||||
intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object());
|
||||
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object());
|
||||
|
||||
const QJNIObjectPrivate activity(QtAndroid::activity());
|
||||
activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE);
|
||||
|
||||
m_activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V",
|
||||
m_intent.object(), REQUEST_CODE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::exec()
|
||||
{
|
||||
m_eventLoop.exec(QEventLoop::DialogExec);
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::hide()
|
||||
{
|
||||
if (m_eventLoop.isRunning())
|
||||
@ -110,43 +218,9 @@ void QAndroidPlatformFileDialogHelper::hide()
|
||||
QtAndroidPrivate::unregisterActivityResultListener(this);
|
||||
}
|
||||
|
||||
QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const
|
||||
void QAndroidPlatformFileDialogHelper::exec()
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter)
|
||||
{
|
||||
Q_UNUSED(filter)
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setFilter()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const
|
||||
{
|
||||
return {m_selectedFile};
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file)
|
||||
{
|
||||
Q_UNUSED(file)
|
||||
}
|
||||
|
||||
QUrl QAndroidPlatformFileDialogHelper::directory() const
|
||||
{
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory)
|
||||
{
|
||||
Q_UNUSED(directory)
|
||||
}
|
||||
|
||||
bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const
|
||||
{
|
||||
return false;
|
||||
m_eventLoop.exec(QEventLoop::DialogExec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include <QEventLoop>
|
||||
#include <qpa/qplatformdialoghelper.h>
|
||||
#include <QtCore/private/qjnihelpers_p.h>
|
||||
#include <private/qjni_p.h>
|
||||
#include <QEventLoop>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -55,26 +57,34 @@ class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public
|
||||
|
||||
public:
|
||||
QAndroidPlatformFileDialogHelper();
|
||||
void exec() override;
|
||||
|
||||
bool show(Qt::WindowFlags windowFlags,
|
||||
Qt::WindowModality windowModality,
|
||||
QWindow *parent) override;
|
||||
void exec() override;
|
||||
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
|
||||
void hide() override;
|
||||
|
||||
QString selectedNameFilter() const override;
|
||||
void selectNameFilter(const QString &filter) override;
|
||||
void setFilter() override;
|
||||
QList<QUrl> selectedFiles() const override;
|
||||
void selectFile(const QUrl &file) override;
|
||||
QUrl directory() const override;
|
||||
void setDirectory(const QUrl &directory) override;
|
||||
bool defaultNameFilterDisables() const override;
|
||||
QString selectedNameFilter() const override { return QString(); };
|
||||
void selectNameFilter(const QString &filter) override { Q_UNUSED(filter) };
|
||||
void setFilter() override {};
|
||||
QList<QUrl> selectedFiles() const override { return m_selectedFile; };
|
||||
void selectFile(const QUrl &file) override { Q_UNUSED(file) };
|
||||
QUrl directory() const override { return QUrl(); };
|
||||
void setDirectory(const QUrl &directory) override { Q_UNUSED(directory) };
|
||||
bool defaultNameFilterDisables() const override { return false; };
|
||||
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
|
||||
|
||||
private:
|
||||
QJNIObjectPrivate getFileDialogIntent(const QString &intentType);
|
||||
void takePersistableUriPermission(const QJNIObjectPrivate &uri);
|
||||
void setLocalFilesOnly(bool localOnly);
|
||||
void setIntentTitle(const QString &title);
|
||||
void setOpenableCategory();
|
||||
void setAllowMultipleSelections(bool allowMultiple);
|
||||
void setMimeTypes();
|
||||
|
||||
QEventLoop m_eventLoop;
|
||||
QUrl m_selectedFile;
|
||||
QList<QUrl> m_selectedFile;
|
||||
QJNIObjectPrivate m_intent;
|
||||
const QJNIObjectPrivate m_activity;
|
||||
};
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user