From 151061ad4af9d1b844f0b029b4e84a3577487048 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 3 Oct 2014 19:30:04 +1000 Subject: update QtBearer NetworkManager backend API Task-number: QTBUG-41747 Change-Id: Idb4afea0215b94957a11895c7db97a72ae680804 Reviewed-by: Lorn Potter --- src/network/doc/src/bearermanagement.qdoc | 2 +- .../networkmanager/qnetworkmanagerengine.cpp | 124 ++++++++++----------- .../bearer/networkmanager/qnetworkmanagerengine.h | 3 +- .../networkmanager/qnetworkmanagerservice.cpp | 30 ++--- .../bearer/networkmanager/qnetworkmanagerservice.h | 6 +- 5 files changed, 80 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/network/doc/src/bearermanagement.qdoc b/src/network/doc/src/bearermanagement.qdoc index 63022b6a6f..cec08491d6 100644 --- a/src/network/doc/src/bearermanagement.qdoc +++ b/src/network/doc/src/bearermanagement.qdoc @@ -248,7 +248,7 @@ determining the feature support: \li Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager} and \l {http://connman.net/}{ConnMan} / \l {http://ofono.org/}{oFono} APIs which support interface notifications and starting and stopping of network - interfaces. + interfaces. Network Manager version 0.9 and above is supported. \row \li Windows\unicode{0xAE} XP \li This platform supports interface notifications without active polling. diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 08a0bb4c63..105531c7f1 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -56,8 +56,8 @@ QT_BEGIN_NAMESPACE QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) : QBearerEngineImpl(parent), interface(new QNetworkManagerInterface(this)), - systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE_SYSTEM_SETTINGS, this)), - userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE_USER_SETTINGS, this)) + systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)), + userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)) { if (!interface->isValid()) return; @@ -107,27 +107,33 @@ void QNetworkManagerEngine::initialize() } // Get connections. + foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) { locker.unlock(); - newConnection(settingsPath, systemSettings); + if (!hasIdentifier(settingsPath.path())) + newConnection(settingsPath, systemSettings); locker.relock(); } + foreach (const QDBusObjectPath &settingsPath, userSettings->listConnections()) { locker.unlock(); - newConnection(settingsPath, userSettings); + if (!hasIdentifier(settingsPath.path())) + newConnection(settingsPath, userSettings); locker.relock(); } // Get active connections. foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { QNetworkManagerConnectionActive *activeConnection = - new QNetworkManagerConnectionActive(acPath.path()); + new QNetworkManagerConnectionActive(acPath.path(),this); + activeConnections.insert(acPath.path(), activeConnection); activeConnection->setConnections(); connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap)), this, SLOT(activeConnectionPropertiesChanged(QString,QMap))); } + Q_EMIT updateCompleted(); } bool QNetworkManagerEngine::networkManagerAvailable() const @@ -144,8 +150,7 @@ QString QNetworkManagerEngine::getInterfaceFromId(const QString &id) foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); - const QString identifier = QString::number(qHash(activeConnection.serviceName() + ' ' + - activeConnection.connection().path())); + const QString identifier = activeConnection.connection().path(); if (id == identifier) { QList devices = activeConnection.devices(); @@ -161,24 +166,11 @@ QString QNetworkManagerEngine::getInterfaceFromId(const QString &id) return QString(); } + bool QNetworkManagerEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); - - if (connectionFromId(id)) - return true; - - for (int i = 0; i < accessPoints.count(); ++i) { - QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i); - - const QString identifier = - QString::number(qHash(accessPoint->connectionInterface()->path())); - - if (id == identifier) - return true; - } - - return false; + return accessPointConfigurations.contains(id); } void QNetworkManagerEngine::connectToId(const QString &id) @@ -214,20 +206,31 @@ void QNetworkManagerEngine::connectToId(const QString &id) const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); + QString specificPath = configuredAccessPoints.key(settingsPath); + + if (specificPath.isEmpty()) + specificPath = "/"; interface->activateConnection(service, QDBusObjectPath(settingsPath), - QDBusObjectPath(dbusDevicePath), QDBusObjectPath("/")); + QDBusObjectPath(dbusDevicePath), QDBusObjectPath(specificPath)); } void QNetworkManagerEngine::disconnectFromId(const QString &id) { QMutexLocker locker(&mutex); + QNetworkManagerSettingsConnection *connection = connectionFromId(id); + QNmSettingsMap map = connection->getSettings(); + bool connectionAutoconnect = map.value("connection").value("autoconnect",true).toBool(); //if not present is true !! + if (connectionAutoconnect) { //autoconnect connections will simply be reconnected by nm + emit connectionError(id, QBearerEngineImpl::OperationNotSupported); + return; + } + foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); - const QString identifier = QString::number(qHash(activeConnection.serviceName() + ' ' + - activeConnection.connection().path())); + const QString identifier = activeConnection.connection().path(); if (id == identifier && accessPointConfigurations.contains(id)) { interface->deactivateConnection(acPath); @@ -244,9 +247,8 @@ void QNetworkManagerEngine::requestUpdate() void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, const QMap &properties) { - QMutexLocker locker(&mutex); - Q_UNUSED(path) + QMutexLocker locker(&mutex); QMapIterator i(properties); while (i.hasNext()) { @@ -269,7 +271,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, QNetworkManagerConnectionActive *activeConnection = this->activeConnections.value(acPath.path()); if (!activeConnection) { - activeConnection = new QNetworkManagerConnectionActive(acPath.path()); + activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this); this->activeConnections.insert(acPath.path(), activeConnection); activeConnection->setConnections(); @@ -277,8 +279,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, this, SLOT(activeConnectionPropertiesChanged(QString,QMap))); } - const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' + - activeConnection->connection().path())); + const QString id = activeConnection->connection().path(); identifiers.removeOne(id); @@ -335,8 +336,7 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat if (!activeConnection) return; - const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' + - activeConnection->connection().path())); + const QString id = activeConnection->connection().path(); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { @@ -367,7 +367,7 @@ void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) QNetworkManagerInterfaceDevice device(path.path()); if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS) { QNetworkManagerInterfaceDeviceWireless *wirelessDevice = - new QNetworkManagerInterfaceDeviceWireless(device.connectionInterface()->path()); + new QNetworkManagerInterfaceDeviceWireless(device.connectionInterface()->path(),this); wirelessDevice->setConnections(); connect(wirelessDevice, SIGNAL(accessPointAdded(QString,QDBusObjectPath)), @@ -377,8 +377,9 @@ void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) connect(wirelessDevice, SIGNAL(propertiesChanged(QString,QMap)), this, SLOT(devicePropertiesChanged(QString,QMap))); - foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) + foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) { newAccessPoint(QString(), apPath); + } mutex.lock(); wirelessDevices.insert(path.path(), wirelessDevice); @@ -406,7 +407,7 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, QNetworkManagerSettingsConnection *connection = new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(), - path.path()); + path.path(),this); connections.append(connection); connect(connection, SIGNAL(removed(QString)), this, SLOT(removeConnection(QString))); @@ -423,14 +424,13 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); - if (activeConnection.serviceName() == service && + if (activeConnection.defaultRoute() && activeConnection.connection().path() == settingsPath && activeConnection.state() == 2) { cpPriv->state |= QNetworkConfiguration::Active; break; } } - QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); @@ -451,8 +451,7 @@ void QNetworkManagerEngine::removeConnection(const QString &path) connections.removeAll(connection); - const QString id = QString::number(qHash(connection->connectionInterface()->service() + ' ' + - connection->connectionInterface()->path())); + const QString id = connection->connectionInterface()->path(); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id); @@ -480,8 +479,7 @@ void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); - if (activeConnection.serviceName() == service && - activeConnection.connection().path() == settingsPath && + if (activeConnection.connection().path() == settingsPath && activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { cpPriv->state |= QNetworkConfiguration::Active; break; @@ -508,14 +506,15 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) { QMutexLocker locker(&mutex); + watcher->deleteLater(); + QDBusPendingReply reply(*watcher); if (!reply.isError()) { QDBusObjectPath result = reply.value(); QNetworkManagerConnectionActive activeConnection(result.path()); - const QString id = QString::number(qHash(activeConnection.serviceName() + ' ' + - activeConnection.connection().path())); + const QString id = activeConnection.connection().path(); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { @@ -542,7 +541,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec Q_UNUSED(path) QNetworkManagerInterfaceAccessPoint *accessPoint = - new QNetworkManagerInterfaceAccessPoint(objectPath.path()); + new QNetworkManagerInterfaceAccessPoint(objectPath.path(),this); accessPoints.append(accessPoint); accessPoint->setConnections(); @@ -565,7 +564,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec if (accessPoint->ssid() == connection->getSsid()) { const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); - const QString connectionId = QString::number(qHash(service + ' ' + settingsPath)); + const QString connectionId = settingsPath; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); @@ -585,7 +584,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec ptr->name = accessPoint->ssid(); ptr->isValid = true; - ptr->id = QString::number(qHash(objectPath.path())); + ptr->id = objectPath.path(); ptr->type = QNetworkConfiguration::InternetAccessPoint; if(accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) { ptr->purpose = QNetworkConfiguration::PrivatePurpose; @@ -614,17 +613,16 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, if (accessPoint->connectionInterface()->path() == objectPath.path()) { accessPoints.removeOne(accessPoint); - if (configuredAccessPoints.contains(accessPoint)) { + if (configuredAccessPoints.contains(accessPoint->connectionInterface()->path())) { // find connection and change state to Defined - configuredAccessPoints.removeOne(accessPoint); + configuredAccessPoints.remove(accessPoint->connectionInterface()->path()); for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); if (accessPoint->ssid() == connection->getSsid()) { const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); - const QString connectionId = - QString::number(qHash(service + ' ' + settingsPath)); + const QString connectionId = settingsPath; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); @@ -640,7 +638,7 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, } } else { QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.take(QString::number(qHash(objectPath.path()))); + accessPointConfigurations.take(objectPath.path()); if (ptr) { locker.unlock(); @@ -673,7 +671,7 @@ void QNetworkManagerEngine::updateAccessPoint(const QMap &map if (accessPoint->ssid() == connection->getSsid()) { const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); - const QString connectionId = QString::number(qHash(service + ' ' + settingsPath)); + const QString connectionId = settingsPath; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); @@ -692,10 +690,12 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri const QString &settingsPath, const QNmSettingsMap &map) { + Q_UNUSED(service); QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; cpPriv->name = map.value("connection").value("id").toString(); + cpPriv->isValid = true; - cpPriv->id = QString::number(qHash(service + ' ' + settingsPath)); + cpPriv->id = settingsPath; cpPriv->type = QNetworkConfiguration::InternetAccessPoint; cpPriv->purpose = QNetworkConfiguration::PublicPurpose; @@ -730,13 +730,13 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri cpPriv->purpose = QNetworkConfiguration::PublicPurpose; } for (int i = 0; i < accessPoints.count(); ++i) { - if (connectionSsid == accessPoints.at(i)->ssid()) { + if (connectionSsid == accessPoints.at(i)->ssid() + && map.value("802-11-wireless").value("seen-bssids").toStringList().contains(accessPoints.at(i)->hwAddress())) { cpPriv->state |= QNetworkConfiguration::Discovered; - if (!configuredAccessPoints.contains(accessPoints.at(i))) { - configuredAccessPoints.append(accessPoints.at(i)); + if (!configuredAccessPoints.contains(accessPoints.at(i)->connectionInterface()->path())) { + configuredAccessPoints.insert(accessPoints.at(i)->connectionInterface()->path(),settingsPath); - const QString accessPointId = - QString::number(qHash(accessPoints.at(i)->connectionInterface()->path())); + const QString accessPointId = accessPoints.at(i)->connectionInterface()->path(); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(accessPointId); @@ -765,7 +765,7 @@ QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); - const QString identifier = QString::number(qHash(service + ' ' + settingsPath)); + const QString identifier = settingsPath; if (id == identifier) return connection; @@ -789,8 +789,7 @@ QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &i foreach (const QString &acPath, activeConnections.keys()) { QNetworkManagerConnectionActive *activeConnection = activeConnections.value(acPath); - const QString identifier = QString::number(qHash(activeConnection->serviceName() + ' ' + - activeConnection->connection().path())); + const QString identifier = activeConnection->connection().path(); if (id == identifier) { switch (activeConnection->state()) { @@ -884,7 +883,8 @@ quint64 QNetworkManagerEngine::startTime(const QString &id) QNetworkConfigurationManager::Capabilities QNetworkManagerEngine::capabilities() const { return QNetworkConfigurationManager::ForcedRoaming | - QNetworkConfigurationManager::CanStartAndStopInterfaces; + QNetworkConfigurationManager::DataStatistics | + QNetworkConfigurationManager::CanStartAndStopInterfaces; } QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend() diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index 19a569d01e..c8bdfe3400 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -122,7 +122,8 @@ private: QHash activeConnections; QList connections; QList accessPoints; - QList configuredAccessPoints; + + QMap configuredAccessPoints; //ap, settings path }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index d249d85c4d..a7d1289b38 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -97,21 +97,21 @@ bool QNetworkManagerInterface::setConnections() QDBusConnection dbusConnection = QDBusConnection::systemBus(); bool allOk = false; - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("PropertiesChanged"), nmDBusHelper,SLOT(slotPropertiesChanged(QMap)))) { allOk = true; } - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("DeviceAdded"), this,SIGNAL(deviceAdded(QDBusObjectPath)))) { allOk = true; } - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("DeviceRemoved"), @@ -133,18 +133,17 @@ QList QNetworkManagerInterface::getDevices() const return reply.value(); } -void QNetworkManagerInterface::activateConnection( const QString &serviceName, +void QNetworkManagerInterface::activateConnection( const QString &, QDBusObjectPath connectionPath, QDBusObjectPath devicePath, QDBusObjectPath specificObject) { QDBusPendingCall pendingCall = d->connectionInterface->asyncCall(QLatin1String("ActivateConnection"), - QVariant(serviceName), QVariant::fromValue(connectionPath), QVariant::fromValue(devicePath), QVariant::fromValue(specificObject)); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pendingCall, this); + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pendingCall); connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SIGNAL(activationFinished(QDBusPendingCallWatcher*))); } @@ -504,7 +503,7 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(QString,QDBusObjectPath)), this,SIGNAL(accessPointRemoved(QString,QDBusObjectPath))); - if(!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointAdded"), @@ -513,7 +512,7 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() } - if(!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointRemoved"), @@ -522,7 +521,7 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() } - if(!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("PropertiesChanged"), @@ -608,7 +607,7 @@ bool QNetworkManagerSettings::setConnections() { bool allOk = false; - if (!QDBusConnection::systemBus().connect(d->path, QLatin1String(NM_DBUS_PATH_SETTINGS), + if (QDBusConnection::systemBus().connect(d->path, QLatin1String(NM_DBUS_PATH_SETTINGS), QLatin1String(NM_DBUS_IFACE_SETTINGS), QLatin1String("NewConnection"), this, SIGNAL(newConnection(QDBusObjectPath)))) { allOk = true; @@ -677,7 +676,7 @@ bool QNetworkManagerSettingsConnection::setConnections() QDBusConnection dbusConnection = QDBusConnection::systemBus(); bool allOk = false; - if(!dbusConnection.connect(d->service, d->path, + if (dbusConnection.connect(d->service, d->path, QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Updated"), this, SIGNAL(updated(QNmSettingsMap)))) { allOk = true; @@ -690,7 +689,7 @@ bool QNetworkManagerSettingsConnection::setConnections() connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(QString)), this,SIGNAL(removed(QString))); - if (!dbusConnection.connect(d->service, d->path, + if (dbusConnection.connect(d->service, d->path, QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Removed"), nmDBusHelper, SIGNAL(slotSettingsRemoved()))) { allOk = true; @@ -795,7 +794,7 @@ public: bool valid; }; -QNetworkManagerConnectionActive::QNetworkManagerConnectionActive( const QString &activeConnectionObjectPath, QObject *parent) +QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString &activeConnectionObjectPath, QObject *parent) : QObject(parent), nmDBusHelper(0) { d = new QNetworkManagerConnectionActivePrivate(); @@ -848,11 +847,6 @@ QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const return d->connectionInterface; } -QString QNetworkManagerConnectionActive::serviceName() const -{ - return d->connectionInterface->property("ServiceName").toString(); -} - QDBusObjectPath QNetworkManagerConnectionActive::connection() const { QVariant prop = d->connectionInterface->property("Connection"); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 6b15642386..25e6d3cf3a 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -101,10 +101,10 @@ typedef enum #define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" #define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" -#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings" +#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" -#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection" -#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings" +#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManager.Settings.Connection" +#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" #define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active" #define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config" -- cgit v1.2.3 From 520b10be4cab66f3f66d3692d0bbbef57eff09e1 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 7 Oct 2014 17:18:09 +1000 Subject: Add better mobile connections to QtBearer NetworkManager backend. Task-number: QTBUG-41807 Change-Id: Ifb5904d4887111416b4bb1a32d6d056029186f5c Reviewed-by: Lorn Potter --- .../networkmanager/qnetworkmanagerengine.cpp | 39 ++++++++--- .../networkmanager/qnetworkmanagerservice.cpp | 75 ++++++++++++++++++++++ .../bearer/networkmanager/qnetworkmanagerservice.h | 37 +++++++++++ 3 files changed, 142 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 105531c7f1..ec5666d36c 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -67,10 +67,6 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) this, SLOT(deviceAdded(QDBusObjectPath))); connect(interface, SIGNAL(deviceRemoved(QDBusObjectPath)), this, SLOT(deviceRemoved(QDBusObjectPath))); -#if 0 - connect(interface, SIGNAL(stateChanged(QString,quint32)), - this, SIGNAL(configurationsChanged())); -#endif connect(interface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), this, SLOT(activationFinished(QDBusPendingCallWatcher*))); connect(interface, SIGNAL(propertiesChanged(QString,QMap)), @@ -586,7 +582,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec ptr->isValid = true; ptr->id = objectPath.path(); ptr->type = QNetworkConfiguration::InternetAccessPoint; - if(accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) { + if (accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) { ptr->purpose = QNetworkConfiguration::PrivatePurpose; } else { ptr->purpose = QNetworkConfiguration::PublicPurpose; @@ -724,7 +720,7 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri const QString connectionSsid = map.value("802-11-wireless").value("ssid").toString(); const QString connectionSecurity = map.value("802-11-wireless").value("security").toString(); - if(!connectionSecurity.isEmpty()) { + if (!connectionSecurity.isEmpty()) { cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; } else { cpPriv->purpose = QNetworkConfiguration::PublicPurpose; @@ -749,9 +745,34 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri break; } } - } else if (connectionType == "gsm") { - cpPriv->bearerType = QNetworkConfiguration::Bearer2G; - } else if (connectionType == "cdma") { + } else if (connectionType == QLatin1String("gsm")) { + + foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + QNetworkManagerInterfaceDevice device(devicePath.path()); + + if (device.deviceType() == DEVICE_TYPE_GSM) { + QNetworkManagerInterfaceDeviceModem deviceModem(device.connectionInterface()->path(),this); + switch (deviceModem.currentCapabilities()) { + case 2: + cpPriv->bearerType = QNetworkConfiguration::Bearer2G; + break; + case 4: + cpPriv->bearerType = QNetworkConfiguration::Bearer3G; + break; + case 8: + cpPriv->bearerType = QNetworkConfiguration::Bearer4G; + break; + default: + cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; + break; + }; + } + } + + cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; + cpPriv->state |= QNetworkConfiguration::Discovered; + } else if (connectionType == QLatin1String("cdma")) { + cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; cpPriv->bearerType = QNetworkConfiguration::BearerCDMA2000; } diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index a7d1289b38..d154f1187e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -568,6 +568,81 @@ quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const return d->connectionInterface->property("WirelelessCapabilities").toUInt(); } +class QNetworkManagerInterfaceDeviceModemPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfaceDeviceModemPrivate(); + d->path = ifaceDevicePath; + d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM), + QDBusConnection::systemBus(), parent); + if (!d->connectionInterface->isValid()) { + d->valid = false; + return; + } + d->valid = true; +} + +QNetworkManagerInterfaceDeviceModem::~QNetworkManagerInterfaceDeviceModem() +{ + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterfaceDeviceModem::isValid() +{ + + return d->valid; +} + +bool QNetworkManagerInterfaceDeviceModem::setConnections() +{ + if (!isValid() ) + return false; + + bool allOk = false; + + delete nmDBusHelper; + nmDBusHelper = new QNmDBusHelper(this); + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), + this,SIGNAL(propertiesChanged(QString,QMap))); + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM), + QLatin1String("PropertiesChanged"), + nmDBusHelper,SLOT(slotDevicePropertiesChanged(QMap))) ) { + allOk = true; + } + return allOk; +} + +QDBusInterface *QNetworkManagerInterfaceDeviceModem::connectionInterface() const +{ + return d->connectionInterface; +} + +quint32 QNetworkManagerInterfaceDeviceModem::modemCapabilities() const +{ + return d->connectionInterface->property("ModemCapabilities").toUInt(); +} + +quint32 QNetworkManagerInterfaceDeviceModem::currentCapabilities() const +{ + return d->connectionInterface->property("CurrentCapabilities").toUInt(); +} + + + + class QNetworkManagerSettingsPrivate { public: diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 25e6d3cf3a..8cda02482b 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -98,6 +98,7 @@ typedef enum #define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device" #define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired" #define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless" +#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem" #define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" #define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" @@ -329,6 +330,42 @@ private: QNmDBusHelper *nmDBusHelper; }; +class QNetworkManagerInterfaceDeviceModemPrivate; +class QNetworkManagerInterfaceDeviceModem : public QObject +{ + Q_OBJECT + +public: + + enum ModemCapability { + None = 0x0, + Pots = 0x1, + Cmda_Edvo = 0x2, + Gsm_Umts = 0x4, + Lte = 0x08 + }; + + explicit QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, + QObject *parent = 0); + ~QNetworkManagerInterfaceDeviceModem(); + + QDBusObjectPath path() const; + QDBusInterface *connectionInterface() const; + + bool setConnections(); + bool isValid(); + + quint32 modemCapabilities() const; + quint32 currentCapabilities() const; + +Q_SIGNALS: + void propertiesChanged( const QString &, QMap); +private: + QNetworkManagerInterfaceDeviceModemPrivate *d; + QNmDBusHelper *nmDBusHelper; +}; + + class QNetworkManagerSettingsPrivate; class QNetworkManagerSettings : public QObject { -- cgit v1.2.3 From 6c7a348cf82665f7f09bc3e0cfe03256f1462744 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 20 Oct 2014 16:25:47 +0200 Subject: Set correct transient parent in q_createNativeChildrenAndSetParent(). Fix warning: void QWindow::setTransientParent(QWindow*) ... must be a top level window. which occurred for example when parenting a QMenu onto a native child widget. Task-number: QTBUG-41898 Change-Id: Icc25fb2108bd68b2d9c0e551949b90fc7a82d358 Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidget.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5529f8f72c..2d12674c29 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1362,11 +1362,11 @@ void q_createNativeChildrenAndSetParent(const QWidget *parentWidget) if (!childWidget->internalWinId()) childWidget->winId(); if (childWidget->windowHandle()) { - QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle(); - if (childWidget->isWindow()) - childWidget->windowHandle()->setTransientParent(parentWindow); - else - childWidget->windowHandle()->setParent(parentWindow); + if (childWidget->isWindow()) { + childWidget->windowHandle()->setTransientParent(parentWidget->window()->windowHandle()); + } else { + childWidget->windowHandle()->setParent(childWidget->nativeParentWidget()->windowHandle()); + } } } else { q_createNativeChildrenAndSetParent(childWidget); -- cgit v1.2.3 From a6ebc9b34ab7e463dac758e465f930e285003d2a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 10 Oct 2014 13:23:14 +0200 Subject: OS X - maximize app's window from the Dock or using cmd-tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On OS X it's possible to maximize app's window by clicking on an app's icon in the Dock. Another trick is to use cmd-tab to select an app +, while still holding the 'cmd' key, press the 'option' key - this should also maximize a window. None of these works at the moment, and to enable these features app delegate should return YES from the -applicationShouldHandleRepopen:hasVisibleWindows:. method. Task-number: QTBUG-40084 Change-Id: I33ba9e74d55d41d23deb429612519b746d461d9e Reviewed-by: Timur Pocheptsov Reviewed-by: Morten Johan Sørvig Reviewed-by: Laszlo Agocs --- src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 326628a261..9f7609f24c 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -396,7 +396,7 @@ static void cleanupCocoaApplicationDelegate() */ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive, true /*forcePropagate*/); - return NO; + return YES; } - (void)setReflectionDelegate:(NSObject *)oldDelegate -- cgit v1.2.3 From ae5f3df59b37e0ce8aaef27dc1e02f40def340ae Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 16 Oct 2014 12:53:04 +0200 Subject: OS X - unified toolbar and AA_NativeWindows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases QToolBar creates a child window (a child borderless NSWindow) placed on top of the toolbar's main window. As a result it's not possible to drag this main window using its toolbar - the window "jumps" on the screen. The reason is quite subtle - QNSView -handleMouseEvent: uses [NSEvent mouseLocation] and this location is invalid: - we have an NSWindow (parent) - we have a child NSWindow ([parent addChildWindow:child ....] - we handle drag event in a child window - we move a parent window as a result of drag event - Cocoa also moves a child window for us - when handling the next drag event, location [NSEvent mouseLocation] differs from the real event's location. Task-number: QTBUG-40106 Change-Id: Ic68cb92ab4233a1e0746b478820c1e33fd37a462 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 06680228bc..6234c0dcbe 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -686,7 +686,23 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_platformWindow->m_forwardWindow = 0; } - [targetView convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; + NSPoint globalPos = [NSEvent mouseLocation]; + + if ([self.window parentWindow] + && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) { + // QToolBar can be implemented as a child window on top of its main window + // (with a borderless NSWindow). If an option "unified toolbar" set on the main window, + // it's possible to drag such a window using this toolbar. + // While handling mouse drag events, QToolBar moves the window (QWidget::move). + // In such a combination [NSEvent mouseLocation] is very different from the + // real event location and as a result a window will move chaotically. + NSPoint winPoint = [theEvent locationInWindow]; + NSRect tmpRect = NSMakeRect(winPoint.x, winPoint.y, 1., 1.); + tmpRect = [[theEvent window] convertRectToScreen:tmpRect]; + globalPos = tmpRect.origin; + } + + [targetView convertFromScreen:globalPos toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; ulong timestamp = [theEvent timestamp] * 1000; QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); -- cgit v1.2.3 From dc267036e31f9193bad76c803ee162df5ec2d40d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 20 Oct 2014 11:28:38 +0200 Subject: OS X: Retina displays and blurry QToolButton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Checkable QToolButton has a special pixmap in the background, painted with a 'smooth pixmaps' hint. This hint also affects how an icon on a toolbutton itself is painted later. The difference can be quite visible on a Retina display, so this patch makes the toolbutton's image always look the same in checked/unchecked state. Task-number: QTBUG-35162 Change-Id: I2adc8006371fa10d89d4b77da6b3aa168aa5abc8 Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 620ba660e0..d909e13f9a 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -6005,8 +6005,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex p->fillPath(path, brush); } else if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png")); + p->save(); p->setRenderHint(QPainter::SmoothPixmapTransform); QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2); + p->restore(); } else { QPen oldPen = p->pen(); p->setPen(QColor(0, 0, 0, 0x3a)); -- cgit v1.2.3 From 90a4c69b2520bfa30364828bda2498e08004c00f Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 20 Oct 2014 13:35:16 +0200 Subject: Produce more correct clip path for QGraphicsShapeItem If no pen is set on the item, we can completely ignore the pen for the creation of the items shape. This both speeds up the creation of the shape and applying it as a clip mask as well as creating more correct results. Task-number: QTBUG-32846 Change-Id: I5f6f690256c71309713d8f746e67599af3088dd7 Reviewed-by: Laszlo Agocs --- src/widgets/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 114c45dc0f..67d135271c 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -797,7 +797,7 @@ static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, cons // if we pass a value of 0.0 to QPainterPathStroker::setWidth() const qreal penWidthZero = qreal(0.00000001); - if (path == QPainterPath()) + if (path == QPainterPath() || pen == Qt::NoPen) return path; QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); -- cgit v1.2.3 From 42bdbed7cedc5d77e999143c44c3e095b7cd4ebd Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 20 Oct 2014 14:54:20 +0200 Subject: Correctly apply miter limits when stroking lines The PDF generator was in many cases not correctly applying miter limits to the generated strokes leading to drawing artifacts for very sharp edges. Task-number: QTBUG-37903 Change-Id: Ie93b0f4a56775729105a375ba3bcdb5b58993433 Reviewed-by: Gunnar Sletta Reviewed-by: Laszlo Agocs --- src/gui/painting/qpdf.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index d1b021d653..6ea002a761 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1347,6 +1347,8 @@ void QPdfEngine::setPen() int pdfJoinStyle = 0; switch(d->pen.joinStyle()) { case Qt::MiterJoin: + case Qt::SvgMiterJoin: + *d->currentPage << d->pen.miterLimit() << "M "; pdfJoinStyle = 0; break; case Qt::BevelJoin: -- cgit v1.2.3 From dafd1ffa2c6fb8823b8e582d7cc75a050e14a80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 26 Jun 2014 15:15:56 +0200 Subject: QPA: Flush window system events with flags. Add a QEventLoop::ProcessEventsFlags argument to flushWindowSystemEvents(). This gives the platform plugins more control over which events to flush. Task-number: QTBUG-39842 Change-Id: Id9c01948b22e297b22503d38ec4e726f9f880fd5 Reviewed-by: Laszlo Agocs Reviewed-by: Jonathan Liu --- src/gui/kernel/qguiapplication.cpp | 5 +++-- src/gui/kernel/qwindowsysteminterface.cpp | 10 +++++----- src/gui/kernel/qwindowsysteminterface.h | 4 ++-- src/gui/kernel/qwindowsysteminterface_p.h | 4 +++- 4 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5233d76d7b..59bcd37251 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1628,8 +1628,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast(e); QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); } break; - case QWindowSystemInterfacePrivate::FlushEvents: - QWindowSystemInterface::deferredFlushWindowSystemEvents(); + case QWindowSystemInterfacePrivate::FlushEvents: { + QWindowSystemInterfacePrivate::FlushEventsEvent *flushEventsEvent = static_cast(e); + QWindowSystemInterface::deferredFlushWindowSystemEvents(flushEventsEvent->flags); } break; case QWindowSystemInterfacePrivate::Close: QGuiApplicationPrivate::processCloseEvent( diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index bd95a8614f..722a695481 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -526,16 +526,16 @@ void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®i QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::deferredFlushWindowSystemEvents() +void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) { Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread()); QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex); - flushWindowSystemEvents(); + flushWindowSystemEvents(flags); QWindowSystemInterfacePrivate::eventsFlushed.wakeOne(); } -void QWindowSystemInterface::flushWindowSystemEvents() +void QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) { const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count(); if (!count) @@ -549,11 +549,11 @@ void QWindowSystemInterface::flushWindowSystemEvents() } if (QThread::currentThread() != QGuiApplication::instance()->thread()) { QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex); - QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(); + QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(flags); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::eventsFlushed.wait(&QWindowSystemInterfacePrivate::flushEventMutex); } else { - sendWindowSystemEvents(QEventLoop::AllEvents); + sendWindowSystemEvents(flags); } } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 9784757d3a..30c236b51f 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -208,8 +208,8 @@ public: // For event dispatcher implementations static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); static void setSynchronousWindowsSystemEvents(bool enable); - static void flushWindowSystemEvents(); - static void deferredFlushWindowSystemEvents(); + static void flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents); + static void deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); static int windowSystemEventsQueued(); }; diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index f48c75a027..c3f41da835 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -178,9 +178,11 @@ public: class FlushEventsEvent : public WindowSystemEvent { public: - FlushEventsEvent() + FlushEventsEvent(QEventLoop::ProcessEventsFlags f = QEventLoop::AllEvents) : WindowSystemEvent(FlushEvents) + , flags(f) { } + QEventLoop::ProcessEventsFlags flags; }; class UserEvent : public WindowSystemEvent { -- cgit v1.2.3 From 1a097dc139d42f165af0c78ced0934b7e6747d9e Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 21 Oct 2014 13:54:45 +0200 Subject: eglfs: Do not flush input events when updating the cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-42079 Change-Id: Ica806a090db74b4a1c34421334a28d7efd002b35 Reviewed-by: Jonathan Liu Reviewed-by: Jørgen Lind --- src/platformsupport/eglconvenience/qeglplatformcursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index df6e6cd50c..cf41bd2f1b 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -267,7 +267,7 @@ void QEGLPlatformCursorUpdater::update(const QPoint &pos, const QRegion &rgn) { m_active = false; QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(pos), rgn); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } void QEGLPlatformCursorUpdater::scheduleUpdate(const QPoint &pos, const QRegion &rgn) -- cgit v1.2.3 From ab556d6b321bb02cec2a0c0705b1212377fde095 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 20 Oct 2014 15:04:24 +0200 Subject: Fix height of combo popup when the list view has non-zero spacing. QListView::spacing() is the space around the item (layout margin), so the effective spacing is twice as big. This differs conceptionally from QTableView, which has a spacing of 1 and a line on top/bottom. Split up QComboBoxPrivateContainer::spacing() into functions return spacing and top/bottom margins to reflect this. Task-number: QTBUG-37865 Change-Id: I1ff812e7856e00a53f1119ef3304956cbb7cbfca Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/widgets/qcombobox.cpp | 26 +++++++++++++++++++++----- src/widgets/widgets/qcombobox_p.h | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 44e22555db..89dc8bf178 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -479,9 +479,9 @@ void QComboBoxPrivateContainer::updateScrollers() view->verticalScrollBar()->minimum() < view->verticalScrollBar()->maximum()) { bool needTop = view->verticalScrollBar()->value() - > (view->verticalScrollBar()->minimum() + spacing()); + > (view->verticalScrollBar()->minimum() + topMargin()); bool needBottom = view->verticalScrollBar()->value() - < (view->verticalScrollBar()->maximum() - spacing()*2); + < (view->verticalScrollBar()->maximum() - bottomMargin() - topMargin()); if (needTop) top->show(); else @@ -571,6 +571,20 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) this, SLOT(viewDestroyed())); } +/*! + Returns the top/bottom vertical margin of the view. +*/ +int QComboBoxPrivateContainer::topMargin() const +{ + if (const QListView *lview = qobject_cast(view)) + return lview->spacing(); +#ifndef QT_NO_TABLEVIEW + if (const QTableView *tview = qobject_cast(view)) + return tview->showGrid() ? 1 : 0; +#endif + return 0; +} + /*! Returns the spacing between the items in the view. */ @@ -578,7 +592,7 @@ int QComboBoxPrivateContainer::spacing() const { QListView *lview = qobject_cast(view); if (lview) - return lview->spacing(); + return 2 * lview->spacing(); // QListView::spacing is the padding around the item. #ifndef QT_NO_TABLEVIEW QTableView *tview = qobject_cast(view); if (tview) @@ -2528,7 +2542,7 @@ void QComboBox::showPopup() QModelIndex idx = d->model->index(i, d->modelColumn, parent); if (!idx.isValid()) continue; - listHeight += view()->visualRect(idx).height() + container->spacing(); + listHeight += view()->visualRect(idx).height(); #ifndef QT_NO_TREEVIEW if (d->model->hasChildren(idx) && treeView && treeView->isExpanded(idx)) toCheck.push(idx); @@ -2540,12 +2554,14 @@ void QComboBox::showPopup() } } } + if (count > 1) + listHeight += (count - 1) * container->spacing(); listRect.setHeight(listHeight); } { // add the spacing for the grid on the top and the bottom; - int heightMargin = 2*container->spacing(); + int heightMargin = container->topMargin() + container->bottomMargin(); // add the frame of the container int marginTop, marginBottom; diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index becdde55ae..67b1aa6943 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -214,6 +214,8 @@ public: QAbstractItemView *itemView() const; void setItemView(QAbstractItemView *itemView); int spacing() const; + int topMargin() const; + int bottomMargin() const { return topMargin(); } void updateTopBottomMargin(); QTimer blockMouseReleaseTimer; -- cgit v1.2.3 From 7614d734c46feb6f74aa0651ae18f850a324e381 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Oct 2014 14:44:08 +0200 Subject: Windows: Implement Qt::WA_ShowWithoutActivating. Set dynamic property for all platforms and query it in QWindowsWindow::show_sys(). Task-number: QTBUG-19194 Task-number: QTBUG-34504 Change-Id: I4199a2ed835d3de928405d470a81c54da93cc768 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 9 ++++++++- src/widgets/kernel/qwidget.cpp | 2 -- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index dd9b9de0b6..8a80729354 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1149,6 +1149,13 @@ void QWindowsWindow::updateTransientParent() const #endif // !Q_OS_WINCE } +static inline bool testShowWithoutActivating(const QWindow *window) +{ + // QWidget-attribute Qt::WA_ShowWithoutActivating . + const QVariant showWithoutActivating = window->property("_q_showWithoutActivating"); + return showWithoutActivating.isValid() && showWithoutActivating.toBool(); +} + // partially from QWidgetPrivate::show_sys() void QWindowsWindow::show_sys() const { @@ -1180,7 +1187,7 @@ void QWindowsWindow::show_sys() const } // Qt::WindowMaximized } // !Qt::WindowMinimized } - if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool) + if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool || testShowWithoutActivating(w)) sm = SW_SHOWNOACTIVATE; if (w->windowState() & Qt::WindowMaximized) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2d12674c29..455d195159 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1403,10 +1403,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win->setProperty(propertyName, q->property(propertyName)); } -#ifdef Q_OS_OSX if (q->testAttribute(Qt::WA_ShowWithoutActivating)) win->setProperty("_q_showWithoutActivating", QVariant(true)); -#endif win->setFlags(data.window_flags); fixPosIncludesFrame(); if (q->testAttribute(Qt::WA_Moved) -- cgit v1.2.3 From 963037d86b6298fd314450f933376fe589b309e6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 16 Oct 2014 11:45:56 +0200 Subject: Fix helper function call in QWindowsVistaStyle::pixelMetric(). Task-number: QTBUG-41944 Task-number: QTBUG-40277 Change-Id: I1da9ffddce8edfcaa87d27058ed73ac7ec63d081 Reviewed-by: Adam Light Reviewed-by: Alessandro Portale --- src/widgets/styles/qwindowsvistastyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index a6eb2c0bc6..044394747c 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -2285,7 +2285,7 @@ int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *opti if (!QWindowsVistaStylePrivate::useVista()) return QWindowsStyle::pixelMetric(metric, option, widget); - int ret = QWindowsStylePrivate::fixedPixelMetric(metric); + int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric); if (ret != QWindowsStylePrivate::InvalidMetric) return int(QStyleHelper::dpiScaled(ret)); -- cgit v1.2.3 From 2fcc88d02131b0fd64857a2646381653b410f053 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 21 Oct 2014 11:05:54 +0200 Subject: OS X: drag and drop and auto-scrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cocoa sens periodic drag updated events even if there is no actuall mouse movement (or any other updates). This breaks animations in different views/widgets supporting our own auto-scroll (done with timers). This patch kindly asks Cocoa _not_ to send us these events. Task-number: QTBUG-32761 Change-Id: I5dad4ceb0a490e2f3cb34a806a5bdb1045b4dac3 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 6234c0dcbe..92ab16683e 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1822,6 +1822,19 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin return NO; } +- (BOOL)wantsPeriodicDraggingUpdates +{ + // From the documentation: + // + // "If the destination returns NO, these messages are sent only when the mouse moves + // or a modifier flag changes. Otherwise the destination gets the default behavior, + // where it receives periodic dragging-updated messages even if nothing changes." + // + // We do not want these constant drag update events while mouse is stationary, + // since we do all animations (autoscroll) with timers. + return NO; +} + - (NSDragOperation)draggingEntered:(id )sender { return [self handleDrag : sender]; -- cgit v1.2.3 From c5bc66df2fd976f4e055c579f6918138d3accd87 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 21 Oct 2014 10:49:54 +0200 Subject: Respect minimum size of heightForWidth layouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we cannot support heightForWidth constraints on toplevel windows, it is impossible to solve this perfectly: if the window is resizable at all, the user will be able to resize it too small. Our old solution was just to give up and allow completely free resizing, even down to 0x0. This makes very little sense. It is clearly better to use the minimum size that we have already computed, even though it is not perfect. This reverts a behavior change introduced in commit 36e9516f85fbb9c9a236f5ca034d5a0126d86c12 (September 9th, 2002) [ChangeLog][QtWidgets][QLayout] Widgets and dialogs containing layouts with heightForWidth (such as a label with word wrap) will no longer get a minimum size of 0x0. Task-number: QTBUG-37673 Change-Id: If26b7ef9c80edbf9d54c6519b36646df408b7652 Reviewed-by: Jan Arve Sæther --- src/widgets/kernel/qlayout.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 3900444df4..46cab90ab4 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1106,15 +1106,6 @@ bool QLayout::activate() ms.setWidth(mw->minimumSize().width()); if (heightSet) ms.setHeight(mw->minimumSize().height()); - if ((!heightSet || !widthSet) && hasHeightForWidth()) { - int h = minimumHeightForWidth(ms.width()); - if (h > ms.height()) { - if (!heightSet) - ms.setHeight(0); - if (!widthSet) - ms.setWidth(0); - } - } mw->setMinimumSize(ms); } else if (!widthSet || !heightSet) { QSize ms = mw->minimumSize(); -- cgit v1.2.3 From bd4a19963e102f4a89fdc1f17349909605324519 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 10 Sep 2014 08:31:35 +0200 Subject: Respect contents margins when calculating the size hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this part of the calendar widget get cut off when put in a layout and the contentsMargins are non zero. Task-number: QTBUG-40352 Change-Id: I9ce90476c59c270d92e876a5dc81ea8ce325848c Reviewed-by: Lars Knoll Reviewed-by: Shawn Rutledge Reviewed-by: Jan Arve Sæther --- src/widgets/widgets/qcalendarwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index d6704c20d2..fa3dbc1f32 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -2247,6 +2247,9 @@ QSize QCalendarWidget::minimumSizeHint() const w *= cols; w = qMax(headerSize.width(), w); h = (h * rows) + headerSize.height(); + QMargins cm = contentsMargins(); + w += cm.left() + cm.right(); + h += cm.top() + cm.bottom(); d->cachedSizeHint = QSize(w, h); return d->cachedSizeHint; } -- cgit v1.2.3 From f4144034aff244f1e1345a4b84baba9477855377 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 21 Oct 2014 14:55:07 +0200 Subject: Fix badly laid out docs for AA_UseHighDpiPixmaps Leaving an empty line causes the last sentence go outside the table, causing a break before the subsequent enum values. Change-Id: I7477010a259497f8063997d2122a954d1799c1ee Reviewed-by: Andy Nichols --- src/corelib/global/qnamespace.qdoc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 044ba66a4c..bf558e48f6 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -159,11 +159,10 @@ \value AA_UseHighDpiPixmaps Make QIcon::pixmap() generate high-dpi pixmaps that can be larger than the requested size. Such pixmaps will have - devicePixelRatio set to a value higher than 1. - - After setting this attribute application code that uses pixmap - sizes in layout geometry calculations should typically divide by - QPixmap::devicePixelRatio() to get device-independent layout geometry. + devicePixelRatio set to a value higher than 1. After setting this + attribute application code that uses pixmap sizes in layout geometry + calculations should typically divide by QPixmap::devicePixelRatio() + to get device-independent layout geometry. \value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces, and do not support non-native GL-based child widgets. -- cgit v1.2.3 From 1c6b9955a5bacc8695e719b42d51de535fa5def1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 20 Oct 2014 13:30:35 +0200 Subject: Document QOpenGLPixelTransferOptions Task-number: QTBUG-35576 Change-Id: I178f5db5f1075b6a395cf8ff73b75fe1765540aa Reviewed-by: Sean Harmer --- src/gui/opengl/qopenglpixeltransferoptions.cpp | 93 ++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'src') diff --git a/src/gui/opengl/qopenglpixeltransferoptions.cpp b/src/gui/opengl/qopenglpixeltransferoptions.cpp index 4f72b43f37..9ea2e0ecc1 100644 --- a/src/gui/opengl/qopenglpixeltransferoptions.cpp +++ b/src/gui/opengl/qopenglpixeltransferoptions.cpp @@ -36,6 +36,23 @@ QT_BEGIN_NAMESPACE +/*! + * \class QOpenGLPixelTransferOptions + * + * \brief The QOpenGLPixelTransferOptions class describes the pixel storage + * modes that affect the unpacking of pixels during texture upload. + */ + +/*! + * \fn QOpenGLPixelTransferOptions & QOpenGLPixelTransferOptions::operator=(QOpenGLPixelTransferOptions &&other) + * \internal + */ + +/*! + * \fn void QOpenGLPixelTransferOptions::swap(QOpenGLPixelTransferOptions &other) + * \internal + */ + class QOpenGLPixelTransferOptionsData : public QSharedData { public: @@ -60,16 +77,25 @@ public: bool swapBytes; }; +/*! + * Constructs a new QOpenGLPixelTransferOptions instance with the default settings. + */ QOpenGLPixelTransferOptions::QOpenGLPixelTransferOptions() : data(new QOpenGLPixelTransferOptionsData) { } +/*! + * \internal + */ QOpenGLPixelTransferOptions::QOpenGLPixelTransferOptions(const QOpenGLPixelTransferOptions &rhs) : data(rhs.data) { } +/*! + * \internal + */ QOpenGLPixelTransferOptions &QOpenGLPixelTransferOptions::operator=(const QOpenGLPixelTransferOptions &rhs) { if (this != &rhs) @@ -77,85 +103,152 @@ QOpenGLPixelTransferOptions &QOpenGLPixelTransferOptions::operator=(const QOpenG return *this; } +/*! + * Destructor. + */ QOpenGLPixelTransferOptions::~QOpenGLPixelTransferOptions() { } +/*! + * Sets the \a alignment requirements for each pixel row. Corresponds to \c GL_UNPACK_ALIGNMENT. + * The default value is 4, as specified by OpenGL. + */ void QOpenGLPixelTransferOptions::setAlignment(int alignment) { data->alignment = alignment; } +/*! + * \return the current alignment requirement for each pixel row. + */ int QOpenGLPixelTransferOptions::alignment() const { return data->alignment; } +/*! + * Sets the number of images that are skipped to \a skipImages. + * Corresponds to \c GL_UNPACK_SKIP_IMAGES. Equivalent to incrementing the pointer + * passed to QOpenGLTexture::setData(). The default value is 0. + */ void QOpenGLPixelTransferOptions::setSkipImages(int skipImages) { data->skipImages = skipImages; } +/*! + * \return the number of images that are skipped. + */ int QOpenGLPixelTransferOptions::skipImages() const { return data->skipImages; } +/*! + * Sets the number of rows that are skipped to \a skipRows. + * Corresponds to \c GL_UNPACK_SKIP_ROWS. Equivalent to incrementing the pointer + * passed to QOpenGLTexture::setData(). The default value is 0. + */ void QOpenGLPixelTransferOptions::setSkipRows(int skipRows) { data->skipRows = skipRows; } +/*! + * \return the number of rows that are skipped. + */ int QOpenGLPixelTransferOptions::skipRows() const { return data->skipRows; } +/*! + * Sets the number of pixels that are skipped to \a skipPixels. + * Corresponds to \c GL_UNPACK_SKIP_PIXELS. Equivalent to incrementing the pointer + * passed to QOpenGLTexture::setData(). The default value is 0. + */ void QOpenGLPixelTransferOptions::setSkipPixels(int skipPixels) { data->skipPixels = skipPixels; } +/*! + * \return the number of pixels that are skipped. + */ int QOpenGLPixelTransferOptions::skipPixels() const { return data->skipPixels; } +/*! + * Sets the image height for 3D textures to \a imageHeight. + * Corresponds to \c GL_UNPACK_IMAGE_HEIGHT. + * The default value is 0. + */ void QOpenGLPixelTransferOptions::setImageHeight(int imageHeight) { data->imageHeight = imageHeight; } +/*! + * \return the currently set image height. + */ int QOpenGLPixelTransferOptions::imageHeight() const { return data->imageHeight; } +/*! + * Sets the number of pixels in a row to \a rowLength. + * Corresponds to \c GL_UNPACK_ROW_LENGTH. + * The default value is 0. + */ void QOpenGLPixelTransferOptions::setRowLength(int rowLength) { data->rowLength = rowLength; } +/*! + * \return the currently set row length. + */ int QOpenGLPixelTransferOptions::rowLength() const { return data->rowLength; } +/*! + * \a lsbFirst specifies if bits within a byte are ordered from least to most significat. + * The default value is \c false, meaning that the first bit in each byte is the + * most significant one. This is significant for bitmap data only. + * Corresponds to \c GL_UNPACK_LSB_FIRST. + */ void QOpenGLPixelTransferOptions::setLeastSignificantByteFirst(bool lsbFirst) { data->lsbFirst = lsbFirst; } +/*! + * \return \c true if bits within a byte are ordered from least to most significant. + */ bool QOpenGLPixelTransferOptions::isLeastSignificantBitFirst() const { return data->lsbFirst; } +/*! + * \a swapBytes specifies if the byte ordering for multibyte components is reversed. + * The default value is \c false. + * Corresponds to \c GL_UNPACK_SWAP_BYTES. + */ void QOpenGLPixelTransferOptions::setSwapBytesEnabled(bool swapBytes) { data->swapBytes = swapBytes; } +/*! + * \return \c true if the byte ordering for multibyte components is reversed. + */ bool QOpenGLPixelTransferOptions::isSwapBytesEnabled() const { return data->swapBytes; -- cgit v1.2.3 From 9518b7e0f198c69d747d93eca5bb003944492c9f Mon Sep 17 00:00:00 2001 From: Weitian Leung Date: Tue, 21 Oct 2014 14:45:38 +0800 Subject: Avoid adding empty parent icon theme "Icon Theme/Inherits" may assign an empty value, e.g. Flattr icon theme Change-Id: I90713b3eb67e39d6a49a49d1f5b3d7a75a8f30f4 Reviewed-by: Friedemann Kleint --- src/gui/image/qiconloader.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 750e253dee..06491f1155 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -223,6 +223,7 @@ QIconTheme::QIconTheme(const QString &themeName) // Parent themes provide fallbacks for missing icons m_parents = indexReader.value( QLatin1String("Icon Theme/Inherits")).toStringList(); + m_parents.removeAll(QString()); // Ensure a default platform fallback for all themes if (m_parents.isEmpty()) { -- cgit v1.2.3 From 2580192defddb4afc0281b6097b8a3c5271412e7 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 20 Oct 2014 15:05:26 +0200 Subject: Windows native socket: handle WSAENETRESET the same as WSAECONNRESET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-41934 Change-Id: Ib92d8a83965e11e2706ef0daba945cb00692d2c5 Reviewed-by: Friedemann Kleint Reviewed-by: Richard J. Moore Reviewed-by: Jędrzej Nowacki --- src/network/socket/qnativesocketengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 85ec2012b8..f5943d657f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1140,7 +1140,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const int err = WSAGetLastError(); if (ret == SOCKET_ERROR && err != WSAEMSGSIZE) { WS_ERROR_DEBUG(err); - if (err == WSAECONNRESET) { + if (err == WSAECONNRESET || err == WSAENETRESET) { // Discard error message to prevent QAbstractSocket from // getting this message repeatedly after reenabling the // notifiers. -- cgit v1.2.3 From 56bb02ade34758c244772c739ce26dd125107ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 20 Oct 2014 13:10:42 +0200 Subject: Improve iOS https error handling. Set the reply state to "finished" also on errors. Do a proper string compare to correctly translate the error codes. Task-number: QTBUG-42023 Change-Id: I222cc06a47b1f9f89095e8f935f316bf94fd0cd6 Reviewed-by: Caroline Chao Reviewed-by: Richard Moe Gustavsen --- src/network/access/qnetworkreplynsurlconnectionimpl.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm index f93f18357a..327dbd4ea7 100644 --- a/src/network/access/qnetworkreplynsurlconnectionimpl.mm +++ b/src/network/access/qnetworkreplynsurlconnectionimpl.mm @@ -245,7 +245,7 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() Q_UNUSED(connection) QNetworkReply::NetworkError qtError = QNetworkReply::UnknownNetworkError; - if ([error domain] == NSURLErrorDomain) { + if ([[error domain] isEqualToString:NSURLErrorDomain]) { switch ([error code]) { case NSURLErrorTimedOut: qtError = QNetworkReply::TimeoutError; break; case NSURLErrorUnsupportedURL: qtError = QNetworkReply::ProtocolUnknownError; break; @@ -260,6 +260,7 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() } replyprivate->setError(qtError, QString::fromNSString([error localizedDescription])); + replyprivate->setFinished(); } - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)aResponse -- cgit v1.2.3 From 28857e7ad03bb416a1bae20b3771b799dee802c7 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 20 Oct 2014 15:55:16 +0200 Subject: Windows: QWindowsPrintDevice::printableMargins avoids leaking the DC MSDN says if the DC was created by calling CreateDC, it must be freed by DeleteDC not ReleaseDC. Task-number: QTBUG-41941 Change-Id: I4c60b5d2587f1c4d3332fce74224cbc8b756eb2a Reviewed-by: Friedemann Kleint --- src/plugins/printsupport/windows/qwindowsprintdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 1a6f40722d..0a21193216 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -271,7 +271,7 @@ QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize, const qreal rightMargin = physicalWidth - leftMargin - printableWidth; const qreal bottomMargin = physicalHeight - topMargin - printableHeight; margins = QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin); - ReleaseDC(NULL, pDC); + DeleteDC(pDC); } return margins; } -- cgit v1.2.3 From d0402bed6f9a4f9943183720b13e941cc6b656b7 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 16 Oct 2014 21:53:35 +0200 Subject: Improve QLoggingCategory's detailed description. Change-Id: I40527890fb752c3a1c0f8d8a8fa4ca2b19e4fc08 Reviewed-by: Kai Koehne --- src/corelib/io/qloggingcategory.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 37503e032c..fef48a9040 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -61,13 +61,15 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \brief The QLoggingCategory class represents a category, or 'area' in the logging infrastructure. - QLoggingCategory represents a certain logging category - identified - by a string - at runtime. Whether a category should be actually logged or - not can be checked with the \l isEnabled() methods. + QLoggingCategory represents a certain logging category - identified by a + string - at runtime. A category can be configured to enable or disable + logging of messages per message type. Whether a message type is enabled or + not can be checked with the \l isDebugEnabled(), \l isWarningEnabled(), and + \l isCriticalEnabled() methods. All objects are meant to be configured by a common registry (see also \l{Configuring Categories}). Different objects can also represent the same - category. It's therefore not recommended to export objects across module + category. It is therefore not recommended to export objects across module boundaries, nor to manipulate the objects directly, nor to inherit from QLoggingCategory. @@ -110,8 +112,9 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \section2 Logging Rules - Logging rules allow to enable or disable logging for categories in a flexible - way. Rules are specified in text, where every line must have the format + Logging rules allow logging for categories to be enabled or disabled in a + flexible way. Rules are specified in text, where every line must have the + format \code [.] = true|false @@ -120,12 +123,12 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \c is the name of the category, potentially with \c{*} as a wildcard symbol as the first or last character (or at both positions). The optional \c must be either \c debug, \c warning, or \c critical. - Lines that do not fit to his scheme are ignored. + Lines that do not fit this scheme are ignored. Rules are evaluated in text order, from first to last. That is, if two rules apply to a category/type, the rule that comes later is applied. - Rules can be set via \l setFilterRules(). Since Qt 5.3 logging rules can also + Rules can be set via \l setFilterRules(). Since Qt 5.3, logging rules can also be set in the \c QT_LOGGING_RULES environment variable, and are automatically loaded from the \c [Rules] section of a logging configuration file. Such configuration files are looked up in the QtProject @@ -168,13 +171,13 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \section2 Installing a Custom Filter - As a lower-level alternative to the text rules you can also implement a + As a lower-level alternative to the text rules, you can also implement a custom filter via \l installFilter(). All filter rules are ignored in this case. \section1 Printing the Category - Use the \c %{category} place holder to print the category in the default + Use the \c %{category} placeholder to print the category in the default message handler: \snippet qloggingcategory/main.cpp 3 -- cgit v1.2.3 From ff98c440603e94ae284ad08d289418f4b5cca89e Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 14 Oct 2014 12:18:08 +0200 Subject: Doc: Improved explanation of quality setting in QImageReader/Writer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explanation was somewhat inprecise and incomplete. Task-number: QTBUG-41358 Change-Id: Iae52c30868ca48a49eac76d6979a9b02c24a7d49 Reviewed-by: Topi Reiniö --- src/gui/image/qimagereader.cpp | 23 +++++++++++++++-------- src/gui/image/qimagewriter.cpp | 17 ++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index a1b9743209..a7a08a6fee 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -877,15 +877,22 @@ QString QImageReader::fileName() const /*! \since 4.2 - This is an image format specific function that sets the quality - level of the image to \a quality. For image formats that do not - support setting the quality, this value is ignored. + Sets the quality setting of the image format to \a quality. - The value range of \a quality depends on the image format. For - example, the "jpeg" format supports a quality range from 0 (low - quality, high compression) to 100 (high quality, low compression). + Some image formats, in particular lossy ones, entail a tradeoff between a) + visual quality of the resulting image, and b) decoding execution time. + This function sets the level of that tradeoff for image formats that + support it. - \sa quality() + In case of scaled image reading, the quality setting may also influence the + tradeoff level between visual quality and execution speed of the scaling + algorithm. + + The value range of \a quality depends on the image format. For example, + the "jpeg" format supports a quality range from 0 (low visual quality) to + 100 (high visual quality). + + \sa quality() setScaledSize() */ void QImageReader::setQuality(int quality) { @@ -895,7 +902,7 @@ void QImageReader::setQuality(int quality) /*! \since 4.2 - Returns the quality level of the image. + Returns the quality setting of the image format. \sa setQuality() */ diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index d172d4008f..fa261df1a5 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -434,13 +434,16 @@ QString QImageWriter::fileName() const } /*! - This is an image format specific function that sets the quality - level of the image to \a quality. For image formats that do not - support setting the quality, this value is ignored. + Sets the quality setting of the image format to \a quality. - The value range of \a quality depends on the image format. For - example, the "jpeg" format supports a quality range from 0 (low - quality, high compression) to 100 (high quality, low compression). + Some image formats, in particular lossy ones, entail a tradeoff between a) + visual quality of the resulting image, and b) encoding execution time and + compression level. This function sets the level of that tradeoff for image + formats that support it. For other formats, this value is ignored. + + The value range of \a quality depends on the image format. For example, + the "jpeg" format supports a quality range from 0 (low visual quality, high + compression) to 100 (high visual quality, low compression). \sa quality() */ @@ -450,7 +453,7 @@ void QImageWriter::setQuality(int quality) } /*! - Returns the quality level of the image. + Returns the quality setting of the image format. \sa setQuality() */ -- cgit v1.2.3 From 763a48fe1af5b0482f929a79ded05ea21456a916 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Oct 2014 14:05:24 +0200 Subject: Windows XP style: Fix size calculation of QScrollBar's grip. Factor out function to calculate the geometry for the styles >= XP. Task-number: QTBUG-41944 Task-number: QTBUG-40277 Change-Id: Ifad1519b99fd587158c790dd241cb3e4bac3bfc3 Reviewed-by: Kai Koehne --- src/widgets/styles/qwindowsvistastyle.cpp | 20 +------------------ src/widgets/styles/qwindowsxpstyle.cpp | 33 ++++++++++++++----------------- src/widgets/styles/qwindowsxpstyle_p_p.h | 1 + 3 files changed, 17 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 044394747c..007952192a 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1756,26 +1756,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle theme.stateId = stateId; d->drawBackground(theme); - // Calculate rect of gripper - const int swidth = theme.rect.width(); - const int sheight = theme.rect.height(); - - const QMargins contentsMargin = theme.margins(theme.rect, TMT_SIZINGMARGINS) - / QWindowsXPStylePrivate::devicePixelRatio(widget); - - theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; - const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) { - QPoint gripperBoundsPos(0, 0); - if ((flags & State_Horizontal - && swidth - contentsMargin.left() - contentsMargin.right() > size.width()) - || sheight - contentsMargin.top() - contentsMargin.bottom() > size.height()) { - gripperBoundsPos = QPoint(theme.rect.left() + (swidth - size.width()) / 2, - theme.rect.top() + (sheight - size.height()) / 2); - } - const QRect gripperBounds(gripperBoundsPos, size); - + const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme); // Draw gripper if there is enough space if (!gripperBounds.isEmpty() && flags & State_Enabled) { painter->save(); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 624023f627..c18bbb3431 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -2529,6 +2529,20 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op d->drawBackground(theme); } +QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme) +{ + const bool horizontal = flags & QStyle::State_Horizontal; + const QMargins contentsMargin = theme->margins(theme->rect, TMT_SIZINGMARGINS) + / QWindowsStylePrivate::devicePixelRatio(widget); + theme->partId = horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; + const QSize size = theme->size() / QWindowsStylePrivate::devicePixelRatio(widget); + + const int hSpace = theme->rect.width() - size.width(); + const int vSpace = theme->rect.height() - size.height(); + const bool sufficientSpace = horizontal && hSpace > (contentsMargin.left() + contentsMargin.right()) + || vSpace > contentsMargin.top() + contentsMargin.bottom(); + return sufficientSpace ? QRect(theme->rect.topLeft() + QPoint(hSpace, vSpace) / 2, size) : QRect(); +} /*! \reimp @@ -2754,24 +2768,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo theme.stateId = stateId; d->drawBackground(theme); - // Calculate rect of gripper - const int swidth = theme.rect.width(); - const int sheight = theme.rect.height(); - - const QMargins contentsMargin = theme.margins(theme.rect, TMT_SIZINGMARGINS) - / QWindowsStylePrivate::devicePixelRatio(widget); - - theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; - const QSize size = theme.size() / QWindowsStylePrivate::devicePixelRatio(widget); - QPoint gripperBoundsPos(0, 0); - if ((flags & State_Horizontal - && swidth - contentsMargin.left() - contentsMargin.right() > size.width()) - || sheight - contentsMargin.top() - contentsMargin.bottom() > size.height()) { - gripperBoundsPos = QPoint(theme.rect.left() + (swidth - size.width()) / 2, - theme.rect.top() + (sheight - size.height()) /2); - } - const QRect gripperBounds(gripperBoundsPos, size); - + const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme); // Draw gripper if there is enough space if (!gripperBounds.isEmpty()) { p->save(); diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h index 4f42b60681..5027588c93 100644 --- a/src/widgets/styles/qwindowsxpstyle_p_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p_p.h @@ -392,6 +392,7 @@ public: static bool resolveSymbols(); static bool useXP(bool update = false); + static QRect scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme); bool isTransparent(XPThemeData &themeData); QRegion region(XPThemeData &themeData); -- cgit v1.2.3 From 4fbd2dd4a633a94d736a80e837fde654d1a14149 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 21 Oct 2014 11:46:32 +0200 Subject: Windows: Initialize the mouse cursor resources Initializing resources is required for static Qt builds on Windows. Task-number: QTBUG-42075 Change-Id: I3074fd8ab57ac48762f589eb3776ed5cc7e2e31d Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscursor.cpp | 12 ++++++++++++ src/plugins/platforms/windows/qwindowscursor.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index d2460e0640..f5d6c140bf 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -48,6 +48,13 @@ #include #include +static void initResources() +{ +#if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG) + Q_INIT_RESOURCE(cursors); +#endif +} + QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); @@ -568,6 +575,11 @@ QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c) return it.value(); } +QWindowsCursor::QWindowsCursor() +{ + initResources(); +} + /*! \brief Set a cursor on a window. diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index c8e1df3f4d..a024646553 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -91,7 +91,7 @@ public: CursorSuppressed // Cursor suppressed by touch interaction (Windows 8). }; - QWindowsCursor() {} + QWindowsCursor(); void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE; QPoint pos() const Q_DECL_OVERRIDE; -- cgit v1.2.3 From b5bbfad0a4e11a5db7ed04caf4dba43bcee7ae8d Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 22 Sep 2014 13:03:21 +0400 Subject: Doc: Fix obsoleteness of some QStyle::PixelMetric enum items The enum items PM_ScrollView_ScrollBarSpacing, PM_ScrollView_ScrollBarOverlap and PM_SubMenuOverlap were mistakenly put together with obsolete enum items. Move them up to fix it. Change-Id: I90bd3a8ab68c99db27134d976fe69df56c9af2b8 Reviewed-by: Sean Harmer Reviewed-by: Martin Smith --- src/widgets/styles/qstyle.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 52a794a03a..6cf61a691e 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1463,6 +1463,12 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value PM_TabCloseIndicatorWidth The default width of a close button on a tab in a tab bar. \value PM_TabCloseIndicatorHeight The default height of a close button on a tab in a tab bar. + \value PM_ScrollView_ScrollBarSpacing Distance between frame and scrollbar + with SH_ScrollView_FrameOnlyAroundContents set. + \value PM_ScrollView_ScrollBarOverlap Overlap between scroll bars and scroll content + + \value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent. + \value PM_TreeViewIndentation The indentation of items in a tree view. This enum value has been introduced in Qt 5.4. @@ -1483,12 +1489,6 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, and PM_LayoutVerticalSpacing instead. - \value PM_ScrollView_ScrollBarSpacing Distance between frame and scrollbar - with SH_ScrollView_FrameOnlyAroundContents set. - \value PM_ScrollView_ScrollBarOverlap Overlap between scroll bars and scroll content - - \value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent. - \sa pixelMetric() */ -- cgit v1.2.3 From 1ff6c575ce57c84324e4be4919cac65e09b96025 Mon Sep 17 00:00:00 2001 From: Jeongmin Kim Date: Wed, 24 Sep 2014 18:51:21 +0900 Subject: QNetworkDiskCache: Fix QNetworkDiskCache don't handle to set CookieHeader. QNetworkDiskCache don't handle to set CookieHeader. so All Set-Cookie's value is invalid. The root of cause is that metaDataChanged() don't work because of no slot for it. Add the slot for it and renamed to _q_metaDataChanged. Task-number: QTBUG-41514 Change-Id: I5cec017e59a1de69c6e89c0bc7209a73dcdc11da Reviewed-by: Jeongmin Kim Reviewed-by: Jung Dong-Heon Reviewed-by: Peter Hartmann --- src/network/access/qnetworkreplyhttpimpl.cpp | 6 +++--- src/network/access/qnetworkreplyhttpimpl_p.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index a021d51952..836b3c3fa4 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1166,7 +1166,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData setCachingEnabled(true); } - metaDataChanged(); + _q_metaDataChanged(); } void QNetworkReplyHttpImplPrivate::replyDownloadProgressSlot(qint64 bytesReceived, qint64 bytesTotal) @@ -1359,7 +1359,7 @@ bool QNetworkReplyHttpImplPrivate::sendCacheContents(const QNetworkCacheMetaData // This needs to be emitted in the event loop because it can be reached at // the direct code path of qnam.get(...) before the user has a chance // to connect any signals. - QMetaObject::invokeMethod(q, "metaDataChanged", Qt::QueuedConnection); + QMetaObject::invokeMethod(q, "_q_metaDataChanged", Qt::QueuedConnection); QMetaObject::invokeMethod(q, "_q_cacheLoadReadyRead", Qt::QueuedConnection); @@ -1986,7 +1986,7 @@ void QNetworkReplyHttpImplPrivate::error(QNetworkReplyImpl::NetworkError code, c emit q->error(code); } -void QNetworkReplyHttpImplPrivate::metaDataChanged() +void QNetworkReplyHttpImplPrivate::_q_metaDataChanged() { // FIXME merge this with replyDownloadMetaData(); ? diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index baff7a943c..77d9c5a368 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -124,6 +124,7 @@ public: Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot()) Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64)) Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose()) + Q_PRIVATE_SLOT(d_func(), void _q_metaDataChanged()) #ifndef QT_NO_SSL @@ -175,7 +176,7 @@ public: void finished(); void error(QNetworkReply::NetworkError code, const QString &errorString); void _q_error(QNetworkReply::NetworkError code, const QString &errorString); - void metaDataChanged(); + void _q_metaDataChanged(); void checkForRedirect(const int statusCode); -- cgit v1.2.3 From 1510411a38cdf0359e2353d7f52d1795294a1d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 22 Oct 2014 21:28:16 +0200 Subject: Revert "Cocoa: Send obscure events on OcclusionStateHidden" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This caused instability in the CI and testing system: Tests that expected expose and paint events no longer got them due to window placement/visibility, including: tst_QGraphicsProxyWidget::paintEvent tst_QMdiArea::tileSubWindows tst_QSizeGrip::hideAndShowOnWindowStateChange This reverts commit f5cf06f4afc48198780e3c3d0d1a52afce425507. Change-Id: I017fbf24f3ad99cce6602eddafc3a67f8edc494d Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 92ab16683e..9cd075fdec 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -420,10 +420,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; #pragma clang diagnostic ignored "-Wobjc-method-access" enum { NSWindowOcclusionStateVisible = 1UL << 1 }; #endif + // Older versions managed in -[QNSView viewDidMoveToWindow]. + // Support QWidgetAction in NSMenu. Mavericks only sends this notification. + // Ideally we should support this in Qt as well, in order to disable animations + // when the window is occluded. if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) m_platformWindow->exposeWindow(); - else - m_platformWindow->obscureWindow(); #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 #pragma clang diagnostic pop #endif -- cgit v1.2.3 From 449b62ed436a8e45d1064b76dc9cc3201966bd91 Mon Sep 17 00:00:00 2001 From: Ruslan Nigmatullin Date: Sat, 27 Sep 2014 00:19:36 +0300 Subject: XCB: Don't trigger less specific shortcuts Without this patch some keycodes like Ctrl+Shift+= may generate several similar key sequences like Ctrl++ and + but only more specific keys should be returned by QXcbKeyboard::possibleKeys. Task-number: QTBUG-38137 Change-Id: I23f6522eefaa3b83cfa639f76bdc6a19b450c6f9 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index fc3443aba5..dae3a79628 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -910,6 +910,18 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const if (qtKey == baseQtKey || qtKey == 0) continue; + // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +, + // but Ctrl++ is more specific than +, so we should skip the last one + bool ambiguous = false; + foreach (int shortcut, result) { + if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) { + ambiguous = true; + break; + } + } + if (ambiguous) + continue; + result += (qtKey + mods); } } -- cgit v1.2.3 From ad66fa0dc18f20f3ceb5916ac791231c067b5898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 14 Feb 2014 14:58:32 +0100 Subject: Cocoa: Delay QMimeData requests for DnD events. We were delaying the conversion from Qt to OS X types, but not the data request to the application. Introduce "Eager" and "Lazy" pasteboard promises: Eager promises request the application data immediately and can continue to use the existing commit-promises- on-app-exit logic. Eager promises are the default type and will be used for copy/paste. Lazy promises delay requesting the data from the application for as long as possible, specifically until when promiseKeeper() is called. Lazy promises are used for drag-and-drop and are not committed on application exit. This brings OS X DnD behavior in line with the Windows behavior. [ChangeLog][OS X] Drag-and-drop QMimeData requests are now delayed until drop time. Task-number: QTBUG-31301 Change-Id: I8ddbba41593251f4c0c49c29492dce990066e20d Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoadrag.mm | 2 +- src/plugins/platforms/cocoa/qmacclipboard.h | 17 +++++++-- src/plugins/platforms/cocoa/qmacclipboard.mm | 56 ++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 2c8d391d2b..47b52c9fdd 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -132,7 +132,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND); m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); - dragBoard.setMimeData(m_drag->mimeData()); + dragBoard.setMimeData(m_drag->mimeData(), QMacPasteboard::LazyRequest); NSPoint event_location = [m_lastEvent locationInWindow]; NSPoint local_point = [m_lastView convertPoint:event_location fromView:nil]; diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h index ba7a2e1aac..c5b6224545 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.h +++ b/src/plugins/platforms/cocoa/qmacclipboard.h @@ -43,15 +43,25 @@ QT_BEGIN_NAMESPACE +class QMacMimeData; class QMacPasteboard { +public: + enum DataRequestType { EagerRequest, LazyRequest }; +private: struct Promise { Promise() : itemId(0), convertor(0) { } - Promise(int itemId, QMacInternalPasteboardMime *c, QString m, QVariant d, int o=0) : itemId(itemId), offset(o), convertor(c), mime(m), data(d) { } + + static Promise eagerPromise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *d, int o = 0); + static Promise lazyPromise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *d, int o = 0); + Promise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *md, int o, DataRequestType drt); + int itemId, offset; QMacInternalPasteboardMime *convertor; QString mime; - QVariant data; + QPointer mimeData; + QVariant variantData; + DataRequestType dataRequestType; }; QList promises; @@ -72,7 +82,8 @@ public: PasteboardRef pasteBoard() const; QMimeData *mimeData() const; - void setMimeData(QMimeData *mime); + + void setMimeData(QMimeData *mime, DataRequestType dataRequestType = EagerRequest); QStringList formats() const; bool hasFormat(const QString &format) const; diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 65665ef790..b235625921 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -64,6 +64,26 @@ QT_BEGIN_NAMESPACE QMacPasteboard code *****************************************************************************/ +class QMacMimeData : public QMimeData +{ +public: + QVariant variantData(const QString &mime) { return retrieveData(mime, QVariant::Invalid); } +private: + QMacMimeData(); +}; + +QMacPasteboard::Promise::Promise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *md, int o, DataRequestType drt) + : itemId(itemId), offset(o), convertor(c), mime(m), dataRequestType(drt) +{ + // Request the data from the application immediately for eager requests. + if (dataRequestType == QMacPasteboard::EagerRequest) { + variantData = md->variantData(m); + mimeData = 0; + } else { + mimeData = md; + } +} + QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt) { mac_mime_source = false; @@ -103,6 +123,11 @@ QMacPasteboard::~QMacPasteboard() // commit all promises for paste after exit close for (int i = 0; i < promises.count(); ++i) { const Promise &promise = promises.at(i); + // At this point app teardown has started and control is somewhere in the Q[Core]Application + // destructor. Skip "lazy" promises where the application has not provided data; + // the application will generally not be in a state to provide it. + if (promise.dataRequestType == LazyRequest) + continue; QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime)); NSInteger pbItemId = promise.itemId; promiseKeeper(paste, reinterpret_cast(pbItemId), flavor, this); @@ -155,7 +180,17 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id, qPrintable(flavorAsQString), qPrintable(promise.convertor->convertorName()), promise.offset); #endif - QList md = promise.convertor->convertFromMime(promise.mime, promise.data, flavorAsQString); + // Get the promise data. If this is a "lazy" promise call variantData() + // to request the data from the application. + QVariant promiseData; + if (promise.dataRequestType == LazyRequest) { + if (!promise.mimeData.isNull()) + promiseData = promise.mimeData->variantData(promise.mime); + } else { + promiseData = promise.variantData; + } + + QList md = promise.convertor->convertFromMime(promise.mime, promiseData, flavorAsQString); if (md.size() <= promise.offset) return cantGetFlavorErr; const QByteArray &ba = md[promise.offset]; @@ -266,16 +301,8 @@ QMimeData return mime; } -class QMacMimeData : public QMimeData -{ -public: - QVariant variantData(const QString &mime) { return retrieveData(mime, QVariant::Invalid); } -private: - QMacMimeData(); -}; - void -QMacPasteboard::setMimeData(QMimeData *mime_src) +QMacPasteboard::setMimeData(QMimeData *mime_src, DataRequestType dataRequestType) { if (!paste) return; @@ -312,12 +339,17 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) continue; QString flavor(c->flavorFor(mimeType)); if (!flavor.isEmpty()) { - QVariant mimeData = static_cast(mime_src)->variantData(mimeType); + QMacMimeData *mimeData = static_cast(mime_src); int numItems = c->count(mime_src); for (int item = 0; item < numItems; ++item) { const NSInteger itemID = item+1; //id starts at 1 - promises.append(QMacPasteboard::Promise(itemID, c, mimeType, mimeData, item)); + //QMacPasteboard::Promise promise = (dataRequestType == QMacPasteboard::EagerRequest) ? + // QMacPasteboard::Promise::eagerPromise(itemID, c, mimeType, mimeData, item) : + // QMacPasteboard::Promise::lazyPromise(itemID, c, mimeType, mimeData, item); + + QMacPasteboard::Promise promise(itemID, c, mimeType, mimeData, item, dataRequestType); + promises.append(promise); PasteboardPutItemFlavor(paste, reinterpret_cast(itemID), QCFString(flavor), 0, kPasteboardFlavorNoFlags); #ifdef DEBUG_PASTEBOARD qDebug(" - adding %d %s [%s] <%s> [%d]", -- cgit v1.2.3 From f3699510d42e5ee910521c0463d9710f77ad4ff1 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Sun, 17 Nov 2013 14:59:03 +0100 Subject: Cocoa: Fix icon size calculation for system tray. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Overall goal is to make it possible to use correctly- sized pixmaps in a predictable way, while still doing something reasonable with small and large pixmaps. (The recommended pixmap height is up to 18 points.) Enable use of rectangular icons by selecting pixmaps based on pixmap height. Draw a low-resolution pixmap on retina displays if there is no high-resolution pixmap available. Scale large pixmaps to fit the available menu bar area. Add a manual-test with various pixmap sizes Task-number: QTBUG-33441 Change-Id: I1926181fe27cae526bae58022df3240bae9f8ac8 Reviewed-by: Morten Johan Sørvig Reviewed-by: Gabriel de Dietrich --- .../platforms/cocoa/qcocoasystemtrayicon.mm | 96 ++++++++++++++-------- 1 file changed, 64 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 83c960d931..e449fd37d6 100755 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -187,6 +187,14 @@ void QCocoaSystemTrayIcon::cleanup() m_sys = 0; } +static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); } +static QList sortByHeight(const QList sizes) +{ + QList sorted = sizes; + std::sort(sorted.begin(), sorted.end(), heightCompareFunction); + return sorted; +} + void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) { if (!m_sys) @@ -196,16 +204,62 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = hgt - 4; + // The reccomended maximum title bar icon height is 18 points + // (device independent pixels). The menu height on past and + // current OS X versions is 22 points. Provide some future-proofing + // by deriving the icon height from the menu height. + const int padding = 4; + const int menuHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + const int maxImageHeight = menuHeight - padding; + + // Select pixmap based on the device pixel height. Ideally we would use + // the devicePixelRatio of the target screen, but that value is not + // known until draw time. Use qApp->devicePixelRatio, which returns the + // devicePixelRatio for the "best" screen on the system. + qreal devicePixelRatio = qApp->devicePixelRatio(); + const int maxPixmapHeight = maxImageHeight * devicePixelRatio; + const QIcon::Mode mode = menuVisible ? QIcon::Selected : QIcon::Normal; + QSize selectedSize; + Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) { + // Select a pixmap based on the height. We want the largest pixmap + // with a height smaller or equal to maxPixmapHeight. The pixmap + // may rectangular; assume it has a reasonable size. If there is + // not suitable pixmap use the smallest one the icon can provide. + if (size.height() <= maxPixmapHeight) { + selectedSize = size; + } else { + if (!selectedSize.isValid()) + selectedSize = size; + break; + } + } - QPixmap pm = m_sys->item->icon.pixmap(QSize(scale, scale), - menuVisible ? QIcon::Selected : QIcon::Normal); - if (pm.isNull()) { - pm = QPixmap(scale, scale); - pm.fill(Qt::transparent); + QPixmap pixmap = icon.pixmap(selectedSize, mode); + + // Draw a low-resolution icon if there is not enough pixels for a retina + // icon. This prevents showing a small icon on retina displays. + if (devicePixelRatio > 1.0 && selectedSize.height() < maxPixmapHeight / 2) + devicePixelRatio = 1.0; + + // Scale large pixmaps to fit the available menu bar area. + if (pixmap.height() > maxPixmapHeight) + pixmap = pixmap.scaledToHeight(maxPixmapHeight, Qt::SmoothTransformation); + + // The icon will be stretched over the full height of the menu bar + // therefore we create a second pixmap which has the full height + QSize fullHeightSize(!pixmap.isNull() ? pixmap.width(): + menuHeight * devicePixelRatio, + menuHeight * devicePixelRatio); + QPixmap fullHeightPixmap(fullHeightSize); + fullHeightPixmap.fill(Qt::transparent); + if (!pixmap.isNull()) { + QPainter p(&fullHeightPixmap); + QRect r = pixmap.rect(); + r.moveCenter(fullHeightPixmap.rect().center()); + p.drawPixmap(r, pixmap); } - NSImage *nsimage = static_cast(qt_mac_create_nsimage(pm)); + + NSImage *nsimage = static_cast(qt_mac_create_nsimage(fullHeightPixmap)); [(NSImageView*)[[m_sys->item item] view] setImage: nsimage]; [nsimage release]; } @@ -327,18 +381,7 @@ QT_END_NAMESPACE Q_UNUSED(notification); down = NO; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = hgt - 4; - - QPixmap pm = parent->icon.pixmap(QSize(scale, scale), QIcon::Normal); - if (pm.isNull()) { - pm = QPixmap(scale, scale); - pm.fill(Qt::transparent); - } - NSImage *nsaltimage = static_cast(qt_mac_create_nsimage(pm)); - [self setImage: nsaltimage]; - [nsaltimage release]; - + parent->systray->updateIcon(parent->icon); parent->menuVisible = false; [self setNeedsDisplay:YES]; @@ -350,18 +393,7 @@ QT_END_NAMESPACE int clickCount = [mouseEvent clickCount]; [self setNeedsDisplay:YES]; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = hgt - 4; - - QPixmap pm = parent->icon.pixmap(QSize(scale, scale), - parent->menuVisible ? QIcon::Selected : QIcon::Normal); - if (pm.isNull()) { - pm = QPixmap(scale, scale); - pm.fill(Qt::transparent); - } - NSImage *nsaltimage = static_cast(qt_mac_create_nsimage(pm)); - [self setImage: nsaltimage]; - [nsaltimage release]; + parent->systray->updateIcon(parent->icon); if (clickCount == 2) { [self menuTrackingDone:nil]; -- cgit v1.2.3 From ed0245e1452f94918853b7d4066c1e5749b74f5d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Oct 2014 12:24:52 +0200 Subject: Fix QWidget::mapTo/FromGlobal() when embedded in QGraphicsView. Map the positions via QGraphicsScene and the first QGraphicsView (as is done in existing code). Fall back to the previous code path when no QGraphicsView exists, which is hit in the tests. Change-Id: I0754765d05cded6bc1b64045f2513fef8afde337 Task-number: QTBUG-41135 Reviewed-by: Frederik Gladhorn --- src/widgets/kernel/qwidget.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 455d195159..b421d5debc 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12250,6 +12250,17 @@ QPaintEngine *QWidget::paintEngine() const */ QPoint QWidget::mapToGlobal(const QPoint &pos) const { +#ifndef QT_NO_GRAPHICSVIEW + Q_D(const QWidget); + if (d->extra && d->extra->proxyWidget) { + const QList views = d->extra->proxyWidget->scene()->views(); + if (!views.isEmpty()) { + const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); + const QPoint viewPortPos = views.first()->mapFromScene(scenePos); + return views.first()->viewport()->mapToGlobal(viewPortPos); + } + } +#endif // !QT_NO_GRAPHICSVIEW int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { @@ -12274,6 +12285,17 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const */ QPoint QWidget::mapFromGlobal(const QPoint &pos) const { +#ifndef QT_NO_GRAPHICSVIEW + Q_D(const QWidget); + if (d->extra && d->extra->proxyWidget) { + const QList views = d->extra->proxyWidget->scene()->views(); + if (!views.isEmpty()) { + const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); + const QPointF scenePos = views.first()->mapToScene(viewPortPos); + return d->extra->proxyWidget->mapFromScene(scenePos).toPoint(); + } + } +#endif // !QT_NO_GRAPHICSVIEW int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { -- cgit v1.2.3 From c30ccb0ecdfa08fbadfa8bd40a67a0efb6eaadde Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Oct 2014 14:57:45 +0200 Subject: Fix title font of Vista-style wizards. Reverse invalid check. Task-number: QTBUG-41878 Change-Id: I05015407e5cfad94aca65594962b897a1d0a0cbd Reviewed-by: Alessandro Portale --- src/widgets/dialogs/qwizard_win.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 6a09f9c273..69761473fc 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -653,10 +653,7 @@ HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) { LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; - if (!hTheme) - pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf); - else - { + if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf))) { NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); -- cgit v1.2.3 From e5c1572e7eafbce26ca5835c7fe1682bfb69d92b Mon Sep 17 00:00:00 2001 From: Axel Rasmussen Date: Sun, 19 Oct 2014 11:09:37 -0600 Subject: Fix uninitialized value warning in QFontEngineFT. When running an application which called e.g. QPainter::drawText under Valgrind, it would produce "Conditional jump or move depends on uninitialized value(s)" warnings, since we were allocating a buffer for a FreeType bitmap without initializing its contents. FreeType, apparently, does not set the value of all bytes in a bitmap buffer when it is used as a FT_Bitmap, so we were left with some uninitialized memory which was still being used. This commit fixes these warnings, and prevents any potential undefined behavior. [ChangeLog][QtGui][General] fixed use of uninitialized memory in the FreeType font engine Change-Id: Ia7b3595c78310ce41f76cb4546fc36016c0000a8 Reviewed-by: Konstantin Ritt --- src/gui/text/qfontengine_ft.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 6dd8585483..b0cfa49b36 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1062,6 +1062,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); glyph_buffer_size = pitch * info.height; glyph_buffer = new uchar[glyph_buffer_size]; + memset(glyph_buffer, 0, glyph_buffer_size); if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Bitmap bitmap; -- cgit v1.2.3 From bf200fc948d89e1a735a8bcca879654028f944d2 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Mon, 20 Oct 2014 15:40:18 +0200 Subject: Adjust the layout if a QGraphicsWidget is explicitly hidden Since layout items can now be hidden, this also makes sure we respect the QSizePolicy::retainSizeWhenHidden Task-number: QTBUG-20132 Change-Id: Iab59fc9b61d4ca1bb2208c479a027da6eb0283a9 Reviewed-by: Paul Olav Tvete --- src/gui/util/qgridlayoutengine.cpp | 2 +- src/gui/util/qgridlayoutengine_p.h | 1 + .../graphicsview/qgraphicsgridlayoutengine.cpp | 20 ++++++++++++++++++++ .../graphicsview/qgraphicsgridlayoutengine_p.h | 4 ++++ src/widgets/graphicsview/qgraphicswidget.cpp | 4 ++++ 5 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp index ed15e460f3..65f2297fce 100644 --- a/src/gui/util/qgridlayoutengine.cpp +++ b/src/gui/util/qgridlayoutengine.cpp @@ -1289,7 +1289,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation)) rowIsIdenticalToPrevious = false; - if (item) + if (item && !item->isIgnored()) rowIsEmpty = false; } diff --git a/src/gui/util/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h index bf34e816b5..b75312bfe8 100644 --- a/src/gui/util/qgridlayoutengine_p.h +++ b/src/gui/util/qgridlayoutengine_p.h @@ -295,6 +295,7 @@ public: virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const = 0; virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0; + virtual bool isIgnored() const { return false; } virtual void setGeometry(const QRectF &rect) = 0; /* diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp index 3d9c5d6de5..c9b2ecd62c 100644 --- a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp +++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp @@ -38,9 +38,29 @@ #include "qgraphicslayoutitem_p.h" #include "qgraphicslayout_p.h" #include "qgraphicswidget.h" +#include QT_BEGIN_NAMESPACE +bool QGraphicsGridLayoutEngineItem::isHidden() const +{ + if (QGraphicsItem *item = q_layoutItem->graphicsItem()) + return QGraphicsItemPrivate::get(item)->explicitlyHidden; + return false; +} + +/*! + \internal + + If this returns true, the layout will arrange just as if the item was never added to the layout. + (Note that this shouldn't lead to a "double spacing" where the item was hidden) + ### Qt6: Move to QGraphicsLayoutItem and make virtual +*/ +bool QGraphicsGridLayoutEngineItem::isIgnored() const +{ + return isHidden() && !q_layoutItem->sizePolicy().retainSizeWhenHidden(); +} + /* returns \c true if the size policy returns \c true for either hasHeightForWidth() or hasWidthForHeight() diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h index 4d6bdfce0a..07486514f8 100644 --- a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h +++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h @@ -82,6 +82,10 @@ public: return q_layoutItem->effectiveSizeHint(which, constraint); } + bool isHidden() const; + + virtual bool isIgnored() const Q_DECL_OVERRIDE; + virtual void setGeometry(const QRectF &rect) Q_DECL_OVERRIDE { q_layoutItem->setGeometry(rect); diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 4a9c3b098e..5bd563e535 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -1137,6 +1137,10 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & setAttribute(Qt::WA_Resized, false); } } + + // layout size hint only changes if an item changes from/to explicitly hidden state + if (value.toBool() || d->explicitlyHidden) + updateGeometry(); break; case ItemVisibleHasChanged: if (!value.toBool()) { -- cgit v1.2.3 From c399e4b7ea0b10dd7eb71ebe3ccea3c6134f25ba Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Oct 2014 15:43:40 +0200 Subject: Q{Sequential,Associative}Iterable: fix const_iterator assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code didn't properly clean up the current state before assigning the new state. Change-Id: If56cf43bace976203ff186759b2a81705b2b22d2 Reviewed-by: Stephen Kelly Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qvariant.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index cea893ba0c..2ac1bb11fb 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3632,11 +3632,13 @@ QSequentialIterable::const_iterator::const_iterator(const const_iterator &other) QSequentialIterable::const_iterator& QSequentialIterable::const_iterator::operator=(const const_iterator &other) { - if (!m_impl.equal(other.m_impl)) { - m_impl = other.m_impl; - ref = other.ref; + other.ref->ref(); + if (!ref->deref()) { + m_impl.destroyIter(); + delete ref; } - ref->ref(); + m_impl = other.m_impl; + ref = other.ref; return *this; } @@ -3941,11 +3943,13 @@ QAssociativeIterable::const_iterator::const_iterator(const const_iterator &other QAssociativeIterable::const_iterator& QAssociativeIterable::const_iterator::operator=(const const_iterator &other) { - if (!m_impl.equal(other.m_impl)) { - m_impl = other.m_impl; - ref = other.ref; + other.ref->ref(); + if (!ref->deref()) { + m_impl.destroyIter(); + delete ref; } - ref->ref(); + m_impl = other.m_impl; + ref = other.ref; return *this; } -- cgit v1.2.3 From 3056b825bd22ddf17deee03c5c43117ad6aa545e Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Mon, 20 Oct 2014 17:51:02 +0300 Subject: Fix styled vertical dockwidget title cut off bug and elide text if long Change common stylesheet to elide text correctly for both direction. Change-Id: I045f6f74733ca8fa67b3e4fbb9d3845a1bea777d Task-number: QTBUG-41466 Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qstylesheetstyle.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index a6c7f5dde2..a9e13bad49 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4047,26 +4047,28 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q } if (!dwOpt->title.isEmpty()) { - QRect r = opt->rect; + QRect r = subElementRect(SE_DockWidgetTitleBarText, opt, w); if (dwOpt->verticalTitleBar) { QSize s = r.size(); s.transpose(); r.setSize(s); - p->save(); p->translate(r.left(), r.top() + r.width()); p->rotate(-90); p->translate(-r.left(), -r.top()); } + r = subRule.contentsRect(r); Qt::Alignment alignment = 0; if (subRule.hasPosition()) alignment = subRule.position()->textAlignment; if (alignment == 0) alignment = Qt::AlignLeft; - drawItemText(p, subRule.contentsRect(opt->rect), + + QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, r.width()); + drawItemText(p, r, alignment | Qt::TextShowMnemonic, dwOpt->palette, - dwOpt->state & State_Enabled, dwOpt->title, + dwOpt->state & State_Enabled, titleText, QPalette::WindowText); if (dwOpt->verticalTitleBar) -- cgit v1.2.3 From f81e76da1e8520866616c2fe9e46547b9201f202 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 20 Oct 2014 18:16:08 +0300 Subject: Allow QtCreator to pass additional args and env vars to the application. We need them to allow developers to easily pass args and env. vars like QSG_RENDER_TIMINGS, QSG_VISUALIZE to theirs apps. The env vars and params must be base64 encoded! Change-Id: I1d781873ffdc6efd40b30543a9fd2514bbdede43 Reviewed-by: Paul Olav Tvete --- .../org/qtproject/qt5/android/QtActivityDelegate.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index ed5be81d80..7642bc38b5 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -55,6 +55,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.text.method.MetaKeyKeyListener; +import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; @@ -660,6 +661,22 @@ public class QtActivityDelegate m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; } + if (extras.containsKey("extraenvvars")) { + try { + m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (extras.containsKey("extraappparams")) { + try { + m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (null == m_surfaces) onCreate(null); String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_activity); -- cgit v1.2.3 From 15377a6927a2df1dcf5592eea411ac1f0dd24840 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 20 Oct 2014 16:51:08 +0200 Subject: Doc: Fix description of QTranslator::translate() If the translations are incomplete it's actually not ensured that a translation without disambiguation is used: lrelease will drop the disambiguation from one of the identical messages if there is no message which actually has no disambiguation ... Task-number: QTBUG-30471 Change-Id: I1787f5c401a7afb964acbf8a8609ba328c8140a9 Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qtranslator.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index d0fa0613b3..33827926c6 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -1086,6 +1086,11 @@ void QTranslatorPrivate::clear() \a disambiguation). If none is found, also tries (\a context, \a sourceText, ""). If that still fails, returns a null string. + \note Incomplete translations may result in unexpected behavior: + If no translation for (\a context, \a sourceText, "") + is provided, the method might in this case actually return a + translation for a different \a disambiguation. + If \a n is not -1, it is used to choose an appropriate form for the translation (e.g. "%n file found" vs. "%n files found"). -- cgit v1.2.3 From 04912b6a3bcff9087d0679b224cfccee3c05bd10 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 10 Oct 2014 13:20:12 +0200 Subject: Don't use cosmetic GDI pens as this is already accounted for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Qt will already handle the cosmetic case when rendering then it should be respected instead of overriding it by using the cosmetic GDI pen. This ensures that the pen's width is used and also the color of the pen. Task-number: QTBUG-33611 Change-Id: I2719311b3fb5480a5b228c0d415aa545967321cf Reviewed-by: Jan Arve Sæther Reviewed-by: Friedemann Kleint --- src/printsupport/kernel/qprintengine_win.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 14ffcaca96..a1a2f97abe 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -734,10 +734,7 @@ void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QC else if (pen.joinStyle() == Qt::RoundJoin) joinStyle = PS_JOIN_ROUND; - bool cosmetic = qt_pen_is_cosmetic(pen, q->state->renderHints()); - - HPEN pen = ExtCreatePen((cosmetic ? PS_COSMETIC : PS_GEOMETRIC) - | PS_SOLID | capStyle | joinStyle, + HPEN pen = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | capStyle | joinStyle, (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); HGDIOBJ old_pen = SelectObject(hdc, pen); -- cgit v1.2.3 From 591bce8f6877ffb8e4ab81330ec077231eb2aab7 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 17 Oct 2014 12:48:02 +0200 Subject: Get the correct available resolutions from the printer On Windows the resolutions are available in pairs so get the y resolution from each pair as the y resolution is the one that is actually useful in QtPrintSupport terms Task-number: QTBUG-42007 Change-Id: I02c0588dd97c541e679f22431435751563caadb2 Reviewed-by: Friedemann Kleint --- src/plugins/printsupport/windows/qwindowsprintdevice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 0a21193216..0feea5ea74 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -280,11 +280,11 @@ void QWindowsPrintDevice::loadResolutions() const { DWORD resCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, NULL, NULL); if (int(resCount) > 0) { - QScopedArrayPointer resolutions(new LONG[resCount*sizeof(LONG)]); + QScopedArrayPointer resolutions(new LONG[resCount*2]); // Get the details and match the default paper size if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, (LPWSTR)resolutions.data(), NULL) == resCount) { - for (int i = 0; i < int(resCount); ++i) - m_resolutions.append(resolutions[i]); + for (int i = 0; i < int(resCount * 2); i += 2) + m_resolutions.append(resolutions[i+1]); } } m_haveResolutions = true; -- cgit v1.2.3 From 876a428f609f35dc7e9517555abd17e7c6b01693 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 22 Oct 2014 17:53:24 +0200 Subject: Cocoa: avoid sending exposes too early Expose events trigger backing store sync and thus paint events on QGLWidgets. Sending the exposes too early may lead to failures in the OpenGL calls. Sending exposes before even getting to calling setVisible(true) in QWidget::show() is just wrong. Task-number: QTBUG-36802 Change-Id: Ic7d5125f4e257d715009811217e453d79d0fcc7c Reviewed-by: Gunnar Sletta --- src/plugins/platforms/cocoa/qnsview.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 9cd075fdec..4cb8fbb451 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -361,8 +361,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; // Send a geometry change event to Qt, if it's ready to handle events if (!m_platformWindow->m_inConstructor) { QWindowSystemInterface::handleGeometryChange(m_window, geometry); - m_platformWindow->updateExposedGeometry(); - QWindowSystemInterface::flushWindowSystemEvents(); + // Do not send incorrect exposes in case the window is not even visible yet. + // We might get here as a result of a resize() from QWidget's show(), for instance. + if (m_platformWindow->window()->isVisible()) { + m_platformWindow->updateExposedGeometry(); + QWindowSystemInterface::flushWindowSystemEvents(); + } } } -- cgit v1.2.3 From 0b0746355c4e120bed4980c07476a1ccb949a951 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 23 Oct 2014 13:01:36 +0200 Subject: Fix software OpenGL DLL name in the enum docs Change-Id: I85c664914a391002afbda0fe203c90397b0bb5c2 Reviewed-by: Kai Koehne Reviewed-by: Friedemann Kleint --- src/corelib/global/qnamespace.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index bf558e48f6..0d4a0bcedf 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -182,7 +182,7 @@ \l{http://www.mesa3d.org/llvmpipe.html}{Mesa llvmpipe}, providing OpenGL 2.1. The value may have no effect if no such OpenGL implementation is available. The default name of this library is - QtSoftwareOpenGL.dll and can be overridden by setting the environment + opengl32sw.dll and can be overridden by setting the environment variable \e QT_OPENGL_DLL. See the platform-specific pages, for instance \l{Qt for Windows}, for more information. This value has been added in Qt 5.4. -- cgit v1.2.3 From feaa1e6373912c2a86ea6603d52c1a400ec38957 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 23 Oct 2014 13:02:17 +0200 Subject: Add missing since info to ShareOpenGLContexts docs Change-Id: I5e42cfd520ab65f7dbeecf152861f977011fe6f9 Reviewed-by: Friedemann Kleint --- src/corelib/global/qnamespace.qdoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 0d4a0bcedf..4e074bcdb5 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -190,7 +190,8 @@ \value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL contexts used by classes like QOpenGLWidget and QQuickWidget. This allows sharing OpenGL resources, like textures, between QOpenGLWidget - instances that belong to different top-level windows. + instances that belong to different top-level windows. This value has + been added in Qt 5.4. The following values are obsolete: -- cgit v1.2.3 From ab79e832e602b6366340151720b8c7c7b7ddb1a3 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Wed, 22 Oct 2014 13:51:30 +0200 Subject: Do not parent the shader program to the QOpenGLContext When the last QOpenGLContext in a share group is destroyed, all the remaining alive QOpenGL* objects have their resource invalidated. This happens under QOpenGLContext::destroy, but before any QObject children of the QOpenGLContext is destroyed by the QObject destructor. This is currently an issue with ANGLE that could be fixed in its own code, but that is still better for us to be covered against. This means that the OpenGL resource is assumed to be destroyed with the context by the driver, but this isn't always the same. Fix an instance of this in QOpenGLTextureGlyphCache by explicitly owning the blit QOpenGLShaderProgram instead of parenting it under the current GL context. The very same resource invalidation system will prevent anything bad to happen if the QOpenGLContext is destroyed before the QOpenGLTextureGlyphCache. Task-number: QTBUG-41588 Change-Id: Ic3bc69b07bcbdcf7d699ea9139b2e34b04e642e5 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltextureglyphcache.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 6e16b2df75..0f70a01014 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -240,7 +240,7 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) QOpenGLShaderProgram *blitProgram = 0; if (pex == 0) { if (m_blitProgram == 0) { - m_blitProgram = new QOpenGLShaderProgram(ctx); + m_blitProgram = new QOpenGLShaderProgram; const bool isCoreProfile = ctx->format().profile() == QSurfaceFormat::CoreProfile; { @@ -444,6 +444,9 @@ void QOpenGLTextureGlyphCache::clear() m_textureResource->free(); m_textureResource = 0; + delete m_blitProgram; + m_blitProgram = 0; + m_w = 0; m_h = 0; m_cx = 0; -- cgit v1.2.3 From 88057e3407aa16d0a9dc9dcc6d0ea6174dce693b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Oct 2014 17:31:55 +0200 Subject: QSwipeGestureRecognizer: Fix gesture cancel on direction change. Task-number: QTBUG-12736 Change-Id: I6d8d09843b45df17cb9158070f63b3397c5b4c07 Reviewed-by: Lars Knoll Reviewed-by: Frederik Gladhorn --- src/widgets/kernel/qstandardgestures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp index 78a2c65060..0822c04033 100644 --- a/src/widgets/kernel/qstandardgestures.cpp +++ b/src/widgets/kernel/qstandardgestures.cpp @@ -341,10 +341,10 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state, if (d->horizontalDirection == QSwipeGesture::NoDirection) d->horizontalDirection = horizontal; if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) { - // the user has changed the direction! result = QGestureRecognizer::CancelGesture; + } else { + result = QGestureRecognizer::TriggerGesture; } - result = QGestureRecognizer::TriggerGesture; } else { if (q->state() != Qt::NoGesture) result = QGestureRecognizer::TriggerGesture; -- cgit v1.2.3 From d6d3841e71473d3e9253b3088bc4094a7546600e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 22 Oct 2014 17:03:48 +0200 Subject: Improve QDebug formatting of QtSql classes. Fix quoting/spaces, introduce QDebugStateSaver, add missing fields of QSqlField. Task-number: QTBUG-39388 Change-Id: Id397f9e79f4d4d2bb5c903cd96bf2c27f8e1b7c3 Reviewed-by: Kai Koehne --- src/sql/kernel/qsqldatabase.cpp | 15 +++++++++------ src/sql/kernel/qsqlerror.cpp | 8 +++++--- src/sql/kernel/qsqlfield.cpp | 23 +++++++++++++---------- src/sql/kernel/qsqlrecord.cpp | 13 ++++++++++--- 4 files changed, 37 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 31f0e2dc9e..dbc95dc5a8 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -1503,15 +1503,18 @@ QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QSqlDatabase &d) { + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg.noquote(); if (!d.isValid()) { - dbg.nospace() << "QSqlDatabase(invalid)"; - return dbg.space(); + dbg << "QSqlDatabase(invalid)"; + return dbg; } - dbg.nospace() << "QSqlDatabase(driver=\"" << d.driverName() << "\", database=\"" - << d.databaseName() << "\", host=\"" << d.hostName() << "\", port=" << d.port() - << ", user=\"" << d.userName() << "\", open=" << d.isOpen() << ")"; - return dbg.space(); + dbg << "QSqlDatabase(driver=\"" << d.driverName() << "\", database=\"" + << d.databaseName() << "\", host=\"" << d.hostName() << "\", port=" << d.port() + << ", user=\"" << d.userName() << "\", open=" << d.isOpen() << ')'; + return dbg; } #endif diff --git a/src/sql/kernel/qsqlerror.cpp b/src/sql/kernel/qsqlerror.cpp index b80b471dfc..470bf57d44 100644 --- a/src/sql/kernel/qsqlerror.cpp +++ b/src/sql/kernel/qsqlerror.cpp @@ -39,9 +39,11 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QSqlError &s) { - dbg.nospace() << "QSqlError(" << s.nativeErrorCode() << ", " << s.driverText() << - ", " << s.databaseText() << ')'; - return dbg.space(); + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg << "QSqlError(" << s.nativeErrorCode() << ", " << s.driverText() + << ", " << s.databaseText() << ')'; + return dbg; } #endif diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp index dfd4712071..3fd2c68296 100644 --- a/src/sql/kernel/qsqlfield.cpp +++ b/src/sql/kernel/qsqlfield.cpp @@ -509,21 +509,24 @@ bool QSqlField::isValid() const #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QSqlField &f) { - dbg.nospace() << "QSqlField(" << f.name() << ", " << QMetaType::typeName(f.type()); + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg << "QSqlField(" << f.name() << ", " << QMetaType::typeName(f.type()); if (f.length() >= 0) - dbg.nospace() << ", length: " << f.length(); + dbg << ", length: " << f.length(); if (f.precision() >= 0) - dbg.nospace() << ", precision: " << f.precision(); + dbg << ", precision: " << f.precision(); if (f.requiredStatus() != QSqlField::Unknown) - dbg.nospace() << ", required: " - << (f.requiredStatus() == QSqlField::Required ? "yes" : "no"); - dbg.nospace() << ", generated: " << (f.isGenerated() ? "yes" : "no"); + dbg << ", required: " + << (f.requiredStatus() == QSqlField::Required ? "yes" : "no"); + dbg << ", generated: " << (f.isGenerated() ? "yes" : "no"); if (f.typeID() >= 0) - dbg.nospace() << ", typeID: " << f.typeID(); + dbg << ", typeID: " << f.typeID(); if (!f.defaultValue().isNull()) - dbg.nospace() << ", auto-value: \"" << f.defaultValue() << '\"'; - dbg.nospace() << ')'; - return dbg.space(); + dbg << ", defaultValue: \"" << f.defaultValue() << '\"'; + dbg << ", autoValue: " << f.isAutoValue() + << ", readOnly: " << f.isReadOnly() << ')'; + return dbg; } #endif diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp index 7fd64d1307..668392bb5b 100644 --- a/src/sql/kernel/qsqlrecord.cpp +++ b/src/sql/kernel/qsqlrecord.cpp @@ -509,9 +509,16 @@ void QSqlRecord::detach() #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QSqlRecord &r) { - dbg << "QSqlRecord(" << r.count() << ')'; - for (int i = 0; i < r.count(); ++i) - dbg << '\n' << QString::fromLatin1("%1:").arg(i, 2) << r.field(i) << r.value(i).toString(); + QDebugStateSaver saver(dbg); + dbg.nospace(); + const int count = r.count(); + dbg << "QSqlRecord(" << count << ')'; + for (int i = 0; i < count; ++i) { + dbg.nospace(); + dbg << '\n' << qSetFieldWidth(2) << right << i << left << qSetFieldWidth(0) << ':'; + dbg.space(); + dbg << r.field(i) << r.value(i).toString(); + } return dbg; } #endif -- cgit v1.2.3 From 575008ec81d7bffc8b7ce631fa8f21377aada7cf Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 23 Oct 2014 19:48:23 +1000 Subject: Fix bogus error report when disconnect/stop actually works The interfaces serviceActive does not mean the network is connected, so we get the next best thing - the interfaces associated ssid will be empty if a previously connected AP is now disconnected. Task-number: QTBUG-42087 Change-Id: I539811d9f18cc553a4022a03686fb8a864b98491 Reviewed-by: Alex Blasche --- src/plugins/bearer/corewlan/qcorewlanengine.h | 2 ++ src/plugins/bearer/corewlan/qcorewlanengine.mm | 34 ++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h index 930bde40b3..50bdab0ea6 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.h +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -83,6 +83,7 @@ public: private Q_SLOTS: void doRequestUpdate(); void networksChanged(); + void checkDisconnect(); private: bool isWifiReady(const QString &dev); @@ -95,6 +96,7 @@ private: QScanThread *scanThread; quint64 getBytes(const QString &interfaceName,bool b); + QString disconnectedInterfaceString; protected: void startNetworkChangeLoop(); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 65e70876f2..8caca7d677 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -544,20 +544,44 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) QMutexLocker locker(&mutex); QString interfaceString = getInterfaceFromId(id); + if (interfaceString.isEmpty()) { + locker.unlock(); + emit connectionError(id, DisconnectionError); + return; + } NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; CWInterface *wifiInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceString)]; + disconnectedInterfaceString = interfaceString; [wifiInterface disassociate]; - if (wifiInterface.serviceActive) { - locker.unlock(); - emit connectionError(id, DisconnectionError); - locker.relock(); - } + + QTimer::singleShot(1000, this,SLOT(checkDisconnect())); [autoreleasepool release]; } +void QCoreWlanEngine::checkDisconnect() +{ + QMutexLocker locker(&mutex); + if (!disconnectedInterfaceString.isEmpty()) { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + + CWInterface *wifiInterface = + [CWInterface interfaceWithName: QCFString::toNSString(disconnectedInterfaceString)]; + + const QString networkSsid = QCFString::toQString([wifiInterface ssid]); + if (!networkSsid.isEmpty()) { + const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); + locker.unlock(); + emit connectionError(id, DisconnectionError); + locker.relock(); + } + [autoreleasepool release]; + disconnectedInterfaceString.clear(); + } +} + void QCoreWlanEngine::requestUpdate() { scanThread->getUserConfigurations(); -- cgit v1.2.3 From 77339e6bbf8baec5c15b604adbc03ab41cb37595 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 20 Oct 2014 13:41:21 +0200 Subject: Doc: warn about preserving input method hints Task-number: QTBUG-41252 Change-Id: I8ea2094c440b3c78b4bc78a69a5f6b18533e4927 Reviewed-by: Venugopal Shivashankar --- src/widgets/kernel/qwidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b421d5debc..7533cacbdc 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9663,6 +9663,10 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const is set, the input method may change its visual components to reflect that only numbers can be entered. + \warning Some widgets require certain flags in order to work as + intended. To set a flag, do \c{w->setInputMethodHints(w->inputMethodHints()|f)} + instead of \c{w->setInputMethodHints(f)}. + \note The flags are only hints, so the particular input method implementation is free to ignore them. If you want to be sure that a certain type of characters are entered, -- cgit v1.2.3 From 2bfee10f3ab8e8e33b2169d735baedcdd9f2b584 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 22 Oct 2014 13:47:55 +0200 Subject: QMainWindow: respect the maximum size of the central widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the dock widgets get the available space when the central widget cannot expand any more. [ChangeLog][QtWidgets][QMainWindow] Dock widgets will now be resized properly when the central widget has a fixed size. Task-number: QTBUG-40410 Change-Id: Id06c07b79aa3102aa41212fa2c621f5fa426fe02 Reviewed-by: Friedemann Kleint Reviewed-by: Jan Arve Sæther --- src/widgets/widgets/qdockarealayout.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 7ac2791112..702cd8bac9 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2575,12 +2575,14 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, { QSize center_hint(0, 0); QSize center_min(0, 0); + QSize center_max(0, 0); const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); if (have_central) { center_hint = centralWidgetRect.size(); if (!center_hint.isValid()) center_hint = centralWidgetItem->sizeHint(); center_min = centralWidgetItem->minimumSize(); + center_max = centralWidgetItem->maximumSize(); } QRect center_rect = rect; @@ -2656,7 +2658,7 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, left = (tl_significant && bl_significant) ? left_min.height() : 0; right = (tr_significant && br_significant) ? right_min.height() : 0; ver_struct_list[1].minimumSize = qMax(left, center_min.height(), right); - ver_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0; + ver_struct_list[1].maximumSize = center_max.height(); ver_struct_list[1].expansive = have_central; ver_struct_list[1].empty = docks[QInternal::LeftDock].isEmpty() && !have_central @@ -2717,7 +2719,7 @@ void QDockAreaLayout::getGrid(QVector *_ver_struct_list, bottom = (bl_significant && br_significant) ? bottom_min.width() : 0; hor_struct_list[1].minimumSize = qMax(top, center_min.width(), bottom); - hor_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0; + hor_struct_list[1].maximumSize = center_max.width(); hor_struct_list[1].expansive = have_central; hor_struct_list[1].empty = !have_central; hor_struct_list[1].pos = center_rect.left(); -- cgit v1.2.3 From 624740cdcdd4abfb15bbbc8a8aa056c57712499f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Oct 2014 14:09:01 +0200 Subject: Fix printing of semitransparent images to PDF The patch marks the image data to be inverted when a soft mask is used. Without this any embedded image with semitransparent pixels would be decoded with inverted colors. Task-number: QTBUG-31540 Change-Id: Ia607f7c1acf542ecf3bc88d713dfd87785b43f40 Reviewed-by: Lars Knoll --- src/gui/painting/qpdf.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 6ea002a761..1da0c6b65f 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -2083,8 +2083,10 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, } if (maskObject > 0) xprintf("/Mask %d 0 R\n", maskObject); - if (softMaskObject > 0) + if (softMaskObject > 0) { xprintf("/SMask %d 0 R\n", softMaskObject); + xprintf("/Decode [1 0 1 0 1 0]\n"); + } int lenobj = requestObject(); xprintf("/Length %d 0 R\n", lenobj); -- cgit v1.2.3 From 3272ef4aaf14b72e0bab4698e4ad40b76a3d23d9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Oct 2014 10:50:28 +0200 Subject: Respect NoSubpixelAntialias in QCoreTextFontEngine::imageForGlyph Adding handling of the new QFont enum NoSubpixelAntialias in QCoreTextFontEngine::imageForGlyph. Task-number: QTBUG-40396 Change-Id: I421c38554360f5e2f822a18117190456c4d04b25 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Konstantin Ritt --- src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index f96163fc5b..2859886d59 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -577,9 +577,10 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition cgflags); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > antialiasingThreshold) - && !(fontDef.styleStrategy & QFont::NoAntialias)); - CGContextSetShouldSmoothFonts(ctx, aa); + const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold) && !(fontDef.styleStrategy & QFont::NoAntialias); + CGContextSetShouldAntialias(ctx, antialias); + const bool smoothing = antialias && !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); + CGContextSetShouldSmoothFonts(ctx, smoothing); CGAffineTransform cgMatrix = CGAffineTransformIdentity; -- cgit v1.2.3 From b79ba9eade2e1b1a8607046ecbe61eba4f063e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 22 Oct 2014 01:52:01 +0200 Subject: Cocoa: Fix trackpad scrolling modifiers. We would reset the keyboard modifier state on NSEventPhaseEnded, which meant that the state would be NoModifier as soon as the fingers left the trackpad. We want the modifier state to stay constant for the duration of the gesture. Remove the "reset" code and rely on setting currentWheelModifiers on NSEventPhaseNone only. Task-number: QTBUG-40197 Change-Id: I615aa5e1148b2b824f1a585bc042c9dbb3f1f250 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4cb8fbb451..9b6a3f9ef4 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1359,10 +1359,6 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) } QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph); - - if (momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled || momentumPhase == NSEventPhaseNone) { - currentWheelModifiers = Qt::NoModifier; - } } else #endif { -- cgit v1.2.3 From 4d7e587a78799a390968615cdfe02a30f566a337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 26 Jun 2014 15:21:26 +0200 Subject: Don't flush user input events from setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applications do not expect user input event delivery during QCocoaWindow::setVisible. The call to flushWindowSystemEvents still needs to be here for proper expose event processing, but we can at least exclude user input events. Task-number: QTBUG-39842 Change-Id: Ibd511efef47eeda21831481ef096a82d7b5a9cf8 Reviewed-by: Jonathan Liu Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 9259c2c772..b680c01c09 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -699,7 +699,7 @@ void QCocoaWindow::setVisible(bool visible) exposeWindow(); if (m_nsWindow) { - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // setWindowState might have been called while the window was hidden and // will not change the NSWindow state in that case. Sync up here: -- cgit v1.2.3 From a38ecb4c67432b55c3040f0bcc79fa3f8d875690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 21 Oct 2014 14:51:29 +0200 Subject: Cocoa: Don't send FrameStrut events during drags Check the (normal) button state and return early if there is a pressed button. Task-number: QTBUG-41609 Change-Id: I69d23f02e55627ca3e03f2466103e0952ff442b3 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 9b6a3f9ef4..aa57fc211e 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -721,6 +721,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent { // get m_buttons in sync + // Don't send frme strut events if we are in the middle of a mouse drag. + if (m_buttons != Qt::NoButton) + return; + NSEventType ty = [theEvent type]; switch (ty) { case NSLeftMouseDown: -- cgit v1.2.3 From f08e6511bb9555e864f715550d4a838bc46fa33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 22 Oct 2014 00:26:22 +0200 Subject: Cocoa: Bring back qt_mac_set_raise_process In the form of an environment variable: QT_MAC_SET_RAISE_PROCESS. The default value is "on". Task-number: QTBUG-41569 Change-Id: Icf2e8818a6b126c7393ee022a1cab493fbc3a18e Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b680c01c09..3366e5bc3c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1009,9 +1009,12 @@ void QCocoaWindow::raise() [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove]; } else { [m_nsWindow orderFront: m_nsWindow]; - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); + static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); + if (raiseProcess) { + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); + } } } } -- cgit v1.2.3 From 0f644f48530f4693f7c77fd41ca42085b3218e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 23 Oct 2014 11:48:45 +0200 Subject: Cocoa: Prevent FrameStrutMouseEvent double-clicks A window may see drag events without corresponding press/release events when dragging happens across several native windows. Handle NSLeftMouseDraged and NRightMouseDraged to synchronize mouse button state. Task-number: QTBUG-41609 Change-Id: Ieb66eb3460fc3cfd21e64c83ec1a28fe409af595 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index aa57fc211e..ca98f6cec3 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -736,6 +736,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; case NSRightMouseDown: m_frameStrutButtons |= Qt::RightButton; break; + case NSLeftMouseDragged: + m_frameStrutButtons |= Qt::LeftButton; + break; + case NSRightMouseDragged: + m_frameStrutButtons |= Qt::RightButton; + break; case NSRightMouseUp: m_frameStrutButtons &= ~Qt::RightButton; break; -- cgit v1.2.3 From 29d3b9745b4ba57cd79c95a96659f97c85c3b4ee Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 20 Oct 2014 14:01:58 +0200 Subject: Item view: Update item positions when delegate changes In QComboBox, when you set editable to true on the QComboBox, the delegates will change from QComboBoxMenuDelegate to QComboBoxDelegate. In some styles, such as Fusion, the size of the delegates will be different. So when the delegate is updated, we need to redo the list view layout, otherwise the items will be positioned based on the size of the old delegates, but the popup for the combo box will be sized for the new. This caused the popup to be too small for its items and display a scroll bar. [ChangeLog][QComboBox] Fixed positions of items when QComboBox is set as editable in Fusion style. Change-Id: Ia43ef96efbeee4d6d596c0674bf3898ef94f89a1 Task-number: QTBUG-33537 Reviewed-by: Mitch Curtis Reviewed-by: Friedemann Kleint --- src/widgets/itemviews/qabstractitemview.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 88b16db93b..1d8be6398c 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -837,6 +837,7 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate) } d->itemDelegate = delegate; viewport()->update(); + d->doDelayedItemsLayout(); } /*! -- cgit v1.2.3 From c4430ed02301c456dd591c88049ee22bc7dd9725 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 21 Oct 2014 10:01:58 +0200 Subject: Correctly update QComboBox appearance on editable change The updateDelegate() function checks isEditable() which in turn checks if d->lineEdit != 0, so we need to make the call after the lineEdit has actually been set/unset, otherwise the change to the delegate will not come until the next time you update the delegate. [ChangeLog][QComboBox] Fixed updating appearance of popup menu when changing the editable state of the combo box. Change-Id: Ib32f36cabd53c2c30d6256484a1eae131419960a Task-number: QTBUG-33537 Reviewed-by: Friedemann Kleint Reviewed-by: Mitch Curtis --- src/widgets/widgets/qcombobox.cpp | 3 +-- src/widgets/widgets/qcombobox_p.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 89dc8bf178..fda37c49de 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1704,8 +1704,6 @@ void QComboBox::setEditable(bool editable) if (isEditable() == editable) return; - d->updateDelegate(); - QStyleOptionComboBox opt; initStyleOption(&opt); if (editable) { @@ -1726,6 +1724,7 @@ void QComboBox::setEditable(bool editable) d->lineEdit = 0; } + d->updateDelegate(); d->updateFocusPolicy(); d->viewContainer()->updateTopBottomMargin(); diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 67b1aa6943..4e1b4125ab 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -254,7 +254,7 @@ private: friend class QComboBox; }; -class QComboMenuDelegate : public QAbstractItemDelegate +class Q_AUTOTEST_EXPORT QComboMenuDelegate : public QAbstractItemDelegate { Q_OBJECT public: QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {} @@ -283,7 +283,7 @@ private: // Note that this class is intentionally not using QStyledItemDelegate // Vista does not use the new theme for combo boxes and there might // be other side effects from using the new class -class QComboBoxDelegate : public QItemDelegate +class Q_AUTOTEST_EXPORT QComboBoxDelegate : public QItemDelegate { Q_OBJECT public: QComboBoxDelegate(QObject *parent, QComboBox *cmb) : QItemDelegate(parent), mCombo(cmb) {} -- cgit v1.2.3 From 88e7a4f661da166e81171a3188f6290c40a2f748 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 20 Oct 2014 12:17:24 +0200 Subject: Doc: QFileDevice and QFile::setPermissions do not manipulate ACLs Task-number: QTBUG-41271 Change-Id: Id97add8a6fdb7ce59020e833f6dc11744c9aaa7e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qfile.cpp | 12 +++++++++++- src/corelib/io/qfiledevice.cpp | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 6fe4c2455b..d3411abf10 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -206,6 +206,13 @@ QAbstractFileEngine *QFilePrivate::engine() const directory usually is not writable, but it is still possible to create files in it. + Qt's understanding of file permissions is limited, which affects especially + the \l QFile::setPermissions() function. On Windows, Qt will set only the + legacy read-only flag, and that only when none of the Write* flags are + passed. Qt does not manipulate access control lists (ACLs), which makes this + function mostly useless for NTFS volumes. It may still be of use for USB + sticks that use VFAT file systems. POSIX ACLs are not manipulated, either. + \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System} */ @@ -1063,9 +1070,12 @@ QFile::permissions(const QString &fileName) /*! Sets the permissions for the file to the \a permissions specified. - Returns \c true if successful, or false if the permissions cannot be + Returns \c true if successful, or \c false if the permissions cannot be modified. + \warning This function does not manipulate ACLs, which may limit its + effectiveness. + \sa permissions(), setFileName() */ diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 8d1c59e159..598347a56f 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -648,9 +648,12 @@ QFile::Permissions QFileDevice::permissions() const /*! Sets the permissions for the file to the \a permissions specified. - Returns \c true if successful, or false if the permissions cannot be + Returns \c true if successful, or \c false if the permissions cannot be modified. + \warning This function does not manipulate ACLs, which may limit its + effectiveness. + \sa permissions() */ bool QFileDevice::setPermissions(Permissions permissions) -- cgit v1.2.3 From 3fd2d9eff8c1f948306ee5fbfe364ccded1c4b84 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Oct 2014 15:44:43 +0200 Subject: Update QSsl::SecureProtocols to not include Sslv3 After the poodle vulnerability SSLv3 should like SSLv2 no longer be considered safe, so when a user request a safe protocol we should only allow TLS versions. [ChangeLog][QtNetwork][QSsl] QSsl::SecureProtocols now also excludes SSLv3 Change-Id: If825f6beb599294b028d706903b39db6b20be519 Reviewed-by: Richard J. Moore --- src/network/ssl/qssl.cpp | 10 +++++----- src/network/ssl/qsslcontext_openssl.cpp | 7 +++++-- src/network/ssl/qsslsocket_openssl.cpp | 4 +++- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 63c826a3d7..740131797c 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -119,12 +119,12 @@ QT_BEGIN_NAMESPACE a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections. On the server side, this will enable both SSLv3 and TLSv1_0 connections. \value SecureProtocols The default option, using protocols known to be secure; - currently behaves like TlsV1SslV3. + currently behaves similar to TlsV1Ssl3 except denying SSLv3 connections that does + not upgrade to TLS. - \note most servers using SSL understand both versions (2 and 3), - but it is recommended to use the latest version only for security - reasons. However, SSL and TLS are not compatible with each other: - if you get unexpected handshake failures, verify that you chose + \note most servers understand both SSL and TLS, but it is recommended to use + TLS only for security reasons. However, SSL and TLS are not compatible with + each other: if you get unexpected handshake failures, verify that you chose the correct setting for your protocol. */ diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 6daddebba3..c042d98056 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -139,8 +139,11 @@ init_context: case QSsl::SslV3: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); break; - case QSsl::SecureProtocols: // SslV2 will be disabled below - case QSsl::TlsV1SslV3: // SslV2 will be disabled below + case QSsl::SecureProtocols: + // SSLv2 and SSLv3 will be disabled by SSL options + // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32. + case QSsl::TlsV1SslV3: + // SSLv2 will will be disabled by SSL options case QSsl::AnyProtocol: default: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 1d675edbbb..84b0d9c75e 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -280,8 +280,10 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions) { long options; - if (protocol == QSsl::TlsV1SslV3 || protocol == QSsl::SecureProtocols) + if (protocol == QSsl::TlsV1SslV3) options = SSL_OP_ALL|SSL_OP_NO_SSLv2; + else if (protocol == QSsl::SecureProtocols) + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; else options = SSL_OP_ALL; -- cgit v1.2.3 From 9c92a18b975173383454c13d34f4438636f0450c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 17 Oct 2014 15:30:52 +0200 Subject: QCoreWLanEngine: Remove OS X 10.6 version Snow Leopard support is dropped in 5.4.0. Change-Id: I7f13735fe5dc8ed3051d918feb7b5600a72c3493 Reviewed-by: Jake Petroules --- src/plugins/bearer/corewlan/qcorewlanengine.mm | 8 +- .../bearer/corewlan/qcorewlanengine_10_6.mm | 922 --------------------- 2 files changed, 1 insertion(+), 929 deletions(-) delete mode 100644 src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm (limited to 'src') diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 8caca7d677..6f9ea91799 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -62,8 +62,6 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time #include #include -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_NA) - @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject { NSNotificationCenter *notificationCenter; @@ -886,7 +884,3 @@ quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b) } QT_END_NAMESPACE - -#else // QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE -#include "qcorewlanengine_10_6.mm" -#endif diff --git a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm deleted file mode 100644 index 6cf614cb30..0000000000 --- a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm +++ /dev/null @@ -1,922 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -@interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject -{ - NSNotificationCenter *notificationCenter; - CWInterface *currentInterface; - QCoreWlanEngine *engine; - NSLock *locker; -} -- (void)notificationHandler:(NSNotification *)notification; -- (void)remove; -- (void)setEngine:(QCoreWlanEngine *)coreEngine; -- (QCoreWlanEngine *)engine; -- (void)dealloc; - -@property (assign) QCoreWlanEngine* engine; - -@end - -@implementation QT_MANGLE_NAMESPACE(QNSListener) - -- (id) init -{ - [locker lock]; - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - notificationCenter = [NSNotificationCenter defaultCenter]; - currentInterface = [CWInterface interfaceWithName:nil]; - [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil]; - [locker unlock]; - [autoreleasepool release]; - return self; -} - --(void)dealloc -{ - [super dealloc]; -} - --(void)setEngine:(QCoreWlanEngine *)coreEngine -{ - [locker lock]; - if(!engine) - engine = coreEngine; - [locker unlock]; -} - --(QCoreWlanEngine *)engine -{ - return engine; -} - --(void)remove -{ - [locker lock]; - [notificationCenter removeObserver:self]; - [locker unlock]; -} - -- (void)notificationHandler:(NSNotification *)notification -{ - Q_UNUSED(notification); - engine->requestUpdate(); -} -@end - -static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; - -QT_BEGIN_NAMESPACE - -void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info) -{ - for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) { - - QString changed = QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(changedKeys, i)); - if( changed.contains("/Network/Global/IPv4")) { - QCoreWlanEngine* wlanEngine = static_cast(info); - wlanEngine->requestUpdate(); - } - } - return; -} - - -QScanThread::QScanThread(QObject *parent) - :QThread(parent) -{ -} - -QScanThread::~QScanThread() -{ -} - -void QScanThread::quit() -{ - wait(); -} - -void QScanThread::run() -{ - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - QStringList found; - mutex.lock(); - CWInterface *currentInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceName)]; - mutex.unlock(); - - if([currentInterface power]) { - NSError *err = nil; - NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kCWScanKeyMerge, - [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, - [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil]; - - NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; - CWNetwork *apNetwork; - - if (!err) { - - for(uint row=0; row < [apArray count]; row++ ) { - apNetwork = [apArray objectAtIndex:row]; - - const QString networkSsid = QCFString::toQString([apNetwork ssid]); - const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); - found.append(id); - - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; - bool known = isKnownSsid(networkSsid); - if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { - if( networkSsid == QCFString::toQString( [currentInterface ssid])) { - state = QNetworkConfiguration::Active; - } - } - if(state == QNetworkConfiguration::Undefined) { - if(known) { - state = QNetworkConfiguration::Discovered; - } else { - state = QNetworkConfiguration::Undefined; - } - } - QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose; - if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) { - purpose = QNetworkConfiguration::PublicPurpose; - } else { - purpose = QNetworkConfiguration::PrivatePurpose; - } - - found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose)); - - } - } - } - // add known configurations that are not around. - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - - QString networkName = i.key(); - const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); - - if(!found.contains(id)) { - QString networkSsid = getSsidFromNetworkName(networkName); - const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; - QString interfaceName; - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - interfaceName = ij.value(); - } - - if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { - if( networkSsid == QCFString::toQString([currentInterface ssid])) { - state = QNetworkConfiguration::Active; - } - } - if(state == QNetworkConfiguration::Undefined) { - if( userProfiles.contains(networkName) - && found.contains(ssidId)) { - state = QNetworkConfiguration::Discovered; - } - } - - if(state == QNetworkConfiguration::Undefined) { - state = QNetworkConfiguration::Defined; - } - - found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose)); - } - } - emit networksChanged(); - [autoreleasepool release]; -} - -QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose) -{ - QStringList found; - QMutexLocker locker(&mutex); - QNetworkConfigurationPrivate *ptr = new QNetworkConfigurationPrivate; - - ptr->name = name; - ptr->isValid = true; - ptr->id = id; - ptr->state = state; - ptr->type = QNetworkConfiguration::InternetAccessPoint; - ptr->bearerType = QNetworkConfiguration::BearerWLAN; - ptr->purpose = purpose; - - fetchedConfigurations.append( ptr); - configurationInterface.insert(ptr->id, interfaceName); - - locker.unlock(); - locker.relock(); - found.append(id); - return found; -} - -QList QScanThread::getConfigurations() -{ - QMutexLocker locker(&mutex); - - QList foundConfigurations = fetchedConfigurations; - fetchedConfigurations.clear(); - - return foundConfigurations; -} - -void QScanThread::getUserConfigurations() -{ - QMutexLocker locker(&mutex); - - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - userProfiles.clear(); - - NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; - for(uint row=0; row < [wifiInterfaces count]; row++ ) { - - CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]]; - if ( ![wifiInterface power] ) - continue; - - NSString *nsInterfaceName = [wifiInterface name]; -// add user configured system networks - SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil); - NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]); - CFRelease(dynRef); - if(airportPlist != nil) { - NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; - - NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"]; - for(NSString *ssidkey in thisSsidarray) { - QString thisSsid = QCFString::toQString(ssidkey); - if(!userProfiles.contains(thisSsid)) { - QMap map; - map.insert(thisSsid, QCFString::toQString(nsInterfaceName)); - userProfiles.insert(thisSsid, map); - } - } - CFRelease(airportPlist); - } - - // 802.1X user profiles - QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist"; - NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: QCFString::toNSString(userProfilePath)] autorelease]; - if(eapDict != nil) { - NSString *profileStr= @"Profiles"; - NSString *nameStr = @"UserDefinedName"; - NSString *networkSsidStr = @"Wireless Network"; - for (id profileKey in eapDict) { - if ([profileStr isEqualToString:profileKey]) { - NSDictionary *itemDict = [eapDict objectForKey:profileKey]; - for (id itemKey in itemDict) { - - NSInteger dictSize = [itemKey count]; - id objects[dictSize]; - id keys[dictSize]; - - [itemKey getObjects:objects andKeys:keys]; - QString networkName; - QString ssid; - for(int i = 0; i < dictSize; i++) { - if([nameStr isEqualToString:keys[i]]) { - networkName = QCFString::toQString(objects[i]); - } - if([networkSsidStr isEqualToString:keys[i]]) { - ssid = QCFString::toQString(objects[i]); - } - if(!userProfiles.contains(networkName) - && !ssid.isEmpty()) { - QMap map; - map.insert(ssid, QCFString::toQString(nsInterfaceName)); - userProfiles.insert(networkName, map); - } - } - } - } - } - } - } - [autoreleasepool release]; -} - -QString QScanThread::getSsidFromNetworkName(const QString &name) -{ - QMutexLocker locker(&mutex); - - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key())); - if(name == i.key() || name == networkNameHash) { - return ij.key(); - } - } - } - return QString(); -} - -QString QScanThread::getNetworkNameFromSsid(const QString &ssid) -{ - QMutexLocker locker(&mutex); - - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - if(ij.key() == ssid) { - return i.key(); - } - } - } - return QString(); -} - -bool QScanThread::isKnownSsid(const QString &ssid) -{ - QMutexLocker locker(&mutex); - - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - if(map.keys().contains(ssid)) { - return true; - } - } - return false; -} - - -QCoreWlanEngine::QCoreWlanEngine(QObject *parent) -: QBearerEngineImpl(parent), scanThread(0) -{ - scanThread = new QScanThread(this); - connect(scanThread, SIGNAL(networksChanged()), - this, SLOT(networksChanged())); -} - -QCoreWlanEngine::~QCoreWlanEngine() -{ - scanThread->terminate(); - scanThread->wait(); - - while (!foundConfigurations.isEmpty()) - delete foundConfigurations.takeFirst(); - [listener remove]; - [listener release]; -} - -void QCoreWlanEngine::initialize() -{ - QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - - if([[CWInterface supportedInterfaces] count] > 0 && !listener) { - listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init]; - listener.engine = this; - hasWifi = true; - } else { - hasWifi = false; - } - storeSession = NULL; - - startNetworkChangeLoop(); - [autoreleasepool release]; -} - - -QString QCoreWlanEngine::getInterfaceFromId(const QString &id) -{ - QMutexLocker locker(&mutex); - - return scanThread->configurationInterface.value(id); -} - -bool QCoreWlanEngine::hasIdentifier(const QString &id) -{ - QMutexLocker locker(&mutex); - - return scanThread->configurationInterface.contains(id); -} - -void QCoreWlanEngine::connectToId(const QString &id) -{ - QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - QString interfaceString = getInterfaceFromId(id); - - CWInterface *wifiInterface = - [CWInterface interfaceWithName: QCFString::toNSString(interfaceString)]; - - if ([wifiInterface power]) { - NSError *err = nil; - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; - - QString wantedSsid; - - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name)); - const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name))); - - bool using8021X = false; - if (idHash2 != id) { - NSArray *array = [CW8021XProfile allUser8021XProfiles]; - - for (NSUInteger i = 0; i < [array count]; ++i) { - const QString networkNameHashCheck = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString([[array objectAtIndex:i] userDefinedName]))); - - const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString([[array objectAtIndex:i] ssid]))); - - if (id == networkNameHashCheck || id == ssidHash) { - const QString thisName = scanThread->getSsidFromNetworkName(id); - if (thisName.isEmpty()) - wantedSsid = id; - else - wantedSsid = thisName; - - [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile]; - using8021X = true; - break; - } - } - } - - if (!using8021X) { - QString wantedNetwork; - QMapIterator > i(scanThread->userProfiles); - while (i.hasNext()) { - i.next(); - wantedNetwork = i.key(); - const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork)); - if (id == networkNameHash) { - wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork); - break; - } - } - } - NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kCWScanKeyMerge, - [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, - [NSNumber numberWithInteger:100], kCWScanKeyRestTime, - QCFString::toNSString(wantedSsid), kCWScanKeySSID, - nil]; - - NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:scanParameters error:&err]; - - if(!err) { - for(uint row=0; row < [scanArray count]; row++ ) { - CWNetwork *apNetwork = [scanArray objectAtIndex:row]; - - if(wantedSsid == QCFString::toQString([apNetwork ssid])) { - - if(!using8021X) { - SecKeychainAttribute attributes[3]; - - NSString *account = [apNetwork ssid]; - NSString *keyKind = @"AirPort network password"; - NSString *keyName = account; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[account UTF8String]; - attributes[0].length = [account length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keyKind UTF8String]; - attributes[1].length = [keyKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keyName UTF8String]; - attributes[2].length = [keyName length]; - - SecKeychainAttributeList attributeList = {3,attributes}; - - SecKeychainSearchRef searchRef; - SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef); - - NSString *password = @""; - SecKeychainItemRef searchItem; - - if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) { - UInt32 realPasswordLength; - SecKeychainAttribute attributesW[8]; - attributesW[0].tag = kSecAccountItemAttr; - SecKeychainAttributeList listW = {1,attributesW}; - char *realPassword; - OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword); - - if (status == noErr) { - if (realPassword != NULL) { - - QByteArray pBuf; - pBuf.resize(realPasswordLength); - pBuf.prepend(realPassword); - pBuf.insert(realPasswordLength,'\0'); - - password = [NSString stringWithUTF8String:pBuf]; - } - SecKeychainItemFreeContent(&listW, realPassword); - } - - CFRelease(searchItem); - } else { - qDebug() << "SecKeychainSearchCopyNext error"; - } - [params setValue: password forKey: kCWAssocKeyPassphrase]; - } // end using8021X - - - bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; - - if(!err) { - if(!result) { - emit connectionError(id, ConnectError); - } else { - return; - } - } else { - qDebug() <<"associate ERROR"<< QCFString::toQString([err localizedDescription ]); - } - } - } //end scan network - } else { - qDebug() <<"scan ERROR"<< QCFString::toQString([err localizedDescription ]); - } - emit connectionError(id, InterfaceLookupError); - } - - locker.unlock(); - emit connectionError(id, InterfaceLookupError); - [autoreleasepool release]; -} - -void QCoreWlanEngine::disconnectFromId(const QString &id) -{ - QMutexLocker locker(&mutex); - - QString interfaceString = getInterfaceFromId(id); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - - CWInterface *wifiInterface = - [CWInterface interfaceWithName: QCFString::toNSString(interfaceString)]; - - [wifiInterface disassociate]; - if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { - locker.unlock(); - emit connectionError(id, DisconnectionError); - locker.relock(); - } - [autoreleasepool release]; -} - -void QCoreWlanEngine::requestUpdate() -{ - scanThread->getUserConfigurations(); - doRequestUpdate(); -} - -void QCoreWlanEngine::doRequestUpdate() -{ - QMutexLocker locker(&mutex); - - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - - NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; - for (uint row = 0; row < [wifiInterfaces count]; ++row) { - scanThread->interfaceName = QCFString::toQString([wifiInterfaces objectAtIndex:row]); - scanThread->start(); - } - locker.unlock(); - if ([wifiInterfaces count] == 0) - networksChanged(); - [autoreleasepool release]; -} - -bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) -{ - QMutexLocker locker(&mutex); - bool haswifi = false; - if(hasWifi) { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - CWInterface *defaultInterface = [CWInterface interfaceWithName: QCFString::toNSString(wifiDeviceName)]; - if([defaultInterface power]) { - haswifi = true; - } - [autoreleasepool release]; - } - return haswifi; -} - - -QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id) -{ - QMutexLocker locker(&mutex); - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - if (!ptr) - return QNetworkSession::Invalid; - - if (!ptr->isValid) { - return QNetworkSession::Invalid; - } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - return QNetworkSession::Connected; - } else if ((ptr->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { - return QNetworkSession::Disconnected; - } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) { - return QNetworkSession::NotAvailable; - } else if ((ptr->state & QNetworkConfiguration::Undefined) == - QNetworkConfiguration::Undefined) { - return QNetworkSession::NotAvailable; - } - - return QNetworkSession::Invalid; -} - -QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const -{ - return QNetworkConfigurationManager::ForcedRoaming; -} - -void QCoreWlanEngine::startNetworkChangeLoop() -{ - - SCDynamicStoreContext dynStoreContext = { 0, this/*(void *)storeSession*/, NULL, NULL, NULL }; - storeSession = SCDynamicStoreCreate(NULL, - CFSTR("networkChangeCallback"), - networkChangeCallback, - &dynStoreContext); - if (!storeSession ) { - qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError()); - return; - } - - CFMutableArrayRef notificationKeys; - notificationKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - CFMutableArrayRef patternsArray; - patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - - CFStringRef storeKey; - storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, - kSCDynamicStoreDomainState, - kSCEntNetIPv4); - CFArrayAppendValue(notificationKeys, storeKey); - CFRelease(storeKey); - - storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, - kSCDynamicStoreDomainState, - kSCCompAnyRegex, - kSCEntNetIPv4); - CFArrayAppendValue(patternsArray, storeKey); - CFRelease(storeKey); - - if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) { - qWarning() << "register notification error:"<< SCErrorString(SCError()); - CFRelease(storeSession ); - CFRelease(notificationKeys); - CFRelease(patternsArray); - return; - } - CFRelease(notificationKeys); - CFRelease(patternsArray); - - runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0); - if (!runloopSource) { - qWarning() << "runloop source error:"<< SCErrorString(SCError()); - CFRelease(storeSession ); - return; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode); - return; -} - -QNetworkSessionPrivate *QCoreWlanEngine::createSessionBackend() -{ - return new QNetworkSessionPrivateImpl; -} - -QNetworkConfigurationPrivatePointer QCoreWlanEngine::defaultConfiguration() -{ - return QNetworkConfigurationPrivatePointer(); -} - -bool QCoreWlanEngine::requiresPolling() const -{ - return true; -} - -void QCoreWlanEngine::networksChanged() -{ - QMutexLocker locker(&mutex); - - QStringList previous = accessPointConfigurations.keys(); - - QList foundConfigurations = scanThread->getConfigurations(); - while (!foundConfigurations.isEmpty()) { - QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst(); - - previous.removeAll(cpPriv->id); - - if (accessPointConfigurations.contains(cpPriv->id)) { - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id); - - bool changed = false; - - ptr->mutex.lock(); - - if (ptr->isValid != cpPriv->isValid) { - ptr->isValid = cpPriv->isValid; - changed = true; - } - - if (ptr->name != cpPriv->name) { - ptr->name = cpPriv->name; - changed = true; - } - - if (ptr->bearerType != cpPriv->bearerType) { - ptr->bearerType = cpPriv->bearerType; - changed = true; - } - - if (ptr->state != cpPriv->state) { - ptr->state = cpPriv->state; - changed = true; - } - - ptr->mutex.unlock(); - - if (changed) { - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - } - - delete cpPriv; - } else { - QNetworkConfigurationPrivatePointer ptr(cpPriv); - - accessPointConfigurations.insert(ptr->id, ptr); - - locker.unlock(); - emit configurationAdded(ptr); - locker.relock(); - } - } - - while (!previous.isEmpty()) { - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.take(previous.takeFirst()); - - locker.unlock(); - emit configurationRemoved(ptr); - locker.relock(); - } - - locker.unlock(); - emit updateCompleted(); - -} - -quint64 QCoreWlanEngine::bytesWritten(const QString &id) -{ - QMutexLocker locker(&mutex); - const QString interfaceStr = getInterfaceFromId(id); - return getBytes(interfaceStr,false); -} - -quint64 QCoreWlanEngine::bytesReceived(const QString &id) -{ - QMutexLocker locker(&mutex); - const QString interfaceStr = getInterfaceFromId(id); - return getBytes(interfaceStr,true); -} - -quint64 QCoreWlanEngine::startTime(const QString &identifier) -{ - QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; - quint64 timestamp = 0; - - NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist"; - NSDictionary* plistDict = [[[NSDictionary alloc] initWithContentsOfFile:filePath] autorelease]; - if(plistDict == nil) - return timestamp; - NSString *input = @"KnownNetworks"; - NSString *timeStampStr = @"_timeStamp"; - - NSString *ssidStr = @"SSID_STR"; - - for (id key in plistDict) { - if ([input isEqualToString:key]) { - - NSDictionary *knownNetworksDict = [plistDict objectForKey:key]; - if(knownNetworksDict == nil) - return timestamp; - for (id networkKey in knownNetworksDict) { - bool isFound = false; - NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey]; - if(itemDict == nil) - return timestamp; - NSInteger dictSize = [itemDict count]; - id objects[dictSize]; - id keys[dictSize]; - - [itemDict getObjects:objects andKeys:keys]; - bool ok = false; - for(int i = 0; i < dictSize; i++) { - if([ssidStr isEqualToString:keys[i]]) { - const QString ident = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(objects[i]))); - if(ident == identifier) { - ok = true; - } - } - if(ok && [timeStampStr isEqualToString:keys[i]]) { - timestamp = (quint64)[objects[i] timeIntervalSince1970]; - isFound = true; - break; - } - } - if(isFound) - break; - } - } - } - [autoreleasepool release]; - return timestamp; -} - -quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b) -{ - struct ifaddrs *ifAddressList, *ifAddress; - struct if_data *if_data; - - quint64 bytes = 0; - ifAddressList = nil; - if(getifaddrs(&ifAddressList) == 0) { - for(ifAddress = ifAddressList; ifAddress; ifAddress = ifAddress->ifa_next) { - if(interfaceName == ifAddress->ifa_name) { - if_data = (struct if_data*)ifAddress->ifa_data; - if(b) { - bytes = if_data->ifi_ibytes; - break; - } else { - bytes = if_data->ifi_obytes; - break; - } - } - } - freeifaddrs(ifAddressList); - } - return bytes; -} - -QT_END_NAMESPACE -- cgit v1.2.3 From 8c4deff51c8064f5a15cae0342bfa66b6663662b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 21 Oct 2014 17:08:57 +0200 Subject: Fix QVariant associative container conversion from built-in types. Task-number: QTBUG-41403 Change-Id: I9dab0f9450cac11678eb6d20abd2dd08e86e0900 Reviewed-by: Stephen Kelly --- src/corelib/kernel/qmetatype.h | 15 +++++++++++++++ src/corelib/kernel/qvariant.h | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 3d859021b5..af38589903 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -2109,6 +2109,21 @@ namespace QtPrivate { }; } +namespace QtMetaTypePrivate { +inline Q_DECL_CONSTEXPR bool isBuiltinSequentialType(int typeId) +{ + return typeId == qMetaTypeId() + || typeId == qMetaTypeId() + || typeId == qMetaTypeId(); +} + +inline Q_DECL_CONSTEXPR bool isBuiltinAssociativeType(int typeId) +{ + return typeId == qMetaTypeId() + || typeId == qMetaTypeId(); +} +} // QtMetaTypePrivate + QT_END_NAMESPACE #endif // QMETATYPE_H diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index bdbd0dd8ef..57e0523f7c 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -736,7 +736,7 @@ namespace QtPrivate { { static QVariantList invoke(const QVariant &v) { - if (v.userType() == qMetaTypeId() || v.userType() == qMetaTypeId() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { + if (QtMetaTypePrivate::isBuiltinSequentialType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { QSequentialIterable iter = QVariantValueHelperInterface::invoke(v); QVariantList l; l.reserve(iter.size()); @@ -752,7 +752,7 @@ namespace QtPrivate { { static QVariantHash invoke(const QVariant &v) { - if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { + if (QtMetaTypePrivate::isBuiltinAssociativeType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { QAssociativeIterable iter = QVariantValueHelperInterface::invoke(v); QVariantHash l; l.reserve(iter.size()); @@ -768,7 +768,7 @@ namespace QtPrivate { { static QVariantMap invoke(const QVariant &v) { - if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { + if (QtMetaTypePrivate::isBuiltinAssociativeType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { QAssociativeIterable iter = QVariantValueHelperInterface::invoke(v); QVariantMap l; for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) -- cgit v1.2.3 From 929509ea03b116588bdae38391377ec1ec976845 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Mon, 20 Oct 2014 18:44:13 +0200 Subject: QStyleSheetStyle: Don't interfere with QFontDialog The sample lineedit in Qt's own font dialog shouldn't have its font affected by stylesheets. Not only does this hampers the ability to preview the font, it actually overrides the font selection as that one is taken directly from the widget. Task-number: QTBUG-41513 Change-Id: I11d0bef8c7bf7bdae4cc08b6b9276d0fc14a75fb Reviewed-by: Olivier Goffart Reviewed-by: Frederik Gladhorn --- src/widgets/dialogs/qfontdialog.cpp | 1 + src/widgets/styles/qstylesheetstyle.cpp | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 109b726880..d12b109d9f 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -322,6 +322,7 @@ void QFontDialogPrivate::init() familyList->setFocus(); retranslateStrings(); + sampleEdit->setObjectName(QLatin1String("qt_fontDialog_sampleEdit")); } /*! diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index a9e13bad49..e9f20de842 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5828,6 +5828,10 @@ bool QStyleSheetStyle::event(QEvent *e) void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const { + // Qt's fontDialog relies on the font of the sample edit for its selection, + // we should never override it. + if (w->objectName() == QLatin1String("qt_fontDialog_sampleEdit")) + return; QWidget *container = containerWidget(w); QRenderRule rule = renderRule(container, PseudoElement_None, PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container)); -- cgit v1.2.3 From ddf3fc0deb906ee591fc01ecc2a74768a49950f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 23 Oct 2014 15:40:55 +0200 Subject: Indicate that QTestLib is running Set QT_QTESTLIB_RUNNING=1 on QTestLib startup. This allows Qt to adapt its behavior to the testing environment, WHICH IS NORMALLY NOT SOMETHING YOU WANT TO DO. Use with caution. Change-Id: I31de80e7c2cc91ff1ed8137926e6b729ef6efdc6 Reviewed-by: Laszlo Agocs --- src/testlib/qtestcase.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index b3b206bfc9..2d92b3f6bd 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2367,6 +2367,7 @@ static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo) static void initEnvironment() { qputenv("QT_LOGGING_TO_CONSOLE", "1"); + qputenv("QT_QTESTLIB_RUNNING", "1"); } /*! -- cgit v1.2.3 From 74a51d590f4acd189f8d0594a5a706cbf97c805b Mon Sep 17 00:00:00 2001 From: John Layt Date: Mon, 17 Mar 2014 17:59:55 +0100 Subject: QPrinter - Fix DuplexMode on all platforms Add support to get/set the DuplexMode on Windows and Mac, improve the CUPS duplex handling, ensure support is the same on all platforms. [ChangeLog][QtPrintSupport][QPrinter] Added duplex support for Windows and OS X. Task-number: QTBUG-11332 Change-Id: I9d61d63233d828c3b1fd6df54072c6049f3c6298 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 3 ++ src/plugins/platforms/cocoa/qprintengine_mac.mm | 47 ++++++++++++++++--- src/plugins/printsupport/cups/qcupsprintengine.cpp | 6 +++ src/plugins/printsupport/cups/qppdprintdevice.cpp | 3 ++ .../printsupport/windows/qwindowsprintdevice.cpp | 1 + src/printsupport/kernel/qprintengine_win.cpp | 54 +++++++++++++++++++--- src/printsupport/kernel/qprinter.cpp | 12 +++-- src/printsupport/kernel/qprinterinfo.cpp | 27 +++++++++++ src/printsupport/kernel/qprinterinfo.h | 3 ++ 9 files changed, 138 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 7322025df6..2101b68769 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -391,6 +391,9 @@ void QCocoaPrintDevice::loadDuplexModes() const // If still no result, or not added in PPD, then add None if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone)) m_duplexModes.append(QPrint::DuplexNone); + // If have both modes, then can support DuplexAuto + if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide)) + m_duplexModes.append(QPrint::DuplexAuto); m_haveDuplexModes = true; } diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index fb968f31e9..f684fef233 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -457,9 +457,6 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va break; case PPK_CustomBase: break; - case PPK_Duplex: - // TODO Add support using PMSetDuplex / PMGetDuplex - break; case PPK_FontEmbedding: break; case PPK_PageOrder: @@ -503,6 +500,29 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va case PPK_DocumentName: PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString())); break; + case PPK_Duplex: { + QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt()); + if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode)) + break; + switch (mode) { + case QPrinter::DuplexNone: + PMSetDuplex(d->settings(), kPMDuplexNone); + break; + case QPrinter::DuplexAuto: + PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble); + break; + case QPrinter::DuplexLongSide: + PMSetDuplex(d->settings(), kPMDuplexNoTumble); + break; + case QPrinter::DuplexShortSide: + PMSetDuplex(d->settings(), kPMDuplexTumble); + break; + default: + // Don't change + break; + } + break; + } case PPK_FullPage: if (value.toBool()) d->m_pageLayout.setMode(QPageLayout::FullPageMode); @@ -602,10 +622,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const case PPK_CustomBase: // Special case, leave null break; - case PPK_Duplex: - // TODO Add support using PMSetDuplex / PMGetDuplex - ret = QPrinter::DuplexNone; - break; case PPK_FontEmbedding: ret = false; break; @@ -647,6 +663,23 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const ret = QCFString::toQString(name); break; } + case PPK_Duplex: { + PMDuplexMode mode = kPMDuplexNone; + PMGetDuplex(d->settings(), &mode); + switch (mode) { + case kPMDuplexNoTumble: + ret = QPrinter::DuplexLongSide; + break; + case kPMDuplexTumble: + ret = QPrinter::DuplexShortSide; + break; + case kPMDuplexNone: + default: + ret = QPrinter::DuplexNone; + break; + } + break; + } case PPK_FullPage: ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode; break; diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index 724ff5b98b..d7cd18f1d1 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -85,6 +85,12 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v // Get the named page size from the printer if supported d->setPageSize(d->m_printDevice.supportedPageSize(value.toString())); break; + case PPK_Duplex: { + QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt()); + if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode)) + d->duplex = mode; + break; + } case PPK_PrinterName: d->changePrinter(value.toString()); break; diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 75e8a8bf26..7a6acf8b78 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -387,6 +387,9 @@ void QPpdPrintDevice::loadDuplexModes() const // If still no result, or not added in PPD, then add None if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone)) m_duplexModes.append(QPrint::DuplexNone); + // If have both modes, then can support DuplexAuto + if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide)) + m_duplexModes.append(QPrint::DuplexAuto); m_haveDuplexModes = true; } diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 0feea5ea74..a0a549da6f 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -378,6 +378,7 @@ void QWindowsPrintDevice::loadDuplexModes() const DWORD duplex = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_DUPLEX, NULL, NULL); if (int(duplex) == 1) { // TODO Assume if duplex flag supports both modes + m_duplexModes.append(QPrint::DuplexAuto); m_duplexModes.append(QPrint::DuplexLongSide); m_duplexModes.append(QPrint::DuplexShortSide); } diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index a1a2f97abe..90b204eb0c 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -1003,9 +1003,6 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & // The following keys are settings that are unsupported by the Windows PrintEngine case PPK_CustomBase: break; - case PPK_Duplex: - // TODO Add support using DEVMODE.dmDuplex - break; case PPK_FontEmbedding: break; case PPK_PageOrder: @@ -1046,6 +1043,33 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & d->docName = value.toString(); break; + case PPK_Duplex: { + if (!d->devMode) + break; + QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt()); + if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice.supportedDuplexModes().contains(mode)) + break; + switch (mode) { + case QPrinter::DuplexNone: + d->devMode->dmDuplex = DMDUP_SIMPLEX; + break; + case QPrinter::DuplexAuto: + d->devMode->dmDuplex = d->m_pageLayout.orientation() == QPageLayout::Landscape ? DMDUP_HORIZONTAL : DMDUP_VERTICAL; + break; + case QPrinter::DuplexLongSide: + d->devMode->dmDuplex = DMDUP_VERTICAL; + break; + case QPrinter::DuplexShortSide: + d->devMode->dmDuplex = DMDUP_HORIZONTAL; + break; + default: + // Don't change + break; + } + d->doReinit(); + break; + } + case PPK_FullPage: if (value.toBool()) d->m_pageLayout.setMode(QPageLayout::FullPageMode); @@ -1260,10 +1284,6 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const // The following keys are settings that are unsupported by the Windows PrintEngine // Return sensible default values to ensure consistent behavior across platforms - case PPK_Duplex: - // TODO Add support using DEVMODE.dmDuplex - value = QPrinter::DuplexNone; - break; case PPK_FontEmbedding: value = false; break; @@ -1300,6 +1320,26 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const value = d->docName; break; + case PPK_Duplex: { + if (!d->devMode) { + value = QPrinter::DuplexNone; + } else { + switch (d->devMode->dmDuplex) { + case DMDUP_VERTICAL: + value = QPrinter::DuplexLongSide; + break; + case DMDUP_HORIZONTAL: + value = QPrinter::DuplexShortSide; + break; + case DMDUP_SIMPLEX: + default: + value = QPrinter::DuplexNone; + break; + } + } + break; + } + case PPK_FullPage: value = d->m_pageLayout.mode() == QPageLayout::FullPageMode; break; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 8d62580d67..c13b1574d0 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1678,9 +1678,11 @@ bool QPrinter::fontEmbeddingEnabled() const /*! \since 4.2 + \obsolete Use setDuplex() instead. + Enables double sided printing if \a doubleSided is true; otherwise disables it. - Currently this option is only supported on X11. + \sa setDuplex() */ void QPrinter::setDoubleSidedPrinting(bool doubleSided) { @@ -1691,9 +1693,11 @@ void QPrinter::setDoubleSidedPrinting(bool doubleSided) /*! \since 4.2 + \obsolete Use duplex() instead. + Returns \c true if double side printing is enabled. - Currently this option is only supported on X11. + \sa duplex() */ bool QPrinter::doubleSidedPrinting() const { @@ -1705,7 +1709,7 @@ bool QPrinter::doubleSidedPrinting() const Enables double sided printing based on the \a duplex mode. - Currently this option is only supported on X11. + \sa duplex() */ void QPrinter::setDuplex(DuplexMode duplex) { @@ -1718,7 +1722,7 @@ void QPrinter::setDuplex(DuplexMode duplex) Returns the current duplex mode. - Currently this option is only supported on X11. + \sa setDuplex() */ QPrinter::DuplexMode QPrinter::duplex() const { diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp index b1321bf57a..a17da3fdaa 100644 --- a/src/printsupport/kernel/qprinterinfo.cpp +++ b/src/printsupport/kernel/qprinterinfo.cpp @@ -352,6 +352,33 @@ QList QPrinterInfo::supportedResolutions() const return d->m_printDevice.supportedResolutions(); } +/*! + Returns the default duplex mode of this printer. + + \since 5.4 +*/ + +QPrinter::DuplexMode QPrinterInfo::defaultDuplexMode() const +{ + Q_D(const QPrinterInfo); + return QPrinter::DuplexMode(d->m_printDevice.defaultDuplexMode()); +} + +/*! + Returns a list of duplex modes supported by this printer. + + \since 5.4 +*/ + +QList QPrinterInfo::supportedDuplexModes() const +{ + Q_D(const QPrinterInfo); + QList list; + foreach (QPrint::DuplexMode mode, d->m_printDevice.supportedDuplexModes()) + list << QPrinter::DuplexMode(mode); + return list; +} + /*! Returns a list of all the available Printer Names on this system. diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h index a4754c48dc..58d3873492 100644 --- a/src/printsupport/kernel/qprinterinfo.h +++ b/src/printsupport/kernel/qprinterinfo.h @@ -82,6 +82,9 @@ public: QList supportedResolutions() const; + QPrinter::DuplexMode defaultDuplexMode() const; + QList supportedDuplexModes() const; + static QStringList availablePrinterNames(); static QList availablePrinters(); -- cgit v1.2.3 From 9911550fa7fa58cfef66a33ccd8b1d0c531f848e Mon Sep 17 00:00:00 2001 From: aavit Date: Mon, 20 Oct 2014 14:09:58 +0200 Subject: Fix rubberband selection in rotated GraphicsView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Selection rectangle was incorrectly mapped to scene space when the view was rotated. It became a rotated rectangle instead of the correct polygon (rhombus). Task-number: QTBUG-42008 Change-Id: Ib7b366bec7e1f83109e03c434268ad6897138f30 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/graphicsview/qgraphicsview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 88d5e52204..5484ecb96e 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -765,7 +765,7 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event) } // Set the new selection area QPainterPath selectionArea; - selectionArea.addPolygon(mapToScene(rubberBandRect)); + selectionArea.addPolygon(q->mapToScene(rubberBandRect)); selectionArea.closeSubpath(); if (scene) scene->setSelectionArea(selectionArea, rubberBandSelectionMode, q->viewportTransform()); -- cgit v1.2.3 From 6841dd6eccda88f08ad4c424fc9d5f9e400aaf43 Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 21 Oct 2014 12:21:06 +0200 Subject: QGraphicsScene: stabilize stacking order of toplevel items Removing and adding toplevel items could result in invalid stacking order (not corresponding to insertion order). Task-number: QTBUG-19316 Change-Id: Ia8646784a2181cfa936b101e2adaf7e7e73bb83d Reviewed-by: Andreas Aardal Hanssen --- src/widgets/graphicsview/qgraphicsscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index ae3eb1eee7..988152da9d 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -392,7 +392,7 @@ void QGraphicsScenePrivate::_q_emitUpdated() */ void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item) { - item->d_ptr->ensureSequentialSiblingIndex(); + ensureSequentialTopLevelSiblingIndexes(); needSortTopLevelItems = true; // ### maybe false item->d_ptr->siblingIndex = topLevelItems.size(); topLevelItems.append(item); -- cgit v1.2.3 From 7645b64d896330885a2afcbb996b677730151570 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 20 Oct 2014 16:31:34 +0400 Subject: Add support for "Apple Roman" encoding Substitute this encoding by "macintosh" when Qt is built with ICU. It is for compatibility with Qt 4.x. Change-Id: I70c51cba7d473ac81e25862736cb71a2f6894055 Reviewed-by: Lars Knoll --- src/corelib/codecs/qicucodec.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index 103bf0573f..a549430649 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -445,6 +445,8 @@ QTextCodec *QIcuCodec::codecForNameUnlocked(const char *name) // backwards compatibility with Qt 4.x if (!qstrcmp(name, "CP949")) name = "windows-949"; + else if (!qstrcmp(name, "Apple Roman")) + name = "macintosh"; // these are broken data in ICU 4.4, and can't be resolved even though they are aliases to tis-620 if (!qstrcmp(name, "windows-874-2000") || !qstrcmp(name, "windows-874") -- cgit v1.2.3 From 3903aee91bb4bca618593cf4c856edc0be2a17d8 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 22 Oct 2014 16:35:43 +0400 Subject: Fix doc about the list of supported codecs Replace "Apple Roman" by "Macintosh" which is registered by IANA: http://tools.ietf.org/html/rfc1345. Replace unsupported "GB18030-0" by "GB18030". Remove "JIS X 0201" and "JIS X 0208" as they are supported as parts of other Japanese encodings but not directly. Add "HP-ROMAN8" which is supported by both Qt and ICU. Also clean the codecs test. Change-Id: Iaf8e8ff1900d3f92ea0e0df75c60fe1534de23ac Reviewed-by: Lars Knoll --- src/corelib/codecs/qtextcodec.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 519570c499..9d13e1b892 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -346,13 +346,13 @@ QTextCodec::ConverterState::~ConverterState() The supported encodings are: \list - \li Apple Roman \li \l{Big5 Text Codec}{Big5} \li \l{Big5-HKSCS Text Codec}{Big5-HKSCS} \li CP949 \li \l{EUC-JP Text Codec}{EUC-JP} \li \l{EUC-KR Text Codec}{EUC-KR} - \li \l{GBK Text Codec}{GB18030-0} + \li \l{GBK Text Codec}{GB18030} + \li HP-ROMAN8 \li IBM 850 \li IBM 866 \li IBM 874 @@ -360,10 +360,9 @@ QTextCodec::ConverterState::~ConverterState() \li ISO 8859-1 to 10 \li ISO 8859-13 to 16 \li Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml - \li JIS X 0201 - \li JIS X 0208 \li KOI8-R \li KOI8-U + \li Macintosh \li \l{Shift-JIS Text Codec}{Shift-JIS} \li TIS-620 \li \l{TSCII Text Codec}{TSCII} -- cgit v1.2.3 From 0f3323ce0194b271024d423bec861d51dc55063f Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 24 Oct 2014 13:19:08 +0400 Subject: Doc: Fix CustomStyle snippet Add missing semicolon, include QtWidgets instead of QtGui and use cast for a const pointer because the example with casting relates to the code above where 'widget' is const. Task-number: QTBUG-31736 Change-Id: I5cb6d33ec692deaf41e9a1be9e36e752a8da8739 Reviewed-by: Venugopal Shivashankar --- src/widgets/doc/snippets/customstyle/customstyle.cpp | 2 +- src/widgets/doc/snippets/customstyle/customstyle.h | 2 +- src/widgets/doc/snippets/customstyle/customstyle.pro | 1 + src/widgets/doc/snippets/customstyle/main.cpp | 2 +- src/widgets/doc/snippets/customviewstyle.cpp | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/doc/snippets/customstyle/customstyle.cpp b/src/widgets/doc/snippets/customstyle/customstyle.cpp index b5d44ebecd..16715929a8 100644 --- a/src/widgets/doc/snippets/customstyle/customstyle.cpp +++ b/src/widgets/doc/snippets/customstyle/customstyle.cpp @@ -45,7 +45,7 @@ CustomStyle::CustomStyle() { //! [0] - QSpinBox *spinBox = qobject_cast(widget); + const QSpinBox *spinBox = qobject_cast(widget); if (spinBox) { //! [0] //! [1] } diff --git a/src/widgets/doc/snippets/customstyle/customstyle.h b/src/widgets/doc/snippets/customstyle/customstyle.h index 0f23efc922..0782bdc09c 100644 --- a/src/widgets/doc/snippets/customstyle/customstyle.h +++ b/src/widgets/doc/snippets/customstyle/customstyle.h @@ -49,7 +49,7 @@ class CustomStyle : public QProxyStyle Q_OBJECT public: - CustomStyle() + CustomStyle(); ~CustomStyle() {} void drawPrimitive(PrimitiveElement element, const QStyleOption *option, diff --git a/src/widgets/doc/snippets/customstyle/customstyle.pro b/src/widgets/doc/snippets/customstyle/customstyle.pro index af0ee4e141..02b9b2791d 100644 --- a/src/widgets/doc/snippets/customstyle/customstyle.pro +++ b/src/widgets/doc/snippets/customstyle/customstyle.pro @@ -1,2 +1,3 @@ +QT += widgets HEADERS += customstyle.h SOURCES += customstyle.cpp main.cpp diff --git a/src/widgets/doc/snippets/customstyle/main.cpp b/src/widgets/doc/snippets/customstyle/main.cpp index 19fb6b2be9..8164a1e877 100644 --- a/src/widgets/doc/snippets/customstyle/main.cpp +++ b/src/widgets/doc/snippets/customstyle/main.cpp @@ -39,7 +39,7 @@ ****************************************************************************/ //! [using a custom style] -#include +#include #include "customstyle.h" diff --git a/src/widgets/doc/snippets/customviewstyle.cpp b/src/widgets/doc/snippets/customviewstyle.cpp index cdb4ed1d77..0e641653aa 100644 --- a/src/widgets/doc/snippets/customviewstyle.cpp +++ b/src/widgets/doc/snippets/customviewstyle.cpp @@ -38,7 +38,7 @@ ** ****************************************************************************/ -#include +#include #include "customviewstyle.h" -- cgit v1.2.3 From 0c482869fb342d7a7ed44d8101e84aec9f981549 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Tue, 21 Oct 2014 17:11:58 +0200 Subject: Add support for more font weights internally We should have more font weights in QFont::Weight to allow for finer grained control. For the time being, we can simply use intermediate weights to better support the different font weights falling in between the ones defined in QFont::Weight. Also amend the documentation to clarify the fact that QFont supports and can return weights falling outside the predefined values, which is already the case (e.g. when using fontconfig). Done-with: Gabriel de Dietrich Change-Id: I693cdd48b8b77e7ed550cdf991227bcb819d8e7b Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 12 ++++++------ src/gui/text/qfontdatabase.cpp | 9 +++++++-- src/gui/text/qfontengine_p.h | 4 ++++ .../fontdatabases/basic/qbasicfontdatabase.cpp | 14 +++++++++++++- .../fontdatabases/mac/qcoretextfontdatabase.mm | 6 ++++++ 5 files changed, 36 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 54fcbac308..a0cbd052e4 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1014,8 +1014,8 @@ void QFont::setStyle(Style style) } /*! - Returns the weight of the font which is one of the enumerated - values from \l{QFont::Weight}. + Returns the weight of the font, using the same scale as the + \l{QFont::Weight} enumeration. \sa setWeight(), Weight, QFontInfo */ @@ -1028,8 +1028,8 @@ int QFont::weight() const \enum QFont::Weight Qt uses a weighting scale from 0 to 99 similar to, but not the - same as, the scales used in Windows or CSS. A weight of 0 is - ultralight, whilst 99 will be extremely black. + same as, the scales used in Windows or CSS. A weight of 0 will be + thin, whilst 99 will be extremely black. This enum contains the predefined font weights: @@ -1041,8 +1041,8 @@ int QFont::weight() const */ /*! - Sets the weight the font to \a weight, which should be a value - from the \l QFont::Weight enumeration. + Sets the weight of the font to \a weight, using the scale defined by + \l QFont::Weight enumeration. \sa weight(), QFontInfo */ diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 06d6ec125e..1322a088e0 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -85,10 +85,11 @@ static int getFontWeight(const QString &weightString) QString s = weightString.toLower(); // Test in decreasing order of commonness - if (s == QLatin1String("medium") || - s == QLatin1String("normal") + if (s == QLatin1String("normal") || s.compare(QCoreApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0) return QFont::Normal; + if (s == QLatin1String("medium")) + return qt_mediumFontWeight; if (s == QLatin1String("bold") || s.compare(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0) return QFont::Bold; @@ -100,6 +101,10 @@ static int getFontWeight(const QString &weightString) return QFont::Black; if (s == QLatin1String("light")) return QFont::Light; + if (s == QLatin1String("thin")) + return qt_thinFontWeight; + if (s == QLatin1String("extralight")) + return qt_extralightFontWeight; if (s.contains(QLatin1String("bold")) || s.contains(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) { diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 8c40189ed2..50b1bb9e9d 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -78,6 +78,10 @@ enum HB_Compat_Error { typedef void (*qt_destroy_func_t) (void *user_data); typedef bool (*qt_get_font_table_func_t) (void *user_data, uint tag, uchar *buffer, uint *length); +const QFont::Weight qt_mediumFontWeight = static_cast(57); +const QFont::Weight qt_extralightFontWeight = static_cast(12); +const QFont::Weight qt_thinFontWeight = static_cast(0); + class Q_GUI_EXPORT QFontEngine { public: diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp index fb9ec0f2e4..43903acfe1 100644 --- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp @@ -277,10 +277,16 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt if (os2->usWeightClass == 0) ; + else if (os2->usWeightClass < 150) + weight = qt_thinFontWeight; + else if (os2->usWeightClass < 250) + weight = qt_extralightFontWeight; else if (os2->usWeightClass < 350) weight = QFont::Light; else if (os2->usWeightClass < 450) weight = QFont::Normal; + else if (os2->usWeightClass < 550) + weight = qt_mediumFontWeight; else if (os2->usWeightClass < 650) weight = QFont::DemiBold; else if (os2->usWeightClass < 750) @@ -290,10 +296,16 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt if (os2->panose[2] >= 2) { int w = os2->panose[2]; - if (w <= 3) + if (w <= 1) + weight = qt_thinFontWeight; + else if (w <= 2) + weight = qt_extralightFontWeight; + else if (w <= 3) weight = QFont::Light; else if (w <= 5) weight = QFont::Normal; + else if (w <= 6) + weight = qt_mediumFontWeight; else if (w <= 7) weight = QFont::DemiBold; else if (w <= 8) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index fc289579ea..9f2ff10a21 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -294,10 +294,16 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) fd->weight = QFont::Bold; else if (normalizedWeight >= 0.3) fd->weight = QFont::DemiBold; + else if (normalizedWeight >= 0.2) + fd->weight = qt_mediumFontWeight; else if (normalizedWeight == 0.0) fd->weight = QFont::Normal; else if (normalizedWeight <= -0.4) fd->weight = QFont::Light; + else if (normalizedWeight <= -0.6) + fd->weight = qt_extralightFontWeight; + else if (normalizedWeight <= -0.8) + fd->weight = qt_thinFontWeight; } } if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) { -- cgit v1.2.3 From 27a321e1ed929a3de72ede000a38d95f98f68150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 24 Oct 2014 17:12:35 +0200 Subject: iOS: Make room for zero-terminator when building argv from NSProcessInfo [NSString lengthOfBytesUsingEncoding] only returns the number of bytes required for the actual string, not including the zero terminator, so when we then used cStringUsingEncoding to fill the malloced buffer with data, we overwrote the byte after our buffer with 0, resulting in random and hard to reproduce crashes at application startup, seemingly depending on the application name. Change-Id: I35d261bea5924e917475b0270bfa280bfb0c787a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioseventdispatcher.mm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 821599d113..ce7dfe2606 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -259,10 +259,16 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline() NSArray *arguments = [[NSProcessInfo processInfo] arguments]; int argc = arguments.count; char **argv = new char*[argc]; + for (int i = 0; i < argc; ++i) { NSString *arg = [arguments objectAtIndex:i]; - argv[i] = reinterpret_cast(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]])); - strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); + + NSStringEncoding cStringEncoding = [NSString defaultCStringEncoding]; + unsigned int bufferSize = [arg lengthOfBytesUsingEncoding:cStringEncoding] + 1; + argv[i] = reinterpret_cast(malloc(bufferSize)); + + if (![arg getCString:argv[i] maxLength:bufferSize encoding:cStringEncoding]) + qFatal("Could not convert argv[%d] to C string", i); } int exitCode = qtmn(argc, argv); -- cgit v1.2.3 From 3f9dbc0ec82e1c7c823707668fcd326d8a1dd82b Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Wed, 22 Oct 2014 14:49:33 +0300 Subject: Android: Keyboard doesn't hide from done button QLineEdit commits and hides QInputMethod on enter key press. When Qt::ImhMultiLine input method hint is set, virtual keyboard is not hidden. Task-number: QTBUG-37850 Change-Id: I018351caa18bd2116665771e5f024a57182a01b9 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/widgets/qwidgetlinecontrol.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 90fbfc1639..a82dd99591 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -1607,6 +1607,13 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event) if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { if (hasAcceptableInput() || fixup()) { + + QInputMethod *inputMethod = QApplication::inputMethod(); + inputMethod->commit(); + QWidget *lineEdit = qobject_cast(parent()); + if (!(lineEdit && lineEdit->inputMethodHints() & Qt::ImhMultiLine)) + inputMethod->hide(); + emit accepted(); emit editingFinished(); } -- cgit v1.2.3 From e859de3fb5203579fbb4a6774bcdf59dc00404f9 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Oct 2014 10:53:01 +0200 Subject: Add extra declarations to make rcc output pass -Wmissing-declarations The previously produced code was valid C++. Add the declaration nevertheless to help people who want to use the switch in their own code. Task-number: QTBUG-42119 Change-Id: Ia47cf3930684474ff65e5cf37335d7d7f57a1d31 Reviewed-by: Olivier Goffart --- src/tools/rcc/rcc.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 11a99d136d..9d8a7b7051 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -1057,6 +1057,12 @@ bool RCCResourceLibrary::writeInitializer() QByteArray initResources = "qInitResources"; initResources += initName; + + // Work around -Wmissing-declarations warnings. + writeString("int "); + writeMangleNamespaceFunction(initResources); + writeString("();\n"); + writeString("int "); writeMangleNamespaceFunction(initResources); writeString("()\n{\n"); @@ -1073,6 +1079,12 @@ bool RCCResourceLibrary::writeInitializer() //cleanup QByteArray cleanResources = "qCleanupResources"; cleanResources += initName; + + // Work around -Wmissing-declarations warnings. + writeString("int "); + writeMangleNamespaceFunction(cleanResources); + writeString("();\n"); + writeString("int "); writeMangleNamespaceFunction(cleanResources); writeString("()\n{\n"); -- cgit v1.2.3 From 18a538ed40d5419b7f9edf5e42730113447ed527 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 16 Oct 2014 17:58:54 +0200 Subject: Add searchEdit as accessible state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The search state is used by VoiceOver on iOS to announce a search field. Change-Id: I464125827dbbf275daf38104e26e9591bb23365a Reviewed-by: Jan Arve Sæther --- src/gui/accessible/qaccessible.cpp | 1 + src/gui/accessible/qaccessible.h | 2 ++ src/plugins/platforms/cocoa/qcocoaaccessibility.h | 1 + src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 17 ++++++++++++++--- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 3 +++ src/plugins/platforms/ios/quiaccessibilityelement.mm | 3 +++ 6 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index f85b6d1aad..a7053aa3da 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -166,6 +166,7 @@ QT_BEGIN_NAMESPACE \value playsSound The object produces sound when interacted with. \value pressed The object is pressed. \value readOnly The object can usually be edited, but is explicitly set to read-only. + \value searchEdit The object is a line edit that is the input for search queries. \value selectable The object is selectable. \value selectableText The object has text which can be selected. This is different from selectable which refers to the object's children. \value selected The object is selected, this is independent of text selection. diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 0583a8c691..7b5d7a1bfd 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -185,6 +185,8 @@ public: quint64 selectableText : 1; quint64 supportsAutoCompletion : 1; + quint64 searchEdit : 1; + // quint64 horizontal : 1; // quint64 vertical : 1; // quint64 invalidEntry : 1; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index 96dbd23695..3d1c95a0b4 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -70,6 +70,7 @@ namespace QCocoaAccessible { */ NSString *macRole(QAccessibleInterface *interface); +NSString *macSubrole(QAccessibleInterface *interface); bool shouldBeIgnored(QAccessibleInterface *interface); NSArray *unignoredChildren(QAccessibleInterface *interface); NSString *getTranslatedAction(const QString &qtAction); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 1ade985b79..00baeddb39 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -162,7 +162,7 @@ static void populateRoleMap() } /* - Returns a Mac accessibility role for the given interface, or + Returns a Cocoa accessibility role for the given interface, or NSAccessibilityUnknownRole if no role mapping is found. */ NSString *macRole(QAccessibleInterface *interface) @@ -190,13 +190,24 @@ NSString *macRole(QAccessibleInterface *interface) } /* - Mac accessibility supports ignoring elements, which means that + Returns a Cocoa sub role for the given interface. +*/ +NSString *macSubrole(QAccessibleInterface *interface) +{ + QAccessible::State s = interface->state(); + if (s.searchEdit) + return NSAccessibilitySearchFieldSubrole; + return nil; +} + +/* + Cocoa accessibility supports ignoring elements, which means that the elements are still present in the accessibility tree but is not used by the screen reader. */ bool shouldBeIgnored(QAccessibleInterface *interface) { - // Mac accessibility does not have an attribute that corresponds to the Invisible/Offscreen + // Cocoa accessibility does not have an attribute that corresponds to the Invisible/Offscreen // state. Ignore interfaces with those flags set. const QAccessible::State state = interface->state(); if (state.invisible || diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 9f803e411d..dd76852b62 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -135,6 +135,7 @@ defaultAttributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, + NSAccessibilitySubroleAttribute, NSAccessibilityChildrenAttribute, NSAccessibilityFocusedAttribute, NSAccessibilityParentAttribute, @@ -221,6 +222,8 @@ if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { return role; + } else if ([attribute isEqualToString:NSAccessibilitySubroleAttribute]) { + return QCocoaAccessible::macSubrole(iface); } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { return NSAccessibilityRoleDescription(role, nil); } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index 331c38460c..63b6827ad3 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -152,6 +152,9 @@ if (state.disabled) traits |= UIAccessibilityTraitNotEnabled; + if (state.searchEdit) + traits |= UIAccessibilityTraitSearchField; + if (iface->role() == QAccessible::Button) traits |= UIAccessibilityTraitButton; -- cgit v1.2.3 From 0ca0ecdb32b3d7df76fe9782d04493ebe0da0a9e Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 20 Oct 2014 11:31:00 +1000 Subject: Make networkmanager bearer backend work better This fixes QNetworkConfigurations when user: - configures new AP - deletes connection configuration - switches wifi AP Change-Id: I38c543c6de7b61f49d7ac96fa05f7a6fc4fba70f Reviewed-by: Alex Blasche --- .../networkmanager/qnetworkmanagerengine.cpp | 301 ++++++++++++--------- .../bearer/networkmanager/qnetworkmanagerengine.h | 18 +- .../networkmanager/qnetworkmanagerservice.cpp | 137 ++++++---- .../bearer/networkmanager/qnetworkmanagerservice.h | 43 +-- .../bearer/networkmanager/qnmdbushelper.cpp | 56 ++-- src/plugins/bearer/networkmanager/qnmdbushelper.h | 12 +- 6 files changed, 346 insertions(+), 221 deletions(-) (limited to 'src') diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index ec5666d36c..5f49ea0b6d 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -55,21 +55,21 @@ QT_BEGIN_NAMESPACE QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) : QBearerEngineImpl(parent), - interface(new QNetworkManagerInterface(this)), + managerInterface(new QNetworkManagerInterface(this)), systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)), userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)) { - if (!interface->isValid()) + if (!managerInterface->isValid()) return; - interface->setConnections(); - connect(interface, SIGNAL(deviceAdded(QDBusObjectPath)), + managerInterface->setConnections(); + connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)), this, SLOT(deviceAdded(QDBusObjectPath))); - connect(interface, SIGNAL(deviceRemoved(QDBusObjectPath)), + connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)), this, SLOT(deviceRemoved(QDBusObjectPath))); - connect(interface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), + connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), this, SLOT(activationFinished(QDBusPendingCallWatcher*))); - connect(interface, SIGNAL(propertiesChanged(QString,QMap)), + connect(managerInterface, SIGNAL(propertiesChanged(QString,QMap)), this, SLOT(interfacePropertiesChanged(QString,QMap))); qDBusRegisterMetaType(); @@ -96,9 +96,9 @@ void QNetworkManagerEngine::initialize() QMutexLocker locker(&mutex); // Get current list of access points. - foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { locker.unlock(); - deviceAdded(devicePath); + deviceAdded(devicePath); //add all accesspoints locker.relock(); } @@ -107,7 +107,7 @@ void QNetworkManagerEngine::initialize() foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) { locker.unlock(); if (!hasIdentifier(settingsPath.path())) - newConnection(settingsPath, systemSettings); + newConnection(settingsPath, systemSettings); //add system connection configs locker.relock(); } @@ -119,10 +119,9 @@ void QNetworkManagerEngine::initialize() } // Get active connections. - foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { QNetworkManagerConnectionActive *activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this); - activeConnections.insert(acPath.path(), activeConnection); activeConnection->setConnections(); @@ -136,14 +135,14 @@ bool QNetworkManagerEngine::networkManagerAvailable() const { QMutexLocker locker(&mutex); - return interface->isValid(); + return managerInterface->isValid(); } QString QNetworkManagerEngine::getInterfaceFromId(const QString &id) { QMutexLocker locker(&mutex); - foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); const QString identifier = activeConnection.connection().path(); @@ -182,18 +181,17 @@ void QNetworkManagerEngine::connectToId(const QString &id) const QString connectionType = map.value("connection").value("type").toString(); QString dbusDevicePath; - foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { QNetworkManagerInterfaceDevice device(devicePath.path()); - if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET && + if (device.deviceType() == DEVICE_TYPE_ETHERNET && connectionType == QLatin1String("802-3-ethernet")) { dbusDevicePath = devicePath.path(); break; - } else if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS && + } else if (device.deviceType() == DEVICE_TYPE_WIFI && connectionType == QLatin1String("802-11-wireless")) { dbusDevicePath = devicePath.path(); break; - } - else if (device.deviceType() == DEVICE_TYPE_GSM && + } else if (device.deviceType() == DEVICE_TYPE_MODEM && connectionType == QLatin1String("gsm")) { dbusDevicePath = devicePath.path(); break; @@ -207,7 +205,7 @@ void QNetworkManagerEngine::connectToId(const QString &id) if (specificPath.isEmpty()) specificPath = "/"; - interface->activateConnection(service, QDBusObjectPath(settingsPath), + managerInterface->activateConnection(service, QDBusObjectPath(settingsPath), QDBusObjectPath(dbusDevicePath), QDBusObjectPath(specificPath)); } @@ -223,19 +221,31 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id) return; } - foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); const QString identifier = activeConnection.connection().path(); if (id == identifier && accessPointConfigurations.contains(id)) { - interface->deactivateConnection(acPath); + managerInterface->deactivateConnection(acPath); break; } } } void QNetworkManagerEngine::requestUpdate() +{ + if (managerInterface->wirelessEnabled()) { + QHashIterator i(wirelessDevices); + while (i.hasNext()) { + i.next(); + i.value()->requestScan(); + } + } + QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection); +} + +void QNetworkManagerEngine::scanFinished() { QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection); } @@ -282,7 +292,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { ptr->mutex.lock(); - if (activeConnection->state() == 2 && + if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && ptr->state != QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Active; ptr->mutex.unlock(); @@ -300,13 +310,13 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, delete this->activeConnections.take(priorActiveConnections.takeFirst()); while (!identifiers.isEmpty()) { - // These configurations are not active QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(identifiers.takeFirst()); ptr->mutex.lock(); if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - ptr->state = QNetworkConfiguration::Discovered; + QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; + ptr->state = (flag | QNetworkConfiguration::Discovered); ptr->mutex.unlock(); locker.unlock(); @@ -337,9 +347,9 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { ptr->mutex.lock(); - if (activeConnection->state() == 2 && + if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && ptr->state != QNetworkConfiguration::Active) { - ptr->state = QNetworkConfiguration::Active; + ptr->state |= QNetworkConfiguration::Active; ptr->mutex.unlock(); locker.unlock(); @@ -351,35 +361,63 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat } } -void QNetworkManagerEngine::devicePropertiesChanged(const QString &path, - const QMap &properties) +void QNetworkManagerEngine::devicePropertiesChanged(const QString &/*path*/,quint32 /*state*/) { - Q_UNUSED(path); - Q_UNUSED(properties); +// Q_UNUSED(path); +// Q_UNUSED(state) +} + +void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &activeConnectionsList) +{ + QMutexLocker locker(&mutex); + for (int i = 0; i < connections.count(); ++i) { + if (activeConnectionsList.contains(connections.at(i)->connectionInterface()->path())) + continue; + + const QString settingsPath = connections.at(i)->connectionInterface()->path(); + + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(settingsPath); + ptr->mutex.lock(); + QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; + ptr->state = (flag | QNetworkConfiguration::Discovered); + ptr->mutex.unlock(); + + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + Q_EMIT updateCompleted(); + } } void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) { - QNetworkManagerInterfaceDevice device(path.path()); - if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS) { + QMutexLocker locker(&mutex); + QNetworkManagerInterfaceDevice *iDevice; + iDevice = new QNetworkManagerInterfaceDevice(path.path(),this); + connect(iDevice,SIGNAL(connectionsChanged(QStringList)), + this,SLOT(deviceConnectionsChanged(QStringList))); + + connect(iDevice,SIGNAL(stateChanged(QString,quint32)), + this,SLOT(devicePropertiesChanged(QString,quint32))); + iDevice->setConnections(); + interfaceDevices.insert(path.path(),iDevice); + + if (iDevice->deviceType() == DEVICE_TYPE_WIFI) { QNetworkManagerInterfaceDeviceWireless *wirelessDevice = - new QNetworkManagerInterfaceDeviceWireless(device.connectionInterface()->path(),this); + new QNetworkManagerInterfaceDeviceWireless(iDevice->connectionInterface()->path(),this); wirelessDevice->setConnections(); - connect(wirelessDevice, SIGNAL(accessPointAdded(QString,QDBusObjectPath)), - this, SLOT(newAccessPoint(QString,QDBusObjectPath))); - connect(wirelessDevice, SIGNAL(accessPointRemoved(QString,QDBusObjectPath)), - this, SLOT(removeAccessPoint(QString,QDBusObjectPath))); - connect(wirelessDevice, SIGNAL(propertiesChanged(QString,QMap)), - this, SLOT(devicePropertiesChanged(QString,QMap))); - - foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) { - newAccessPoint(QString(), apPath); - } + connect(wirelessDevice, SIGNAL(accessPointAdded(QString)), + this, SLOT(newAccessPoint(QString))); + connect(wirelessDevice, SIGNAL(accessPointRemoved(QString)), + this, SLOT(removeAccessPoint(QString))); + connect(wirelessDevice,SIGNAL(scanDone()),this,SLOT(scanFinished())); + + foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) + newAccessPoint(apPath.path()); - mutex.lock(); wirelessDevices.insert(path.path(), wirelessDevice); - mutex.unlock(); } } @@ -387,42 +425,69 @@ void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path) { QMutexLocker locker(&mutex); - delete wirelessDevices.take(path.path()); + if (interfaceDevices.contains(path.path())) { + locker.unlock(); + delete interfaceDevices.take(path.path()); + locker.relock(); + } + if (wirelessDevices.contains(path.path())) { + locker.unlock(); + delete wirelessDevices.take(path.path()); + locker.relock(); + } } void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings) { QMutexLocker locker(&mutex); - if (!settings) settings = qobject_cast(sender()); if (!settings) return; + settings->deleteLater(); QNetworkManagerSettingsConnection *connection = new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(), path.path(),this); + QString apPath; + for (int i = 0; i < accessPoints.count(); ++i) { + if (connection->getSsid() == accessPoints.at(i)->ssid()) { + // remove the corresponding accesspoint from configurations + apPath = accessPoints.at(i)->connectionInterface()->path(); + + QNetworkConfigurationPrivatePointer ptr + = accessPointConfigurations.take(apPath); + if (ptr) { + locker.unlock(); + emit configurationRemoved(ptr); + locker.relock(); + } + } + } connections.append(connection); - connect(connection, SIGNAL(removed(QString)), this, SLOT(removeConnection(QString))); - connect(connection, SIGNAL(updated(QNmSettingsMap)), - this, SLOT(updateConnection(QNmSettingsMap))); + connect(connection,SIGNAL(removed(QString)),this,SLOT(removeConnection(QString))); + connect(connection,SIGNAL(updated()),this,SLOT(updateConnection())); + connection->setConnections(); - const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); + if (connection->getType() == DEVICE_TYPE_WIFI + && !configuredAccessPoints.contains(settingsPath)) + configuredAccessPoints.insert(apPath,settingsPath); + QNetworkConfigurationPrivate *cpPriv = - parseConnection(service, settingsPath, connection->getSettings()); + parseConnection(settingsPath, connection->getSettings()); // Check if connection is active. - foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); if (activeConnection.defaultRoute() && activeConnection.connection().path() == settingsPath && - activeConnection.state() == 2) { + activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { cpPriv->state |= QNetworkConfiguration::Active; break; } @@ -438,26 +503,34 @@ void QNetworkManagerEngine::removeConnection(const QString &path) { QMutexLocker locker(&mutex); - Q_UNUSED(path) - QNetworkManagerSettingsConnection *connection = qobject_cast(sender()); if (!connection) return; + connection->deleteLater(); connections.removeAll(connection); - const QString id = connection->connectionInterface()->path(); + const QString id = path; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id); - connection->deleteLater(); - - locker.unlock(); - emit configurationRemoved(ptr); + if (ptr) { + locker.unlock(); + emit configurationRemoved(ptr); + locker.relock(); + } + // add base AP back into configurations + QMapIterator i(configuredAccessPoints); + while (i.hasNext()) { + i.next(); + if (i.value() == path) { + newAccessPoint(i.key()); + } + } } -void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) +void QNetworkManagerEngine::updateConnection() { QMutexLocker locker(&mutex); @@ -466,13 +539,13 @@ void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) if (!connection) return; - const QString service = connection->connectionInterface()->service(); + connection->deleteLater(); const QString settingsPath = connection->connectionInterface()->path(); - QNetworkConfigurationPrivate *cpPriv = parseConnection(service, settingsPath, settings); + QNetworkConfigurationPrivate *cpPriv = parseConnection(settingsPath, connection->getSettings()); // Check if connection is active. - foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { QNetworkManagerConnectionActive activeConnection(acPath.path()); if (activeConnection.connection().path() == settingsPath && @@ -495,6 +568,7 @@ void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) locker.unlock(); emit configurationChanged(ptr); + locker.relock(); delete cpPriv; } @@ -515,9 +589,9 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { ptr->mutex.lock(); - if (activeConnection.state() == 2 && + if (activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && ptr->state != QNetworkConfiguration::Active) { - ptr->state = QNetworkConfiguration::Active; + ptr->state |= QNetworkConfiguration::Active; ptr->mutex.unlock(); locker.unlock(); @@ -530,42 +604,41 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) } } -void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjectPath &objectPath) +void QNetworkManagerEngine::newAccessPoint(const QString &path) { QMutexLocker locker(&mutex); - Q_UNUSED(path) - QNetworkManagerInterfaceAccessPoint *accessPoint = - new QNetworkManagerInterfaceAccessPoint(objectPath.path(),this); - accessPoints.append(accessPoint); - - accessPoint->setConnections(); - connect(accessPoint, SIGNAL(propertiesChanged(QMap)), - this, SLOT(updateAccessPoint(QMap))); + new QNetworkManagerInterfaceAccessPoint(path,this); - // Check if configuration for this SSID already exists. + bool okToAdd = true; for (int i = 0; i < accessPoints.count(); ++i) { - if (accessPoint != accessPoints.at(i) && - accessPoint->ssid() == accessPoints.at(i)->ssid()) { - return; + if (accessPoints.at(i)->connectionInterface()->path() == path) { + okToAdd = false; } } + if (okToAdd) { + accessPoints.append(accessPoint); + accessPoint->setConnections(); + connect(accessPoint, SIGNAL(propertiesChanged(QMap)), + this, SLOT(updateAccessPoint(QMap))); + } // Check if configuration exists for connection. if (!accessPoint->ssid().isEmpty()) { for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); - + const QString settingsPath = connection->connectionInterface()->path(); if (accessPoint->ssid() == connection->getSsid()) { - const QString service = connection->connectionInterface()->service(); - const QString settingsPath = connection->connectionInterface()->path(); - const QString connectionId = settingsPath; + if (!configuredAccessPoints.contains(path)) { + configuredAccessPoints.insert(path,settingsPath); + } QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.value(connectionId); + accessPointConfigurations.value(settingsPath); ptr->mutex.lock(); - ptr->state = QNetworkConfiguration::Discovered; + QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; + ptr->state = (flag | QNetworkConfiguration::Discovered); ptr->mutex.unlock(); locker.unlock(); @@ -580,7 +653,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec ptr->name = accessPoint->ssid(); ptr->isValid = true; - ptr->id = objectPath.path(); + ptr->id = path; ptr->type = QNetworkConfiguration::InternetAccessPoint; if (accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) { ptr->purpose = QNetworkConfiguration::PrivatePurpose; @@ -596,17 +669,13 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec emit configurationAdded(ptr); } -void QNetworkManagerEngine::removeAccessPoint(const QString &path, - const QDBusObjectPath &objectPath) +void QNetworkManagerEngine::removeAccessPoint(const QString &path) { QMutexLocker locker(&mutex); - - Q_UNUSED(path) - for (int i = 0; i < accessPoints.count(); ++i) { QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i); - if (accessPoint->connectionInterface()->path() == objectPath.path()) { + if (accessPoint->connectionInterface()->path() == path) { accessPoints.removeOne(accessPoint); if (configuredAccessPoints.contains(accessPoint->connectionInterface()->path())) { @@ -615,8 +684,7 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); - if (accessPoint->ssid() == connection->getSsid()) { - const QString service = connection->connectionInterface()->service(); + if (accessPoint->ssid() == connection->getSsid()) {//might not have bssid yet const QString settingsPath = connection->connectionInterface()->path(); const QString connectionId = settingsPath; @@ -634,17 +702,17 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, } } else { QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.take(objectPath.path()); + accessPointConfigurations.take(path); if (ptr) { + locker.unlock(); + locker.unlock(); emit configurationRemoved(ptr); locker.relock(); } } - delete accessPoint; - break; } } @@ -660,19 +728,19 @@ void QNetworkManagerEngine::updateAccessPoint(const QMap &map qobject_cast(sender()); if (!accessPoint) return; - + accessPoint->deleteLater(); for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); if (accessPoint->ssid() == connection->getSsid()) { - const QString service = connection->connectionInterface()->service(); const QString settingsPath = connection->connectionInterface()->path(); const QString connectionId = settingsPath; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); ptr->mutex.lock(); - ptr->state = QNetworkConfiguration::Discovered; + QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; + ptr->state = (flag | QNetworkConfiguration::Discovered); ptr->mutex.unlock(); locker.unlock(); @@ -682,11 +750,11 @@ void QNetworkManagerEngine::updateAccessPoint(const QMap &map } } -QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &service, - const QString &settingsPath, +QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &settingsPath, const QNmSettingsMap &map) { - Q_UNUSED(service); + // Q_UNUSED(service); + QMutexLocker locker(&mutex); QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; cpPriv->name = map.value("connection").value("id").toString(); @@ -704,15 +772,14 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri cpPriv->bearerType = QNetworkConfiguration::BearerEthernet; cpPriv->purpose = QNetworkConfiguration::PublicPurpose; - foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { QNetworkManagerInterfaceDevice device(devicePath.path()); - if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET) { + if (device.deviceType() == DEVICE_TYPE_ETHERNET) { QNetworkManagerInterfaceDeviceWired wiredDevice(device.connectionInterface()->path()); if (wiredDevice.carrier()) { cpPriv->state |= QNetworkConfiguration::Discovered; break; } - } } } else if (connectionType == QLatin1String("802-11-wireless")) { @@ -737,9 +804,9 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri accessPointConfigurations.take(accessPointId); if (ptr) { - mutex.unlock(); + locker.unlock(); emit configurationRemoved(ptr); - mutex.lock(); + locker.relock(); } } break; @@ -747,10 +814,10 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri } } else if (connectionType == QLatin1String("gsm")) { - foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { QNetworkManagerInterfaceDevice device(devicePath.path()); - if (device.deviceType() == DEVICE_TYPE_GSM) { + if (device.deviceType() == DEVICE_TYPE_MODEM) { QNetworkManagerInterfaceDeviceModem deviceModem(device.connectionInterface()->path(),this); switch (deviceModem.currentCapabilities()) { case 2: @@ -771,9 +838,6 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; cpPriv->state |= QNetworkConfiguration::Discovered; - } else if (connectionType == QLatin1String("cdma")) { - cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; - cpPriv->bearerType = QNetworkConfiguration::BearerCDMA2000; } return cpPriv; @@ -783,12 +847,7 @@ QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const { for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); - const QString service = connection->connectionInterface()->service(); - const QString settingsPath = connection->connectionInterface()->path(); - - const QString identifier = settingsPath; - - if (id == identifier) + if (id == connection->connectionInterface()->path()) return connection; } diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index c8bdfe3400..ab1cfea71e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -93,35 +93,35 @@ private Q_SLOTS: const QMap &properties); void activeConnectionPropertiesChanged(const QString &path, const QMap &properties); - void devicePropertiesChanged(const QString &path, - const QMap &properties); + void devicePropertiesChanged(const QString &path, quint32); void deviceAdded(const QDBusObjectPath &path); void deviceRemoved(const QDBusObjectPath &path); void newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings = 0); void removeConnection(const QString &path); - void updateConnection(const QNmSettingsMap &settings); + void updateConnection(); void activationFinished(QDBusPendingCallWatcher *watcher); + void deviceConnectionsChanged(const QStringList &activeConnectionsList); - void newAccessPoint(const QString &path, const QDBusObjectPath &objectPath); - void removeAccessPoint(const QString &path, const QDBusObjectPath &objectPath); + void newAccessPoint(const QString &path); + void removeAccessPoint(const QString &path); void updateAccessPoint(const QMap &map); + void scanFinished(); private: - QNetworkConfigurationPrivate *parseConnection(const QString &service, - const QString &settingsPath, + QNetworkConfigurationPrivate *parseConnection(const QString &settingsPath, const QNmSettingsMap &map); QNetworkManagerSettingsConnection *connectionFromId(const QString &id) const; -private: - QNetworkManagerInterface *interface; + QNetworkManagerInterface *managerInterface; QNetworkManagerSettings *systemSettings; QNetworkManagerSettings *userSettings; QHash wirelessDevices; QHash activeConnections; QList connections; QList accessPoints; + QHash interfaceDevices; QMap configuredAccessPoints; //ap, settings path }; diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index d154f1187e..f249ac6100 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -322,18 +322,31 @@ bool QNetworkManagerInterfaceDevice::setConnections() if(!isValid() ) return false; - bool allOk = false; + bool allOk = true; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)), this, SIGNAL(stateChanged(QString,quint32))); + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE), QLatin1String("StateChanged"), nmDBusHelper,SLOT(deviceStateChanged(quint32)))) { - allOk = true; + allOk = false; + } + + connect(nmDBusHelper, SIGNAL(pathForConnectionsChanged(QStringList)), + this,SIGNAL(connectionsChanged(QStringList))); + + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), + QLatin1String("PropertiesChanged"), + nmDBusHelper,SLOT(slotPropertiesChanged(QMap))) ) { + allOk = false; } + return allOk; } @@ -414,18 +427,18 @@ bool QNetworkManagerInterfaceDeviceWired::setConnections() if(!isValid() ) return false; - bool allOk = false; + bool allOk = true; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), QLatin1String("PropertiesChanged"), nmDBusHelper,SLOT(slotPropertiesChanged(QMap))) ) { - allOk = true; + allOk = false; } return allOk; } @@ -491,44 +504,50 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() return false; QDBusConnection dbusConnection = QDBusConnection::systemBus(); - bool allOk = false; + bool allOk = true; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(QString,QDBusObjectPath)), - this,SIGNAL(accessPointAdded(QString,QDBusObjectPath))); + connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(QString)), + this,SIGNAL(accessPointAdded(QString))); - connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(QString,QDBusObjectPath)), - this,SIGNAL(accessPointRemoved(QString,QDBusObjectPath))); + connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(QString)), + this,SIGNAL(accessPointRemoved(QString))); - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointAdded"), nmDBusHelper, SLOT(slotAccessPointAdded(QDBusObjectPath)))) { - allOk = true; + allOk = false; } - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointRemoved"), nmDBusHelper, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) { - allOk = true; + allOk = false; } - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("PropertiesChanged"), nmDBusHelper,SLOT(slotPropertiesChanged(QMap)))) { - allOk = true; + allOk = false; + } + if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), + QLatin1String("ScanDone"), + this, SLOT(scanIsDone()))) { + allOk = false; } - return allOk; } @@ -568,6 +587,17 @@ quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const return d->connectionInterface->property("WirelelessCapabilities").toUInt(); } +void QNetworkManagerInterfaceDeviceWireless::scanIsDone() +{ + Q_EMIT scanDone(); +} + +void QNetworkManagerInterfaceDeviceWireless::requestScan() +{ + d->connectionInterface->asyncCall(QLatin1String("RequestScan")); +} + + class QNetworkManagerInterfaceDeviceModemPrivate { public: @@ -609,18 +639,18 @@ bool QNetworkManagerInterfaceDeviceModem::setConnections() if (!isValid() ) return false; - bool allOk = false; + bool allOk = true; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM), QLatin1String("PropertiesChanged"), nmDBusHelper,SLOT(slotDevicePropertiesChanged(QMap))) ) { - allOk = true; + allOk = false; } return allOk; } @@ -640,9 +670,6 @@ quint32 QNetworkManagerInterfaceDeviceModem::currentCapabilities() const return d->connectionInterface->property("CurrentCapabilities").toUInt(); } - - - class QNetworkManagerSettingsPrivate { public: @@ -680,12 +707,14 @@ bool QNetworkManagerSettings::isValid() bool QNetworkManagerSettings::setConnections() { - bool allOk = false; + bool allOk = true; - if (QDBusConnection::systemBus().connect(d->path, QLatin1String(NM_DBUS_PATH_SETTINGS), - QLatin1String(NM_DBUS_IFACE_SETTINGS), QLatin1String("NewConnection"), - this, SIGNAL(newConnection(QDBusObjectPath)))) { - allOk = true; + if (!QDBusConnection::systemBus().connect(d->path, + QLatin1String(NM_DBUS_PATH_SETTINGS), + QLatin1String(NM_DBUS_IFACE_SETTINGS), + QLatin1String("NewConnection"), + this, SIGNAL(newConnection(QDBusObjectPath)))) { + allOk = false; } return allOk; @@ -697,6 +726,14 @@ QList QNetworkManagerSettings::listConnections() return reply.value(); } +QString QNetworkManagerSettings::getConnectionByUuid(const QString &uuid) +{ + QList argumentList; + argumentList << QVariant::fromValue(uuid); + QDBusReply reply = d->connectionInterface->callWithArgumentList(QDBus::Block,QLatin1String("GetConnectionByUuid"), argumentList); + return reply.value().path(); +} + QDBusInterface *QNetworkManagerSettings::connectionInterface() const { return d->connectionInterface; @@ -750,13 +787,13 @@ bool QNetworkManagerSettingsConnection::setConnections() return false; QDBusConnection dbusConnection = QDBusConnection::systemBus(); - bool allOk = false; - if (dbusConnection.connect(d->service, d->path, - QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Updated"), - this, SIGNAL(updated(QNmSettingsMap)))) { - allOk = true; - } else { - QDBusError error = dbusConnection.lastError(); + bool allOk = true; + if (!dbusConnection.connect(d->service, + d->path, + QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), + QLatin1String("Updated"), + this, SIGNAL(updated()))) { + allOk = false; } delete nmDBusHelper; @@ -764,12 +801,13 @@ bool QNetworkManagerSettingsConnection::setConnections() connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(QString)), this,SIGNAL(removed(QString))); - if (dbusConnection.connect(d->service, d->path, - QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Removed"), - nmDBusHelper, SIGNAL(slotSettingsRemoved()))) { - allOk = true; + if (!dbusConnection.connect(d->service, + d->path, + QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), + QLatin1String("Removed"), + nmDBusHelper, SIGNAL(slotSettingsRemoved()))) { + allOk = false; } - return allOk; } @@ -791,9 +829,9 @@ NMDeviceType QNetworkManagerSettingsConnection::getType() d->settingsMap.value(QLatin1String("connection")).value(QLatin1String("type")).toString(); if (devType == QLatin1String("802-3-ethernet")) - return DEVICE_TYPE_802_3_ETHERNET; + return DEVICE_TYPE_ETHERNET; else if (devType == QLatin1String("802-11-wireless")) - return DEVICE_TYPE_802_11_WIRELESS; + return DEVICE_TYPE_WIFI; else return DEVICE_TYPE_UNKNOWN; } @@ -840,10 +878,10 @@ QString QNetworkManagerSettingsConnection::getMacAddress() { NMDeviceType type = getType(); - if (type == DEVICE_TYPE_802_3_ETHERNET) { + if (type == DEVICE_TYPE_ETHERNET) { return d->settingsMap.value(QLatin1String("802-3-ethernet")) .value(QLatin1String("mac-address")).toString(); - } else if (type == DEVICE_TYPE_802_11_WIRELESS) { + } else if (type == DEVICE_TYPE_WIFI) { return d->settingsMap.value(QLatin1String("802-11-wireless")) .value(QLatin1String("mac-address")).toString(); } else { @@ -853,7 +891,7 @@ QString QNetworkManagerSettingsConnection::getMacAddress() QStringList QNetworkManagerSettingsConnection::getSeenBssids() { - if (getType() == DEVICE_TYPE_802_11_WIRELESS) { + if (getType() == DEVICE_TYPE_WIFI) { return d->settingsMap.value(QLatin1String("802-11-wireless")) .value(QLatin1String("seen-bssids")).toStringList(); } else { @@ -901,17 +939,18 @@ bool QNetworkManagerConnectionActive::setConnections() if(!isValid() ) return false; - bool allOk = false; + bool allOk = true; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + + if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap))) ) { - allOk = true; + nmDBusHelper,SLOT(activeConnectionPropertiesChanged(QMap))) ) { + allOk = false; } return allOk; diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 8cda02482b..11ddaf7088 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -64,31 +64,32 @@ typedef enum NMDeviceType { DEVICE_TYPE_UNKNOWN = 0, - DEVICE_TYPE_802_3_ETHERNET, - DEVICE_TYPE_802_11_WIRELESS, - DEVICE_TYPE_GSM, - DEVICE_TYPE_CDMA + DEVICE_TYPE_ETHERNET, + DEVICE_TYPE_WIFI, + DEVICE_TYPE_MODEM = 8 } NMDeviceType; typedef enum { NM_DEVICE_STATE_UNKNOWN = 0, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_PREPARE, - NM_DEVICE_STATE_CONFIG, - NM_DEVICE_STATE_NEED_AUTH, - NM_DEVICE_STATE_IP_CONFIG, - NM_DEVICE_STATE_ACTIVATED, - NM_DEVICE_STATE_FAILED + NM_DEVICE_STATE_UNMANAGED = 10, + NM_DEVICE_STATE_UNAVAILABLE = 20, + NM_DEVICE_STATE_DISCONNECTED = 30, + NM_DEVICE_STATE_PREPARE = 40, + NM_DEVICE_STATE_CONFIG = 50, + NM_DEVICE_STATE_NEED_AUTH = 60, + NM_DEVICE_STATE_IP_CONFIG = 70, + NM_DEVICE_STATE_ACTIVATED = 100, + NM_DEVICE_STATE_DEACTIVATING = 110, + NM_DEVICE_STATE_FAILED = 120 } NMDeviceState; typedef enum { NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, NM_ACTIVE_CONNECTION_STATE_ACTIVATING, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED } NMActiveConnectionState; #define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" @@ -257,7 +258,8 @@ public: Q_SIGNALS: void stateChanged(const QString &, quint32); - + void propertiesChanged(const QString &, QMap); + void connectionsChanged(QStringList); private: QNetworkManagerInterfaceDevicePrivate *d; QNmDBusHelper *nmDBusHelper; @@ -321,10 +323,14 @@ public: bool setConnections(); bool isValid(); + void requestScan(); Q_SIGNALS: void propertiesChanged( const QString &, QMap); - void accessPointAdded(const QString &,QDBusObjectPath); - void accessPointRemoved(const QString &,QDBusObjectPath); + void accessPointAdded(const QString &); + void accessPointRemoved(const QString &); + void scanDone(); +private Q_SLOTS: + void scanIsDone(); private: QNetworkManagerInterfaceDeviceWirelessPrivate *d; QNmDBusHelper *nmDBusHelper; @@ -378,6 +384,7 @@ public: QDBusInterface *connectionInterface() const; QList listConnections(); + QString getConnectionByUuid(const QString &uuid); bool setConnections(); bool isValid(); @@ -412,7 +419,7 @@ public: Q_SIGNALS: - void updated(const QNmSettingsMap &settings); + void updated(); void removed(const QString &path); private: diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp index a2e055d784..0decfd78b9 100644 --- a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp +++ b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp @@ -60,7 +60,7 @@ QNmDBusHelper::~QNmDBusHelper() void QNmDBusHelper::deviceStateChanged(quint32 state) { QDBusMessage msg = this->message(); - if(state == NM_DEVICE_STATE_ACTIVATED + if (state == NM_DEVICE_STATE_ACTIVATED || state == NM_DEVICE_STATE_DISCONNECTED || state == NM_DEVICE_STATE_UNAVAILABLE || state == NM_DEVICE_STATE_FAILED) { @@ -70,18 +70,14 @@ void QNmDBusHelper::deviceStateChanged(quint32 state) void QNmDBusHelper::slotAccessPointAdded(QDBusObjectPath path) { - if(path.path().length() > 2) { - QDBusMessage msg = this->message(); - emit pathForAccessPointAdded(msg.path(), path); - } + if (path.path().length() > 2) + emit pathForAccessPointAdded(path.path()); } void QNmDBusHelper::slotAccessPointRemoved(QDBusObjectPath path) { - if(path.path().length() > 2) { - QDBusMessage msg = this->message(); - emit pathForAccessPointRemoved(msg.path(), path); - } + if (path.path().length() > 2) + emit pathForAccessPointRemoved(path.path()); } void QNmDBusHelper::slotPropertiesChanged(QMap map) @@ -90,23 +86,29 @@ void QNmDBusHelper::slotPropertiesChanged(QMap map) QMapIterator i(map); while (i.hasNext()) { i.next(); - if( i.key() == "State") { //state only applies to device interfaces + if (i.key() == QStringLiteral("State")) { quint32 state = i.value().toUInt(); - if( state == NM_DEVICE_STATE_ACTIVATED + if (state == NM_DEVICE_STATE_ACTIVATED || state == NM_DEVICE_STATE_DISCONNECTED || state == NM_DEVICE_STATE_UNAVAILABLE || state == NM_DEVICE_STATE_FAILED) { - emit pathForPropertiesChanged( msg.path(), map); + emit pathForPropertiesChanged(msg.path(), map); } - } else if( i.key() == "ActiveAccessPoint") { + } else if (i.key() == QStringLiteral("ActiveAccessPoint")) { emit pathForPropertiesChanged(msg.path(), map); - // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value().value().path(); - // } else if( i.key() == "Strength") - // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value().toUInt(); - // else - // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value(); - } else if (i.key() == "ActiveConnections") { + } else if (i.key() == QStringLiteral("ActiveConnections")) { emit pathForPropertiesChanged(msg.path(), map); + } else if (i.key() == QStringLiteral("AvailableConnections")) { + const QDBusArgument &dbusArgs = i.value().value(); + QDBusObjectPath path; + QStringList paths; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + paths << path.path(); + } + dbusArgs.endArray(); + emit pathForConnectionsChanged(paths); } } } @@ -117,6 +119,22 @@ void QNmDBusHelper::slotSettingsRemoved() emit pathForSettingsRemoved(msg.path()); } +void QNmDBusHelper::activeConnectionPropertiesChanged(QMap map) +{ + QDBusMessage msg = this->message(); + QMapIterator i(map); + while (i.hasNext()) { + i.next(); + if (i.key() == QStringLiteral("State")) { + quint32 state = i.value().toUInt(); + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED + || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { + emit pathForPropertiesChanged(msg.path(), map); + } + } + } +} + QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.h b/src/plugins/bearer/networkmanager/qnmdbushelper.h index cd5e8a3494..e224af87f1 100644 --- a/src/plugins/bearer/networkmanager/qnmdbushelper.h +++ b/src/plugins/bearer/networkmanager/qnmdbushelper.h @@ -51,17 +51,19 @@ class QNmDBusHelper: public QObject, protected QDBusContext public slots: void deviceStateChanged(quint32); - void slotAccessPointAdded( QDBusObjectPath ); - void slotAccessPointRemoved( QDBusObjectPath ); - void slotPropertiesChanged( QMap); + void slotAccessPointAdded(QDBusObjectPath); + void slotAccessPointRemoved(QDBusObjectPath); + void slotPropertiesChanged(QMap); void slotSettingsRemoved(); + void activeConnectionPropertiesChanged(QMap); Q_SIGNALS: void pathForStateChanged(const QString &, quint32); - void pathForAccessPointAdded(const QString &, QDBusObjectPath ); - void pathForAccessPointRemoved(const QString &, QDBusObjectPath ); + void pathForAccessPointAdded(const QString &); + void pathForAccessPointRemoved(const QString &); void pathForPropertiesChanged(const QString &, QMap); void pathForSettingsRemoved(const QString &); + void pathForConnectionsChanged(const QStringList &pathsList); }; QT_END_NAMESPACE -- cgit v1.2.3 From 81998b4e8e440076bd22a9164f0a93481c0e597a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 10 Oct 2014 14:23:00 +0200 Subject: Android: Fix android bearer implementation. 1. If the interface used by a configuration changes, remove the whole configuration and replace it with a new one (instead of updating it). While this isn't intuitive, this is the exact behavior we used to have on android when using the generic plugin... 2. Setting the session state to roaming is not correct in this context as it's a transitional state where we should end up in connected state (forced roaming). Before this patch we would get stuck in the roaming state for mobile networks. 4. Use QNetworkInterface::name() instead of QNetworkInterface::humanReadableName(), as this is the expected value when querying the interface used. 3. Don't re-iterate through the interface list for each configuration. Task-number: QTBUG-41832 Change-Id: I315f725434bc6a1a8dca13dffd41f606c87bd06d Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../bearer/android/src/qandroidbearerengine.cpp | 41 ++++++++-------------- 1 file changed, 14 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/plugins/bearer/android/src/qandroidbearerengine.cpp b/src/plugins/bearer/android/src/qandroidbearerengine.cpp index 2d047ba612..64c1a20ecc 100644 --- a/src/plugins/bearer/android/src/qandroidbearerengine.cpp +++ b/src/plugins/bearer/android/src/qandroidbearerengine.cpp @@ -166,10 +166,7 @@ QNetworkSession::State QAndroidBearerEngine::sessionStateForId(const QString &id const QMutexLocker configLocker(&ptr->mutex); // Don't re-order... if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - return (m_connectivityManager->isActiveNetworkMetered() - || m_connectivityManager->getActiveNetworkInfo().isRoaming()) - ? QNetworkSession::Roaming - : QNetworkSession::Connected; + return QNetworkSession::Connected; } else if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { return QNetworkSession::Disconnected; } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) { @@ -267,6 +264,10 @@ void QAndroidBearerEngine::updateConfigurations() QMutexLocker locker(&mutex); QStringList oldKeys = accessPointConfigurations.keys(); + QList interfaces = QNetworkInterface::allInterfaces(); + if (interfaces.isEmpty()) + interfaces = QNetworkInterface::allInterfaces(); + // Create a configuration for each of the main types (WiFi, Mobile, Bluetooth, WiMax, Ethernet) foreach (const AndroidNetworkInfo &netInfo, m_connectivityManager->getAllNetworkInfo()) { @@ -279,14 +280,13 @@ void QAndroidBearerEngine::updateConfigurations() QNetworkConfiguration::BearerType bearerType = getBearerType(netInfo); - QNetworkConfiguration::StateFlag state; QString interfaceName; + QNetworkConfiguration::StateFlag state = QNetworkConfiguration::Defined; if (netInfo.isAvailable()) { if (netInfo.isConnected()) { - state = QNetworkConfiguration::Active; // Attempt to map an interface to this configuration - const QList &interfaces = QNetworkInterface::allInterfaces(); - foreach (const QNetworkInterface &interface, interfaces) { + while (!interfaces.isEmpty()) { + QNetworkInterface interface = interfaces.takeFirst(); // ignore loopback interface if (!interface.isValid()) continue; @@ -297,22 +297,17 @@ void QAndroidBearerEngine::updateConfigurations() // look for an active interface... if (interface.flags() & QNetworkInterface::IsRunning && !interface.addressEntries().isEmpty()) { - interfaceName = interface.humanReadableName(); - if (interfaceName.isEmpty()) - interfaceName = interface.name(); + state = QNetworkConfiguration::Active; + interfaceName = interface.name(); + break; } } - } else if (netInfo.isConnectedOrConnecting()) { - state = QNetworkConfiguration::Undefined; - } else { - state = QNetworkConfiguration::Discovered; } - } else { - state = QNetworkConfiguration::Defined; } - const uint identifier = qHash(QLatin1String("android:") + name); - const QString id = QString::number(identifier); + const QString key = QString(QLatin1String("android:%1:%2")).arg(name).arg(interfaceName); + const QString id = QString::number(qHash(key)); + m_configurationInterface[id] = interfaceName; oldKeys.removeAll(id); if (accessPointConfigurations.contains(id)) { @@ -347,12 +342,6 @@ void QAndroidBearerEngine::updateConfigurations() ptr->state = state; changed = true; } - - QString &oldIfName = m_configurationInterface[id]; - if (oldIfName != interfaceName) { - oldIfName = interfaceName; - changed = true; - } } // Unlock configuration if (changed) { @@ -369,8 +358,6 @@ void QAndroidBearerEngine::updateConfigurations() ptr->type = QNetworkConfiguration::InternetAccessPoint; ptr->bearerType = bearerType; accessPointConfigurations.insert(id, ptr); - m_configurationInterface.insert(id, interfaceName); - locker.unlock(); Q_EMIT configurationAdded(ptr); locker.relock(); -- cgit v1.2.3